"""
Document Control Service — API Serializers.
"""
from rest_framework import serializers

from .models import (
    Document,
    DocumentAccess,
    DocumentApproval,
    DocumentAuditLog,
    DocumentCategory,
    DocumentVersion,
    AccessLevel,
    ApprovalStatus,
    DocumentAccessType,
    DocumentStatus,
)


# ============================================================================
# Category Serializers
# ============================================================================

class DocumentCategoryListSerializer(serializers.ModelSerializer):
    """List serializer for document categories."""
    children_count = serializers.SerializerMethodField()

    class Meta:
        model = DocumentCategory
        fields = [
            'id', 'name', 'code', 'parent', 'description',
            'sort_order', 'is_active', 'children_count',
            'created_at', 'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']

    def get_children_count(self, obj):
        return obj.children.filter(is_active=True).count()


class DocumentCategoryDetailSerializer(serializers.ModelSerializer):
    """Detail serializer with nested children."""
    children = serializers.SerializerMethodField()

    class Meta:
        model = DocumentCategory
        fields = [
            'id', 'name', 'code', 'parent', 'description',
            'sort_order', 'is_active', 'children',
            'created_at', 'updated_at',
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']

    def get_children(self, obj):
        children = obj.children.filter(is_active=True).order_by('sort_order', 'name')
        return DocumentCategoryListSerializer(children, many=True).data


class DocumentCategoryCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating/updating categories."""

    class Meta:
        model = DocumentCategory
        fields = ['name', 'code', 'parent', 'description', 'sort_order', 'is_active']


# ============================================================================
# Document Serializers
# ============================================================================

class DocumentListSerializer(serializers.ModelSerializer):
    """List serializer for documents."""
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    category_name = serializers.CharField(source='category.name', read_only=True, default=None)
    owner_name = serializers.SerializerMethodField()

    class Meta:
        model = Document
        fields = [
            'id', 'title', 'code', 'category', 'category_name',
            'status', 'status_display', 'current_version',
            'owner', 'owner_name', 'is_checked_out',
            'created_at', 'updated_at',
        ]
        read_only_fields = ['id', 'current_version', 'created_at', 'updated_at']

    def get_owner_name(self, obj):
        if obj.owner:
            return obj.owner.get_full_name() or obj.owner.username
        return None


class DocumentDetailSerializer(serializers.ModelSerializer):
    """Detail serializer for documents — includes versions count & access info."""
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    access_level_display = serializers.CharField(source='get_access_level_display', read_only=True)
    category_name = serializers.CharField(source='category.name', read_only=True, default=None)
    owner_name = serializers.SerializerMethodField()
    checked_out_by_name = serializers.SerializerMethodField()
    versions_count = serializers.SerializerMethodField()

    class Meta:
        model = Document
        fields = [
            'id', 'title', 'code', 'category', 'category_name',
            'description', 'owner', 'owner_name',
            'status', 'status_display',
            'current_version', 'versions_count',
            'metadata', 'access_level', 'access_level_display',
            'is_checked_out', 'checked_out_by', 'checked_out_by_name', 'checked_out_at',
            'created_at', 'updated_at',
        ]
        read_only_fields = [
            'id', 'current_version', 'is_checked_out',
            'checked_out_by', 'checked_out_at',
            'created_at', 'updated_at',
        ]

    def get_owner_name(self, obj):
        if obj.owner:
            return obj.owner.get_full_name() or obj.owner.username
        return None

    def get_checked_out_by_name(self, obj):
        if obj.checked_out_by:
            return obj.checked_out_by.get_full_name() or obj.checked_out_by.username
        return None

    def get_versions_count(self, obj):
        return obj.versions.count()


class DocumentCreateSerializer(serializers.ModelSerializer):
    """Serializer for creating documents."""

    class Meta:
        model = Document
        fields = [
            'title', 'code', 'category', 'description',
            'metadata', 'access_level',
        ]


class DocumentUpdateSerializer(serializers.ModelSerializer):
    """Serializer for updating documents."""

    class Meta:
        model = Document
        fields = [
            'title', 'category', 'description',
            'metadata', 'access_level',
        ]


# ============================================================================
# Version Serializers
# ============================================================================

class DocumentVersionListSerializer(serializers.ModelSerializer):
    """List serializer for document versions."""
    created_by_name = serializers.SerializerMethodField()

    class Meta:
        model = DocumentVersion
        fields = [
            'id', 'document', 'version_number',
            'file_url', 'file_name', 'file_size', 'mime_type',
            'change_description', 'is_current',
            'created_by', 'created_by_name', 'created_at',
        ]
        read_only_fields = ['id', 'version_number', 'is_current', 'created_at']

    def get_created_by_name(self, obj):
        if obj.created_by:
            return obj.created_by.get_full_name() or obj.created_by.username
        return None


class DocumentVersionCreateSerializer(serializers.Serializer):
    """Serializer for creating a new version."""
    file_url = serializers.CharField(max_length=1000)
    file_name = serializers.CharField(max_length=500)
    file_size = serializers.IntegerField(default=0, min_value=0)
    mime_type = serializers.CharField(max_length=100, required=False, default='')
    change_description = serializers.CharField(required=False, default='')


class VersionRevertSerializer(serializers.Serializer):
    """Serializer for reverting to a previous version."""
    target_version_number = serializers.IntegerField(min_value=1)


class VersionCompareSerializer(serializers.Serializer):
    """Serializer for comparing two versions."""
    version_a = serializers.IntegerField(min_value=1)
    version_b = serializers.IntegerField(min_value=1)


# ============================================================================
# Approval Serializers
# ============================================================================

class DocumentApprovalListSerializer(serializers.ModelSerializer):
    """List serializer for approvals."""
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    document_title = serializers.CharField(source='document.title', read_only=True)
    document_code = serializers.CharField(source='document.code', read_only=True)
    approver_name = serializers.SerializerMethodField()

    class Meta:
        model = DocumentApproval
        fields = [
            'id', 'document', 'document_title', 'document_code',
            'version', 'approver', 'approver_name',
            'status', 'status_display', 'comments',
            'approved_at', 'created_at', 'updated_at',
        ]
        read_only_fields = ['id', 'approved_at', 'created_at', 'updated_at']

    def get_approver_name(self, obj):
        if obj.approver:
            return obj.approver.get_full_name() or obj.approver.username
        return None


class SubmitForApprovalSerializer(serializers.Serializer):
    """Serializer for submitting a document for approval."""
    document_id = serializers.UUIDField()
    approver_id = serializers.UUIDField()
    version_id = serializers.UUIDField(required=False, default=None)


class ApprovalActionSerializer(serializers.Serializer):
    """Serializer for approve/reject actions."""
    comments = serializers.CharField(required=False, default='')


# ============================================================================
# Access Serializers
# ============================================================================

class DocumentAccessListSerializer(serializers.ModelSerializer):
    """List serializer for document access rules."""
    access_type_display = serializers.CharField(source='get_access_type_display', read_only=True)
    permission_level_display = serializers.CharField(source='get_permission_level_display', read_only=True)
    user_name = serializers.SerializerMethodField()
    granted_by_name = serializers.SerializerMethodField()

    class Meta:
        model = DocumentAccess
        fields = [
            'id', 'document', 'access_type', 'access_type_display',
            'user', 'user_name', 'role_id',
            'permission_level', 'permission_level_display',
            'granted_by', 'granted_by_name', 'created_at',
        ]
        read_only_fields = ['id', 'created_at']

    def get_user_name(self, obj):
        if obj.user:
            return obj.user.get_full_name() or obj.user.username
        return None

    def get_granted_by_name(self, obj):
        if obj.granted_by:
            return obj.granted_by.get_full_name() or obj.granted_by.username
        return None


class GrantAccessSerializer(serializers.Serializer):
    """Serializer for granting document access."""
    document_id = serializers.UUIDField()
    user_id = serializers.UUIDField(required=False, default=None)
    role_id = serializers.UUIDField(required=False, default=None)
    permission_level = serializers.ChoiceField(
        choices=AccessLevel.choices,
        default=AccessLevel.VIEW,
    )

    def validate(self, attrs):
        if not attrs.get('user_id') and not attrs.get('role_id'):
            raise serializers.ValidationError('باید حداقل یک کاربر یا نقش مشخص شود.')
        return attrs


# ============================================================================
# Audit Log Serializer
# ============================================================================

class DocumentAuditLogSerializer(serializers.ModelSerializer):
    """Read-only serializer for audit logs."""
    action_display = serializers.CharField(source='get_action_display', read_only=True)
    document_title = serializers.CharField(source='document.title', read_only=True)
    document_code = serializers.CharField(source='document.code', read_only=True)
    user_name = serializers.SerializerMethodField()

    class Meta:
        model = DocumentAuditLog
        fields = [
            'id', 'document', 'document_title', 'document_code',
            'action', 'action_display',
            'user', 'user_name', 'details',
            'ip_address', 'user_agent', 'created_at',
        ]
        read_only_fields = fields

    def get_user_name(self, obj):
        if obj.user:
            return obj.user.get_full_name() or obj.user.username
        return None
