"""Correspondence DRF serializers."""

from __future__ import annotations

from rest_framework import serializers

from simorgh.apps.correspondence.models import (
    Category,
    Letter,
    LetterAttachment,
    LetterheadTemplate,
    LetterRecipient,
    LetterTemplate,
    NumberingTemplate,
)

# ═══════════════════════════════════════════════════════════════════════════
# Category
# ═══════════════════════════════════════════════════════════════════════════


class CategoryListSerializer(serializers.ModelSerializer):
    children_count = serializers.SerializerMethodField()

    class Meta:
        model = Category
        fields = [
            "id", "public_id", "name", "category_type", "parent_id",
            "description", "is_active", "sort_order", "children_count",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "public_id", "created_at", "updated_at"]

    def get_children_count(self, obj: Category) -> int:
        return obj.children.count()


class CategoryCreateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=255)
    category_type = serializers.ChoiceField(choices=["subject", "unit"], default="subject")
    parent_id = serializers.IntegerField(required=False, allow_null=True)
    description = serializers.CharField(required=False, allow_blank=True, default="")
    sort_order = serializers.IntegerField(required=False, default=0)


class CategoryUpdateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=255, required=False)
    category_type = serializers.ChoiceField(choices=["subject", "unit"], required=False)
    parent_id = serializers.IntegerField(required=False, allow_null=True)
    description = serializers.CharField(required=False, allow_blank=True)
    is_active = serializers.BooleanField(required=False)
    sort_order = serializers.IntegerField(required=False)


# ═══════════════════════════════════════════════════════════════════════════
# NumberingTemplate
# ═══════════════════════════════════════════════════════════════════════════


class NumberingTemplateSerializer(serializers.ModelSerializer):
    class Meta:
        model = NumberingTemplate
        fields = [
            "id", "public_id", "name", "pattern", "prefix", "counter",
            "letter_type", "is_default", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "public_id", "counter", "created_at", "updated_at"]


class NumberingTemplateCreateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=255)
    pattern = serializers.CharField(max_length=255, required=False, default="{year}/{counter:04d}")
    prefix = serializers.CharField(max_length=50, required=False, allow_blank=True, default="")
    letter_type = serializers.ChoiceField(
        choices=["incoming", "outgoing", "internal_memo", "announcement", "notice"],
        default="outgoing",
    )
    is_default = serializers.BooleanField(required=False, default=False)


# ═══════════════════════════════════════════════════════════════════════════
# LetterheadTemplate
# ═══════════════════════════════════════════════════════════════════════════


class LetterheadTemplateSerializer(serializers.ModelSerializer):
    class Meta:
        model = LetterheadTemplate
        fields = [
            "id", "public_id", "name", "header_html", "footer_html",
            "css_styles", "is_default", "is_active", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "public_id", "created_at", "updated_at"]


class LetterheadTemplateCreateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=255)
    header_html = serializers.CharField(required=False, allow_blank=True, default="")
    footer_html = serializers.CharField(required=False, allow_blank=True, default="")
    css_styles = serializers.CharField(required=False, allow_blank=True, default="")
    is_default = serializers.BooleanField(required=False, default=False)


# ═══════════════════════════════════════════════════════════════════════════
# LetterTemplate
# ═══════════════════════════════════════════════════════════════════════════


class LetterTemplateSerializer(serializers.ModelSerializer):
    letterhead = LetterheadTemplateSerializer(read_only=True)
    numbering_template = NumberingTemplateSerializer(read_only=True)

    class Meta:
        model = LetterTemplate
        fields = [
            "id", "public_id", "name", "letter_type", "subject_template",
            "body_template", "letterhead", "numbering_template",
            "is_default", "is_active", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "public_id", "created_at", "updated_at"]


class LetterTemplateCreateSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=255)
    letter_type = serializers.ChoiceField(
        choices=["incoming", "outgoing", "internal_memo", "announcement", "notice"],
        default="outgoing",
    )
    subject_template = serializers.CharField(required=False, allow_blank=True, default="")
    body_template = serializers.CharField(required=False, allow_blank=True, default="")
    letterhead_id = serializers.IntegerField(required=False, allow_null=True)
    numbering_template_id = serializers.IntegerField(required=False, allow_null=True)
    is_default = serializers.BooleanField(required=False, default=False)


# ═══════════════════════════════════════════════════════════════════════════
# Letter
# ═══════════════════════════════════════════════════════════════════════════


class LetterRecipientSerializer(serializers.ModelSerializer):
    class Meta:
        model = LetterRecipient
        fields = [
            "id", "public_id", "recipient_id", "recipient_name",
            "recipient_organization", "recipient_type", "status",
            "sent_at", "delivered_at", "read_at",
        ]
        read_only_fields = ["id", "public_id", "sent_at", "delivered_at", "read_at"]


class LetterAttachmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = LetterAttachment
        fields = [
            "id", "public_id", "file_id", "attachment_type",
            "description", "sort_order", "created_at",
        ]
        read_only_fields = ["id", "public_id", "created_at"]


class LetterListSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField(source="category.name")
    sender_name = serializers.SerializerMethodField()

    class Meta:
        model = Letter
        fields = [
            "id", "public_id", "letter_type", "status", "priority",
            "security", "registration_number", "registration_date",
            "subject", "sender_name", "sender_external",
            "category_id", "category_name",
            "letter_date", "due_date", "external_reference",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "public_id", "created_at", "updated_at"]

    def get_sender_name(self, obj: Letter) -> str:
        if obj.sender:
            return obj.sender.get_full_name() or obj.sender.email
        return obj.sender_external


class LetterDetailSerializer(LetterListSerializer):
    recipients = LetterRecipientSerializer(many=True, read_only=True)
    attachments = LetterAttachmentSerializer(many=True, read_only=True)
    parent_id = serializers.ReadOnlyField()
    replies_count = serializers.SerializerMethodField()

    class Meta(LetterListSerializer.Meta):
        fields = [*LetterListSerializer.Meta.fields, "body", "summary", "sender_organization", "template_id", "numbering_template_id", "letterhead_id", "parent_id", "received_date", "sent_date", "recipients", "attachments", "replies_count", "metadata"]

    def get_replies_count(self, obj: Letter) -> int:
        return obj.replies.count()


# ── Write serializers ──────────────────────────────────────────────────


class LetterRecipientInputSerializer(serializers.Serializer):
    recipient_id = serializers.IntegerField(required=False, allow_null=True)
    recipient_name = serializers.CharField(max_length=500, required=False, allow_blank=True, default="")
    recipient_organization = serializers.CharField(max_length=500, required=False, allow_blank=True, default="")
    recipient_type = serializers.ChoiceField(choices=["to", "cc", "bcc"], default="to")


class LetterCreateSerializer(serializers.Serializer):
    letter_type = serializers.ChoiceField(
        choices=["incoming", "outgoing", "internal_memo", "announcement", "notice"],
    )
    subject = serializers.CharField(max_length=500)
    body = serializers.CharField(required=False, allow_blank=True, default="")
    priority = serializers.ChoiceField(
        choices=["low", "normal", "high", "urgent"], required=False, default="normal"
    )
    security = serializers.ChoiceField(
        choices=["normal", "confidential", "secret", "top_secret"],
        required=False, default="normal",
    )
    sender_id = serializers.IntegerField(required=False, allow_null=True)
    sender_external = serializers.CharField(max_length=500, required=False, allow_blank=True, default="")
    sender_organization = serializers.CharField(max_length=500, required=False, allow_blank=True, default="")
    category_id = serializers.IntegerField(required=False, allow_null=True)
    template_id = serializers.IntegerField(required=False, allow_null=True)
    numbering_template_id = serializers.IntegerField(required=False, allow_null=True)
    letterhead_id = serializers.IntegerField(required=False, allow_null=True)
    registration_date = serializers.DateField(required=False)
    letter_date = serializers.DateField(required=False)
    received_date = serializers.DateField(required=False)
    due_date = serializers.DateField(required=False)
    external_reference = serializers.CharField(max_length=255, required=False, allow_blank=True, default="")
    summary = serializers.CharField(required=False, allow_blank=True, default="")
    parent_id = serializers.IntegerField(required=False, allow_null=True)
    auto_number = serializers.BooleanField(required=False, default=True)
    tag_ids = serializers.ListField(child=serializers.IntegerField(), required=False)
    recipients = LetterRecipientInputSerializer(many=True, required=False)
    metadata = serializers.JSONField(required=False, default=dict)


class LetterUpdateSerializer(serializers.Serializer):
    subject = serializers.CharField(max_length=500, required=False)
    body = serializers.CharField(required=False, allow_blank=True)
    priority = serializers.ChoiceField(
        choices=["low", "normal", "high", "urgent"], required=False
    )
    security = serializers.ChoiceField(
        choices=["normal", "confidential", "secret", "top_secret"], required=False
    )
    sender_external = serializers.CharField(max_length=500, required=False, allow_blank=True)
    sender_organization = serializers.CharField(max_length=500, required=False, allow_blank=True)
    category_id = serializers.IntegerField(required=False, allow_null=True)
    template_id = serializers.IntegerField(required=False, allow_null=True)
    letterhead_id = serializers.IntegerField(required=False, allow_null=True)
    registration_date = serializers.DateField(required=False)
    letter_date = serializers.DateField(required=False)
    received_date = serializers.DateField(required=False)
    due_date = serializers.DateField(required=False)
    external_reference = serializers.CharField(max_length=255, required=False, allow_blank=True)
    summary = serializers.CharField(required=False, allow_blank=True)
    metadata = serializers.JSONField(required=False)


class LetterStatusChangeSerializer(serializers.Serializer):
    status = serializers.ChoiceField(
        choices=["draft", "sent", "received", "in_progress", "completed", "archived", "cancelled"],
    )


class LetterCancelSerializer(serializers.Serializer):
    reason = serializers.CharField(required=False, allow_blank=True, default="")


class ReplyCreateSerializer(serializers.Serializer):
    body = serializers.CharField(required=False, allow_blank=True, default="")
    subject = serializers.CharField(max_length=500, required=False)
    letter_type = serializers.ChoiceField(
        choices=["incoming", "outgoing", "internal_memo", "announcement", "notice"],
        required=False, default="outgoing",
    )
    priority = serializers.ChoiceField(
        choices=["low", "normal", "high", "urgent"], required=False, default="normal"
    )


class AttachmentAddSerializer(serializers.Serializer):
    file_id = serializers.IntegerField()
    attachment_type = serializers.ChoiceField(choices=["scan", "attachment"], default="attachment")
    description = serializers.CharField(required=False, allow_blank=True, default="")
    sort_order = serializers.IntegerField(required=False, default=0)
