import importlib
import uuid

import factory
from django.apps import apps
from django.conf import settings
from faker import Faker

from blog.factories.comment import BlogCommentFactory
from blog.factories.tag import BlogTagFactory
from blog.models.post import BlogPost
from core.factories import CustomDjangoModelFactory


fake = Faker()

available_languages = [
    lang["code"] for lang in settings.PARLER_LANGUAGES[settings.SITE_ID]
]


def generate_unique_blog_filename():
    return f"blog_post_{uuid.uuid4().hex[:8]}.jpg"


def get_or_create_category():
    if apps.get_model("blog", "BlogCategory").objects.exists():
        return (
            apps.get_model("blog", "BlogCategory").objects.order_by("?").first()
        )
    else:
        category_factory_module = importlib.import_module(
            "blog.factories.category"
        )
        category_factory_class = category_factory_module.BlogCategoryFactory
        return category_factory_class.create()


def get_or_create_author():
    if apps.get_model("blog", "BlogAuthor").objects.exists():
        return (
            apps.get_model("blog", "BlogAuthor").objects.order_by("?").first()
        )
    else:
        author_factory_module = importlib.import_module("blog.factories.author")
        author_factory_class = author_factory_module.BlogAuthorFactory
        return author_factory_class.create()


class BlogPostTranslationFactory(factory.django.DjangoModelFactory):
    language_code = factory.Iterator(available_languages)
    title = factory.Faker("sentence", nb_words=6)
    subtitle = factory.Faker("sentence", nb_words=12)
    body = factory.Faker("paragraph", nb_sentences=5)
    master = factory.SubFactory("blog.factories.post.BlogPostFactory")

    class Meta:
        model = apps.get_model("blog", "BlogPostTranslation")
        django_get_or_create = ("language_code", "master")


class BlogPostFactory(CustomDjangoModelFactory):
    auto_translations = False

    unique_model_fields = [
        ("slug", lambda: fake.slug()),
    ]

    image = factory.django.ImageField(
        filename=factory.LazyFunction(generate_unique_blog_filename),
        width=1200,
        height=630,
        color="purple",
    )
    category = factory.LazyFunction(get_or_create_category)
    author = factory.LazyFunction(get_or_create_author)
    is_published = factory.Faker("boolean")
    featured = factory.Faker("boolean")
    view_count = factory.Faker("random_int", min=0, max=1000)

    class Meta:
        model = BlogPost
        django_get_or_create = ("slug",)
        skip_postgeneration_save = True

    @factory.post_generation
    def num_tags(self, create, extracted, **kwargs):
        if not create:
            return

        if extracted:
            tags = BlogTagFactory.create_batch(extracted)
            self.tags.add(*tags)

    @factory.post_generation
    def num_comments(self, create, extracted, **kwargs):
        if not create:
            return

        if extracted:
            BlogCommentFactory.create_batch(extracted, post=self)

    @factory.post_generation
    def translations(self, create, extracted, **kwargs):
        if not create:
            return

        translations = extracted or [
            BlogPostTranslationFactory(language_code=lang, master=self)
            for lang in available_languages
        ]

        for translation in translations:
            translation.master = self
            translation.save()
