from __future__ import annotations

from rest_framework import serializers

from simorgh.core.api.serializers import PublicIdMixin, ReadOnlyTimestampsMixin, TenantScopedSerializer


class JobTitleSerializer(serializers.ModelSerializer):
    class Meta:
        from simorgh.apps.hr_core.models.employee import JobTitle
        model = JobTitle
        fields = ("id", "title", "level", "department_id")
        read_only_fields = ("id",)


class EmployeeSerializer(PublicIdMixin, ReadOnlyTimestampsMixin, TenantScopedSerializer):
    display_name = serializers.SerializerMethodField()
    department_name = serializers.SerializerMethodField()
    manager_name = serializers.SerializerMethodField()
    job_title = serializers.SerializerMethodField()
    national_id = serializers.SerializerMethodField()
    birth_date = serializers.SerializerMethodField()
    personal_email = serializers.SerializerMethodField()

    class Meta:
        from simorgh.apps.hr_core.models import Employee
        model = Employee
        fields = (
            "id", "employee_no", "first_name", "last_name", "display_name",
            "employment_type", "hire_date", "termination_date", "status",
            "gender", "mobile", "work_email", "department_id", "department_name",
            "manager_id", "manager_name", "job_title_id", "job_title",
            "work_location", "national_id", "birth_date", "personal_email",
            "created_at", "updated_at",
        )
        read_only_fields = (
            "id", "employee_no", "display_name", "department_name",
            "manager_name", "job_title", "national_id", "birth_date",
            "personal_email", "created_at", "updated_at",
        )

    def _show_sensitive(self) -> bool:
        return bool(self.context.get("show_sensitive", False))

    def get_display_name(self, obj) -> str:
        return obj.display_name or obj.get_full_name()

    def get_department_name(self, obj) -> str | None:
        return obj.department.name if obj.department else None

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

    def get_job_title(self, obj) -> str | None:
        return obj.job_title.title if obj.job_title else None

    def get_national_id(self, obj) -> str:
        if self._show_sensitive() and obj.national_id:
            from simorgh.apps.hr_core.services import decrypt_field
            return decrypt_field(obj.national_id)
        return "****" if obj.national_id else ""

    def get_birth_date(self, obj):
        if self._show_sensitive():
            return obj.birth_date.isoformat() if obj.birth_date else None
        return None

    def get_personal_email(self, obj) -> str:
        if self._show_sensitive():
            return obj.personal_email
        return "****" if obj.personal_email else ""


class EmployeeDocumentSerializer(PublicIdMixin, serializers.ModelSerializer):
    class Meta:
        from simorgh.apps.hr_core.models import EmployeeDocument
        model = EmployeeDocument
        fields = ("id", "doc_type", "title", "dms_file_id", "expiry_date", "is_verified", "created_at")
        read_only_fields = ("id", "created_at")


class EmployeeBankAccountSerializer(PublicIdMixin, serializers.ModelSerializer):
    account_no = serializers.SerializerMethodField()
    iban = serializers.SerializerMethodField()

    class Meta:
        from simorgh.apps.hr_core.models import EmployeeBankAccount
        model = EmployeeBankAccount
        fields = ("id", "bank_name", "account_no", "iban", "is_default")
        read_only_fields = ("id", "account_no", "iban")

    def _show_sensitive(self) -> bool:
        return bool(self.context.get("show_sensitive", False))

    def get_account_no(self, obj) -> str:
        if self._show_sensitive():
            from simorgh.apps.hr_core.services import decrypt_field
            return decrypt_field(obj.account_no)
        return "****"

    def get_iban(self, obj) -> str:
        if not obj.iban:
            return ""
        if self._show_sensitive():
            from simorgh.apps.hr_core.services import decrypt_field
            return decrypt_field(obj.iban)
        return "****"
