from typing import Dict, List, Optional
from rest_framework import serializers
from django.utils.timezone import localtime

from apps.archive.models import CreatorDescription, CreatorModel


class CreatorListSerializer(serializers.ModelSerializer):
    source_site = serializers.SerializerMethodField()
    date = serializers.SerializerMethodField()
    description = serializers.SerializerMethodField()
    avatar_url = serializers.SerializerMethodField()
    banner_url = serializers.SerializerMethodField()

    class Meta:
        model = CreatorModel
        fields = [
            "creator_id",
            "source_site",
            "slug",
            "name",
            "mature",
            "date",
            "description",
            "avatar_url",
            "banner_url",
        ]

    def get_source_site(self, obj) -> str:
        return obj.source_site.slug

    def get_date(self, obj) -> Dict[str, str]:
        return {
            "created": localtime(obj.date_created).isoformat(),
            "imported": localtime(obj.date_imported).isoformat(),
            "last_import": localtime(obj.date_last_import).isoformat(),
        }

    def get_description(self, obj) -> Optional[str]:
        # Get the most recent CreatorDescription entry
        creator_desc = (
            CreatorDescription.objects.filter(creator=obj)
            .order_by("-date_imported")
            .first()
        )

        if creator_desc:
            return creator_desc.description.content

        return None  # Return None if no descriptions exist

    def get_avatar_url(self, obj) -> Optional[str]:
        if obj.avatar:
            return obj.avatar.file.url
        else:
            return None

    def get_banner_url(self, obj) -> Optional[str]:
        if obj.banner:
            return obj.banner.file.url
        else:
            return None


class CreatorDetailsSerializer(serializers.ModelSerializer):
    description = serializers.SerializerMethodField()
    date = serializers.SerializerMethodField()
    avatar_url = serializers.SerializerMethodField()
    banner_url = serializers.SerializerMethodField()
    categories = serializers.SerializerMethodField()

    class Meta:
        model = CreatorModel
        fields = [
            "creator_id",
            "slug",
            "name",
            "mature",
            "avatar_url",
            "banner_url",
            "description",
            "date",
            "categories",
        ]

    def get_description(self, obj) -> List[Dict[str, str]]:
        data = []

        # Fetch descriptions ordered by date_imported from the through model
        creator_descriptions = CreatorDescription.objects.filter(creator=obj).order_by(
            "-date_imported"
        )

        for creator_desc in creator_descriptions:
            data.append(
                {
                    "id": creator_desc.description.id,
                    "content": creator_desc.description.content,
                    "date_imported": creator_desc.date_imported,
                }
            )

        return data

    def get_avatar_url(self, obj) -> Optional[str]:
        if obj.avatar:
            return obj.avatar.file.url
        else:
            return None

    def get_banner_url(self, obj) -> Optional[str]:
        if obj.banner:
            return obj.banner.file.url
        else:
            return None

    def get_date(self, obj) -> Dict[str, str]:
        return {
            "created": localtime(obj.date_created).isoformat(),
            "imported": localtime(obj.date_imported).isoformat(),
            "last_import": localtime(obj.date_last_import).isoformat(),
        }

    def get_categories(self, obj) -> List[Dict[str, str]]:
        data = []
        for cat in obj.categories.all():
            data.append({"name": cat.name, "slug": cat.slug})
        return data