"""DMS permissions — REST serializers."""

from __future__ import annotations

from rest_framework import serializers

from simorgh.apps.dms.permissions.models import (
    ACLAction,
    ACLEffect,
    ACLPolicy,
    ACLPrincipalType,
    ACLRule,
    ACLSubjectType,
    DocumentPermission,
    ShareLink,
)


# ---------------------------------------------------------------------------
# ACLPolicy
# ---------------------------------------------------------------------------

class ACLPolicySerializer(serializers.ModelSerializer):
    """Full read serializer for ACLPolicy."""

    public_id = serializers.UUIDField(read_only=True)

    class Meta:
        model = ACLPolicy
        fields = [
            "public_id",
            "name",
            "description",
            "subject_type",
            "subject_id",
            "inheritable",
            "is_active",
            "created_at",
            "updated_at",
        ]
        read_only_fields = fields


class ACLPolicyCreateInputSerializer(serializers.Serializer):
    subject_type = serializers.ChoiceField(choices=ACLSubjectType.choices)
    subject_id = serializers.CharField(max_length=40)
    name = serializers.CharField(max_length=200)
    description = serializers.CharField(required=False, default="", allow_blank=True)
    inheritable = serializers.BooleanField(required=False, default=True)


class ACLPolicyUpdateInputSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=200, required=False)
    description = serializers.CharField(required=False, allow_blank=True)
    inheritable = serializers.BooleanField(required=False)
    is_active = serializers.BooleanField(required=False)


# ---------------------------------------------------------------------------
# ACLRule
# ---------------------------------------------------------------------------

class ACLRuleSerializer(serializers.ModelSerializer):
    """Full read serializer for ACLRule."""

    public_id = serializers.UUIDField(read_only=True)

    class Meta:
        model = ACLRule
        fields = [
            "public_id",
            "principal_type",
            "principal_id",
            "action",
            "effect",
            "priority",
            "created_at",
        ]
        read_only_fields = fields


class ACLRuleCreateInputSerializer(serializers.Serializer):
    principal_type = serializers.ChoiceField(choices=ACLPrincipalType.choices)
    principal_id = serializers.CharField(
        max_length=40, required=False, default="", allow_blank=True
    )
    action = serializers.ChoiceField(choices=ACLAction.choices)
    effect = serializers.ChoiceField(
        choices=ACLEffect.choices, required=False, default=ACLEffect.ALLOW
    )
    priority = serializers.IntegerField(required=False, default=0, min_value=0)


# ---------------------------------------------------------------------------
# DocumentPermission
# ---------------------------------------------------------------------------

class DocumentPermissionSerializer(serializers.ModelSerializer):
    """Full read serializer for DocumentPermission."""

    public_id = serializers.UUIDField(read_only=True)

    class Meta:
        model = DocumentPermission
        fields = [
            "public_id",
            "principal_type",
            "principal_id",
            "action",
            "effect",
            "expires_at",
            "inheritable",
            "notes",
            "created_at",
        ]
        read_only_fields = fields


class DocumentPermissionGrantInputSerializer(serializers.Serializer):
    principal_type = serializers.ChoiceField(choices=ACLPrincipalType.choices)
    principal_id = serializers.CharField(
        max_length=40, required=False, default="", allow_blank=True
    )
    action = serializers.ChoiceField(choices=ACLAction.choices)
    effect = serializers.ChoiceField(
        choices=ACLEffect.choices, required=False, default=ACLEffect.ALLOW
    )
    expires_at = serializers.DateTimeField(required=False, allow_null=True, default=None)
    inheritable = serializers.BooleanField(required=False, default=False)
    notes = serializers.CharField(required=False, default="", allow_blank=True)


# ---------------------------------------------------------------------------
# ShareLink
# ---------------------------------------------------------------------------

class ShareLinkSerializer(serializers.ModelSerializer):
    """Public read serializer for ShareLink (token included for owner)."""

    public_id = serializers.UUIDField(read_only=True)
    is_expired = serializers.BooleanField(read_only=True)
    is_exhausted = serializers.BooleanField(read_only=True)

    class Meta:
        model = ShareLink
        fields = [
            "public_id",
            "token",
            "label",
            "expires_at",
            "max_uses",
            "use_count",
            "allow_download",
            "allow_preview",
            "is_active",
            "is_expired",
            "is_exhausted",
            "notes",
            "created_at",
        ]
        read_only_fields = fields


class ShareLinkCreateInputSerializer(serializers.Serializer):
    label = serializers.CharField(max_length=200, required=False, default="", allow_blank=True)
    expires_at = serializers.DateTimeField(required=False, allow_null=True, default=None)
    max_uses = serializers.IntegerField(
        required=False, allow_null=True, default=None, min_value=1
    )
    allow_download = serializers.BooleanField(required=False, default=True)
    allow_preview = serializers.BooleanField(required=False, default=True)
    notes = serializers.CharField(required=False, default="", allow_blank=True)
    password = serializers.CharField(
        required=False, default=None, allow_null=True, allow_blank=True,
        write_only=True,
        help_text="Optional password to protect this share link.",
    )


class ShareLinkUseInputSerializer(serializers.Serializer):
    """Input for the public token-use endpoint."""

    password = serializers.CharField(
        required=False, default=None, allow_null=True, allow_blank=True,
        write_only=True,
    )


class ResolvePermissionsInputSerializer(serializers.Serializer):
    """Optional overrides for resolve endpoint — used in tests / admin calls."""

    role_slugs = serializers.ListField(
        child=serializers.CharField(), required=False, default=list
    )
    org_node_ids = serializers.ListField(
        child=serializers.CharField(), required=False, default=list
    )
