"""Factories for the ``ashley`` application."""
import json
import uuid

import factory
from django.contrib.auth import get_user_model
from django.utils.text import slugify
from factory.django import DjangoModelFactory
from faker import Faker
from lti_toolbox.factories import LTIConsumerFactory
from machina.core.db.models import get_model

faker = Faker()

Forum = get_model("forum", "Forum")  # pylint: disable=C0103
LTIContext = get_model("ashley", "LTIContext")  # pylint: disable=C0103
Post = get_model("forum_conversation", "Post")  # pylint: disable=C0103
Topic = get_model("forum_conversation", "Topic")  # pylint: disable=C0103
User = get_user_model()
UploadImage = get_model("ashley", "UploadImage")  # pylint: disable=C0103


class UserFactory(DjangoModelFactory):
    """Factory to create a User."""

    class Meta:
        model = User

    email = factory.LazyAttribute(lambda u: f"{u.public_username}@example.com")
    lti_consumer = factory.SubFactory(LTIConsumerFactory)
    lti_remote_user_id = factory.SelfAttribute("public_username")
    public_username = factory.Sequence(lambda n: f"user{n}")
    username = factory.LazyAttribute(
        lambda u: f"{u.public_username}@{u.lti_consumer.slug}"
    )


class LTIContextFactory(DjangoModelFactory):
    """Factory to create a LTIContext."""

    class Meta:
        model = LTIContext

    lti_consumer = factory.SubFactory(LTIConsumerFactory)
    lti_id = factory.Sequence(lambda n: f"context{n}")


class ForumFactory(DjangoModelFactory):
    """Factory to create a Forum"""

    class Meta:
        model = Forum

    name = factory.Sequence(lambda n: f"forum{n}")
    type = Forum.FORUM_POST


class TopicFactory(DjangoModelFactory):
    """Factory to create a Topic"""

    class Meta:
        model = Topic

    forum = factory.SubFactory(ForumFactory)
    poster = factory.SubFactory(UserFactory)
    slug = factory.LazyAttribute(lambda t: slugify(t.subject))
    status = Topic.TOPIC_UNLOCKED
    # Watchout: Django Machina is overriding the topic subject when saving the first post!
    # https://github.com/ellmetha/django-machina/blob/master/machina/apps/forum_conversation/abstract_models.py#L314
    subject = factory.Faker("text", max_nb_chars=100)
    type = Topic.TOPIC_POST


class PostFactory(DjangoModelFactory):
    """Factory to create a Post"""

    class Meta:
        model = Post
        exclude = ("text",)

    poster = factory.SubFactory(UserFactory)
    subject = factory.Faker("text", max_nb_chars=100)
    text = factory.Faker("paragraph", nb_sentences=5)
    topic = factory.SubFactory(TopicFactory)

    @factory.lazy_attribute
    def content(self):
        """Building a fake content around the text as would be generated by draftjs."""
        data = {
            "blocks": [
                {
                    "key": faker.uuid4(),
                    "text": self.text,
                    "type": "unstyled",
                    "depth": 0,
                    "inlineStyleRanges": [],
                    "entityRanges": [],
                    "data": {},
                }
            ],
            "entityMap": {},
        }
        return json.dumps(data)


class UploadImageFactory(DjangoModelFactory):
    """Factory to create an UploadImage"""

    class Meta:
        model = UploadImage

    forum = factory.SubFactory(ForumFactory)
    poster = factory.SubFactory(UserFactory)
    file = f"{uuid.uuid4()}.png"
