from rest_framework import serializers

from infrastructure.models import Attendance, Holiday, LeaveRequest, User, WorkSchedule


class UserSerializer(serializers.ModelSerializer):
    """Legacy user shape. `is_admin` is derived from permissions and passed in by the caller
    (context["is_admin"]); the stored User.is_admin flag no longer grants or reveals anything."""

    has_name = serializers.BooleanField(read_only=True)
    is_admin = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ["id", "personnel_code", "name", "is_admin", "has_name"]

    def get_is_admin(self, obj) -> bool:
        return bool(self.context.get("is_admin", False))


class LoginSerializer(serializers.Serializer):
    personnel_code = serializers.CharField()
    password = serializers.CharField()


class CompleteProfileSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=255, allow_blank=False)


class AttendanceSerializer(serializers.ModelSerializer):
    worked = serializers.CharField(source="worked_hours_formatted", read_only=True)

    class Meta:
        model = Attendance
        fields = [
            "id",
            "date",
            "check_in",
            "check_out",
            "is_default_checkout",
            "tasks_note",
            "worked",
        ]


class CheckOutSerializer(serializers.Serializer):
    tasks_note = serializers.CharField(min_length=3, max_length=5000)


class HolidaySerializer(serializers.ModelSerializer):
    class Meta:
        model = Holiday
        fields = ["id", "date", "title", "description"]


class LeaveRequestSerializer(serializers.ModelSerializer):
    user_id = serializers.IntegerField(source="user.id", read_only=True)
    personnel_code = serializers.CharField(source="user.personnel_code", read_only=True)
    user_name = serializers.CharField(source="user.name", read_only=True)
    reviewed_by_name = serializers.SerializerMethodField()

    def get_reviewed_by_name(self, obj):
        reviewer = obj.reviewed_by
        return (reviewer.name or reviewer.username or reviewer.personnel_code) if reviewer else None

    class Meta:
        model = LeaveRequest
        fields = [
            "id",
            "user_id",
            "personnel_code",
            "user_name",
            "date",
            "type",
            "start_time",
            "end_time",
            "category",
            "reason",
            "status",
            "reviewed_by",
            "reviewed_by_name",
            "reviewed_at",
            "review_note",
            "created_at",
        ]
        read_only_fields = ["status", "reviewed_by", "reviewed_at", "review_note", "created_at"]


class LeaveRequestCreateSerializer(serializers.Serializer):
    date = serializers.DateField()
    type = serializers.ChoiceField(choices=["daily", "hourly"])
    category = serializers.ChoiceField(choices=["annual", "sick", "unpaid"])
    start_time = serializers.TimeField(required=False, allow_null=True)
    end_time = serializers.TimeField(required=False, allow_null=True)
    reason = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=2000)


class GrantLeaveSerializer(serializers.Serializer):
    user_id = serializers.IntegerField()
    date = serializers.DateField()
    category = serializers.ChoiceField(choices=["annual", "sick", "unpaid"], default="annual")


class CreatePersonnelSerializer(serializers.Serializer):
    personnel_code = serializers.CharField(max_length=50)
    name = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=255)
    password = serializers.CharField(min_length=4)


class AdminAttendanceEditSerializer(serializers.Serializer):
    check_in = serializers.TimeField(required=False, allow_null=True)
    check_out = serializers.TimeField(required=False, allow_null=True)
    tasks_note = serializers.CharField(required=False, allow_blank=True, allow_null=True, max_length=5000)


class MonthlyReportRowSerializer(serializers.Serializer):
    date = serializers.DateField()
    jalali_date = serializers.CharField()
    check_in = serializers.TimeField(allow_null=True)
    check_out = serializers.TimeField(allow_null=True)
    is_default_checkout = serializers.BooleanField()
    worked = serializers.CharField(allow_null=True)
    tasks_note = serializers.CharField(allow_null=True)
    is_holiday = serializers.BooleanField()
    holiday_title = serializers.CharField(allow_null=True)
    leaves = serializers.SerializerMethodField()
    missing = serializers.BooleanField()
    standard_check_in = serializers.TimeField(allow_null=True)
    standard_check_out = serializers.TimeField(allow_null=True)
    late = serializers.CharField(allow_null=True)
    overtime = serializers.CharField(allow_null=True)

    def get_leaves(self, obj):
        return LeaveRequestSerializer(obj.leaves, many=True).data


class WorkScheduleSerializer(serializers.ModelSerializer):
    class Meta:
        model = WorkSchedule
        fields = ["id", "date", "standard_check_in", "standard_check_out"]


class WorkScheduleSetSerializer(serializers.Serializer):
    standard_check_in = serializers.TimeField()
    standard_check_out = serializers.TimeField()
