from __future__ import annotations

from rest_framework import serializers


class LeaveTypeSerializer(serializers.ModelSerializer):
    class Meta:
        from simorgh.apps.hr_core.models import LeaveType
        model = LeaveType
        fields = (
            "id", "name", "code", "color", "is_paid", "requires_approval",
            "max_days_per_year", "carry_forward_days", "accrual_method",
        )
        read_only_fields = ("id",)


class LeaveRequestSerializer(serializers.ModelSerializer):
    public_id = serializers.UUIDField(read_only=True)
    employee_name = serializers.SerializerMethodField()
    leave_type = LeaveTypeSerializer(read_only=True)
    leave_type_name = serializers.SerializerMethodField()
    reviewed_by_name = serializers.SerializerMethodField()
    days_requested = serializers.DecimalField(
        max_digits=6, decimal_places=2, coerce_to_string=False, read_only=True
    )

    class Meta:
        from simorgh.apps.hr_core.models import LeaveRequest
        model = LeaveRequest
        fields = (
            "public_id", "employee_id", "employee_name", "leave_type",
            "leave_type_name", "from_date", "to_date", "days_requested",
            "reason", "status", "submitted_at", "reviewed_by_name",
            "reviewed_at", "review_note", "created_at",
        )
        read_only_fields = (
            "public_id", "employee_name", "leave_type", "leave_type_name",
            "days_requested", "submitted_at", "reviewed_by_name",
            "reviewed_at", "created_at",
        )

    def get_employee_name(self, obj) -> str:
        return str(obj.employee)

    def get_leave_type_name(self, obj) -> str:
        return obj.leave_type.name if obj.leave_type else ""

    def get_reviewed_by_name(self, obj) -> str | None:
        return str(obj.reviewed_by) if obj.reviewed_by else None


class LeaveBalanceSerializer(serializers.ModelSerializer):
    employee_name = serializers.SerializerMethodField()
    leave_type = LeaveTypeSerializer(read_only=True)
    allocated = serializers.SerializerMethodField()
    used = serializers.SerializerMethodField()
    pending = serializers.SerializerMethodField()
    remaining = serializers.SerializerMethodField()

    class Meta:
        from simorgh.apps.hr_core.models import LeaveBalance
        model = LeaveBalance
        fields = (
            "id", "employee_id", "employee_name", "leave_type",
            "year", "allocated", "used", "pending", "remaining",
        )
        read_only_fields = ("id", "employee_name", "leave_type", "used", "pending", "remaining")

    @staticmethod
    def _fmt(v) -> str:
        if v is None:
            return "0"
        s = str(v)
        if "." in s:
            s = s.rstrip("0").rstrip(".")
        return s if s else "0"

    def get_allocated(self, obj) -> str:
        return self._fmt(obj.allocated)

    def get_used(self, obj) -> str:
        return self._fmt(obj.used)

    def get_pending(self, obj) -> str:
        return self._fmt(obj.pending)

    def get_remaining(self, obj) -> str:
        return self._fmt(obj.remaining)

    def get_employee_name(self, obj) -> str:
        return str(obj.employee)


class PublicHolidaySerializer(serializers.ModelSerializer):
    class Meta:
        from simorgh.apps.hr_core.models import PublicHoliday
        model = PublicHoliday
        fields = ("id", "date", "name", "calendar_type", "is_recurring")
        read_only_fields = ("id",)
