"""
HRM API Serializers - v1.

سریالایزرهای REST API ماژول مدیریت منابع انسانی.
"""
from rest_framework import serializers

from ...infrastructure.persistence.models import (
    LegalEntityModel,
    LocationModel,
    EmployeeModel,
    EmploymentRecordModel,
    EmployeeDocumentModel,
    JobFamilyModel,
    JobTitleModel,
    PositionModel,
    ReportingLineModel,
)
from ...infrastructure.persistence.models_extended import (
    WorkScheduleModel,
    ShiftPatternModel,
    TimesheetModel,
    AttendanceRecordModel,
    LeavePolicyModel,
    LeaveBalanceModel,
    LeaveRequestModel,
    PayGradeModel,
    CompensationRecordModel,
    BankAccountModel,
    CostAllocationModel,
)


# ═══════════════════════════════════════════════════
# 1. Organization Structure
# ═══════════════════════════════════════════════════

class LegalEntitySerializer(serializers.ModelSerializer):
    """سریالایزر شخصیت حقوقی."""

    class Meta:
        model = LegalEntityModel
        fields = [
            "id", "name", "name_en", "registration_number",
            "national_id", "economic_code", "entity_type",
            "parent_entity", "address", "phone", "email",
            "website", "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class LegalEntityListSerializer(serializers.ModelSerializer):
    """سریالایزر لیست شخصیت حقوقی."""

    class Meta:
        model = LegalEntityModel
        fields = [
            "id", "name", "name_en", "entity_type",
            "national_id", "is_active",
        ]


class LocationSerializer(serializers.ModelSerializer):
    """سریالایزر مکان."""

    class Meta:
        model = LocationModel
        fields = [
            "id", "name", "code", "location_type",
            "legal_entity", "address", "city", "province",
            "postal_code", "latitude", "longitude", "capacity",
            "timezone", "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class LocationListSerializer(serializers.ModelSerializer):
    """سریالایزر لیست مکان."""

    class Meta:
        model = LocationModel
        fields = [
            "id", "name", "code", "location_type",
            "city", "province", "is_active",
        ]


# ═══════════════════════════════════════════════════
# 2. Employee Master Data
# ═══════════════════════════════════════════════════

class EmployeeSerializer(serializers.ModelSerializer):
    """سریالایزر کارمند - جزئیات کامل."""

    full_name = serializers.SerializerMethodField()
    full_name_en = serializers.SerializerMethodField()

    class Meta:
        model = EmployeeModel
        fields = [
            "id", "employee_code", "first_name", "last_name",
            "first_name_en", "last_name_en", "full_name", "full_name_en",
            "national_code", "birth_certificate_number", "date_of_birth",
            "gender", "marital_status", "military_status", "nationality",
            "phone", "mobile", "email", "address", "postal_code",
            "city", "province",
            "emergency_contact_name", "emergency_contact_phone",
            "emergency_contact_relation",
            "user_id", "hire_date", "termination_date",
            "employment_status", "employment_type", "probation_end_date",
            "legal_entity_id", "org_unit_id", "location_id",
            "primary_position_id", "manager_id",
            "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_full_name(self, obj):
        return f"{obj.first_name} {obj.last_name}".strip()

    def get_full_name_en(self, obj):
        return f"{obj.first_name_en or ''} {obj.last_name_en or ''}".strip()


class EmployeeListSerializer(serializers.ModelSerializer):
    """سریالایزر لیست کارمندان."""

    full_name = serializers.SerializerMethodField()

    class Meta:
        model = EmployeeModel
        fields = [
            "id", "employee_code", "full_name",
            "national_code", "employment_status",
            "employment_type", "org_unit_id", "is_active",
            "user",
        ]

    def get_full_name(self, obj):
        return f"{obj.first_name} {obj.last_name}".strip()


class EmployeeCreateSerializer(serializers.ModelSerializer):
    """سریالایزر ایجاد کارمند."""

    # فیلدهایی که فرانت‌اند ممکن است رشته خالی ارسال کند — تبدیل به None
    NULLABLE_FIELDS = {
        "date_of_birth", "hire_date", "probation_end_date",
        "legal_entity_id", "org_unit_id", "location_id",
        "primary_position_id", "manager_id",
    }

    class Meta:
        model = EmployeeModel
        fields = [
            "employee_code", "first_name", "last_name",
            "first_name_en", "last_name_en",
            "national_code", "birth_certificate_number", "date_of_birth",
            "gender", "marital_status", "military_status", "nationality",
            "phone", "mobile", "email", "address", "postal_code",
            "city", "province",
            "emergency_contact_name", "emergency_contact_phone",
            "emergency_contact_relation",
            "hire_date", "employment_type", "probation_end_date",
            "legal_entity_id", "org_unit_id", "location_id",
            "primary_position_id", "manager_id",
            "metadata",
        ]

    def to_internal_value(self, data):
        """تبدیل رشته خالی به None برای فیلدهای nullable."""
        data = data.copy() if hasattr(data, "copy") else dict(data)
        for field_name in self.NULLABLE_FIELDS:
            if field_name in data and data[field_name] == "":
                data[field_name] = None
        return super().to_internal_value(data)

    def validate_national_code(self, value):
        if len(value) != 10 or not value.isdigit():
            raise serializers.ValidationError("کد ملی باید ۱۰ رقم باشد.")
        return value


class EmployeeTerminateSerializer(serializers.Serializer):
    """سریالایزر خاتمه همکاری."""

    termination_date = serializers.DateField()
    reason = serializers.CharField(required=False, allow_blank=True)


class EmployeeTransferSerializer(serializers.Serializer):
    """سریالایزر انتقال کارمند."""

    new_org_unit_id = serializers.UUIDField()
    new_position_id = serializers.UUIDField(required=False)
    new_location_id = serializers.UUIDField(required=False)
    effective_date = serializers.DateField()
    reason = serializers.CharField(required=False, allow_blank=True)


class EmploymentRecordSerializer(serializers.ModelSerializer):
    """سریالایزر سابقه استخدامی."""

    class Meta:
        model = EmploymentRecordModel
        fields = [
            "id", "employee", "contract_type", "contract_number",
            "start_date", "end_date", "position_id", "org_unit_id",
            "notes", "is_current", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class EmployeeDocumentSerializer(serializers.ModelSerializer):
    """سریالایزر مدارک کارمند."""

    class Meta:
        model = EmployeeDocumentModel
        fields = [
            "id", "employee", "document_type", "title",
            "file_path", "issue_date", "expiry_date",
            "notes", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


# ═══════════════════════════════════════════════════
# 3. Position & Job
# ═══════════════════════════════════════════════════

class JobFamilySerializer(serializers.ModelSerializer):
    """سریالایزر خانواده شغلی."""

    class Meta:
        model = JobFamilyModel
        fields = [
            "id", "name", "code",
            "description", "is_active",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class JobTitleSerializer(serializers.ModelSerializer):
    """سریالایزر عنوان شغلی."""

    class Meta:
        model = JobTitleModel
        fields = [
            "id", "title", "title_en", "code",
            "job_family", "level", "grade", "description",
            "responsibilities", "qualifications",
            "min_experience_years", "is_active",
            "metadata", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class PositionSerializer(serializers.ModelSerializer):
    """سریالایزر پست سازمانی."""

    is_vacant = serializers.ReadOnlyField()

    class Meta:
        model = PositionModel
        fields = [
            "id", "code", "title",
            "job_title", "org_unit_id", "location",
            "legal_entity",
            "reports_to", "incumbent", "status",
            "is_key_position", "is_budgeted",
            "budget_amount", "headcount", "fte",
            "effective_date", "end_date",
            "is_vacant", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "is_vacant", "created_at", "updated_at"]


class PositionListSerializer(serializers.ModelSerializer):
    """سریالایزر لیست پست‌ها."""

    is_vacant = serializers.ReadOnlyField()

    class Meta:
        model = PositionModel
        fields = [
            "id", "code", "title", "status",
            "org_unit_id", "is_key_position", "is_vacant",
        ]


class ReportingLineSerializer(serializers.ModelSerializer):
    """سریالایزر خط گزارش‌دهی."""

    class Meta:
        model = ReportingLineModel
        fields = [
            "id", "employee", "manager", "reporting_type",
            "is_primary", "effective_date", "end_date",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


# ═══════════════════════════════════════════════════
# 4. Time & Attendance
# ═══════════════════════════════════════════════════

class WorkScheduleSerializer(serializers.ModelSerializer):
    """سریالایزر برنامه کاری."""

    class Meta:
        model = WorkScheduleModel
        fields = [
            "id", "name", "code", "schedule_type",
            "start_time", "end_time", "break_duration_minutes",
            "working_days", "daily_hours", "weekly_hours",
            "is_night_shift",
            "overtime_threshold_daily", "overtime_threshold_weekly",
            "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class ShiftPatternSerializer(serializers.ModelSerializer):
    """سریالایزر الگوی شیفت."""

    class Meta:
        model = ShiftPatternModel
        fields = [
            "id", "name", "code", "cycle_days",
            "shifts", "is_active",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class TimesheetSerializer(serializers.ModelSerializer):
    """سریالایزر تایم‌شیت."""

    class Meta:
        model = TimesheetModel
        fields = [
            "id", "employee", "period_start", "period_end",
            "status", "total_regular_hours", "total_overtime_hours",
            "total_working_days", "submitted_at", "approved_at",
            "approved_by", "rejection_reason", "notes",
            "metadata", "created_at", "updated_at",
        ]
        read_only_fields = [
            "id", "submitted_at", "approved_at",
            "approved_by", "created_at", "updated_at",
        ]


class TimesheetSubmitSerializer(serializers.Serializer):
    """سریالایزر ارسال تایم‌شیت."""

    notes = serializers.CharField(required=False, allow_blank=True)


class TimesheetApproveSerializer(serializers.Serializer):
    """سریالایزر تأیید/رد تایم‌شیت."""

    action = serializers.ChoiceField(choices=["approve", "reject"])
    reason = serializers.CharField(required=False, allow_blank=True)


class AttendanceRecordSerializer(serializers.ModelSerializer):
    """سریالایزر حضور و غیاب."""

    class Meta:
        model = AttendanceRecordModel
        fields = [
            "id", "employee", "attendance_date",
            "check_in", "check_out", "status",
            "scheduled_start", "scheduled_end",
            "late_minutes", "early_departure_minutes",
            "overtime_minutes", "break_minutes",
            "effective_hours", "source", "location",
            "notes", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class AttendanceCheckInSerializer(serializers.Serializer):
    """سریالایزر ثبت ورود."""

    employee_id = serializers.UUIDField()
    check_in = serializers.DateTimeField()
    source = serializers.ChoiceField(
        choices=["MANUAL", "BIOMETRIC", "GPS", "MOBILE"],
        default="MANUAL",
    )
    location_id = serializers.UUIDField(required=False)
    notes = serializers.CharField(required=False, allow_blank=True)


class AttendanceCheckOutSerializer(serializers.Serializer):
    """سریالایزر ثبت خروج."""

    check_out = serializers.DateTimeField()
    notes = serializers.CharField(required=False, allow_blank=True)


# ═══════════════════════════════════════════════════
# 5. Leave Management
# ═══════════════════════════════════════════════════

class LeavePolicySerializer(serializers.ModelSerializer):
    """سریالایزر سیاست مرخصی."""

    class Meta:
        model = LeavePolicyModel
        fields = [
            "id", "name", "code", "leave_type",
            "annual_entitlement_days", "max_carryover_days",
            "max_accumulation_days", "min_service_days_required",
            "accrual_method", "requires_approval",
            "max_consecutive_days", "min_notice_days",
            "allow_half_day", "allow_hourly", "is_paid",
            "applicable_genders", "applicable_employment_types",
            "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class LeaveBalanceSerializer(serializers.ModelSerializer):
    """سریالایزر مانده مرخصی."""

    available_days = serializers.ReadOnlyField()

    class Meta:
        model = LeaveBalanceModel
        fields = [
            "id", "employee", "leave_policy", "leave_type",
            "year", "entitled_days", "carried_over_days",
            "used_days", "pending_days", "adjustment_days",
            "available_days", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "available_days", "created_at", "updated_at"]


class LeaveRequestSerializer(serializers.ModelSerializer):
    """سریالایزر درخواست مرخصی."""

    class Meta:
        model = LeaveRequestModel
        fields = [
            "id", "employee", "leave_type", "leave_policy",
            "start_date", "end_date", "days_count",
            "is_half_day", "half_day_period",
            "status", "reason", "substitute",
            "approved_by", "approved_at", "rejection_reason",
            "attachment", "notes", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = [
            "id", "status", "approved_by", "approved_at",
            "rejection_reason", "created_at", "updated_at",
        ]


class LeaveRequestCreateSerializer(serializers.Serializer):
    """سریالایزر ایجاد درخواست مرخصی."""

    employee_id = serializers.UUIDField()
    leave_type = serializers.CharField()
    start_date = serializers.DateField()
    end_date = serializers.DateField()
    is_half_day = serializers.BooleanField(default=False)
    half_day_period = serializers.CharField(required=False, allow_blank=True)
    reason = serializers.CharField(required=False, allow_blank=True)
    substitute_id = serializers.UUIDField(required=False)

    def validate(self, data):
        if data["start_date"] > data["end_date"]:
            raise serializers.ValidationError(
                "تاریخ شروع نمی‌تواند بعد از تاریخ پایان باشد."
            )
        return data


class LeaveActionSerializer(serializers.Serializer):
    """سریالایزر عملیات تأیید/رد مرخصی."""

    action = serializers.ChoiceField(choices=["approve", "reject", "cancel"])
    reason = serializers.CharField(required=False, allow_blank=True)


# ═══════════════════════════════════════════════════
# 6. Payroll Foundation
# ═══════════════════════════════════════════════════

class PayGradeSerializer(serializers.ModelSerializer):
    """سریالایزر رتبه حقوقی."""

    class Meta:
        model = PayGradeModel
        fields = [
            "id", "name", "code", "grade_type",
            "min_amount", "mid_amount", "max_amount",
            "currency", "step_count", "step_increment",
            "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class CompensationRecordSerializer(serializers.ModelSerializer):
    """سریالایزر سابقه حقوقی."""

    total_monthly = serializers.ReadOnlyField()

    class Meta:
        model = CompensationRecordModel
        fields = [
            "id", "employee", "pay_grade",
            "base_salary", "housing_allowance",
            "transportation_allowance", "food_allowance",
            "family_allowance",
            "overtime_rate", "holiday_rate", "night_shift_rate",
            "currency", "pay_grade_step",
            "effective_date", "end_date", "is_current",
            "change_reason", "total_monthly",
            "metadata", "created_at", "updated_at",
        ]
        read_only_fields = [
            "id", "total_monthly", "created_at", "updated_at",
        ]


class SetSalarySerializer(serializers.Serializer):
    """سریالایزر تنظیم حقوق."""

    employee_id = serializers.UUIDField()
    base_salary = serializers.DecimalField(max_digits=18, decimal_places=0)
    housing_allowance = serializers.DecimalField(
        max_digits=18, decimal_places=0, default=0
    )
    transportation_allowance = serializers.DecimalField(
        max_digits=18, decimal_places=0, default=0
    )
    food_allowance = serializers.DecimalField(
        max_digits=18, decimal_places=0, default=0
    )
    family_allowance = serializers.DecimalField(
        max_digits=18, decimal_places=0, default=0
    )
    pay_grade_id = serializers.UUIDField(required=False)
    effective_date = serializers.DateField()
    change_reason = serializers.CharField(required=False, allow_blank=True)


class BankAccountSerializer(serializers.ModelSerializer):
    """سریالایزر حساب بانکی."""

    class Meta:
        model = BankAccountModel
        fields = [
            "id", "employee", "bank_name", "branch_name",
            "branch_code", "account_number", "sheba_number",
            "card_number", "account_holder_name",
            "is_primary", "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def validate_sheba_number(self, value):
        if value and (len(value) != 26 or not value.startswith("IR")):
            raise serializers.ValidationError(
                "شماره شبا باید ۲۶ کاراکتر و با IR شروع شود."
            )
        return value


class CostAllocationSerializer(serializers.ModelSerializer):
    """سریالایزر تخصیص هزینه."""

    class Meta:
        model = CostAllocationModel
        fields = [
            "id", "employee", "allocation_type",
            "target_id", "target_code", "percentage",
            "gl_account_code", "effective_date", "end_date",
            "is_active", "metadata",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]
