"""
Organizations serializers
"""

from rest_framework import serializers

from .models import (
    Area,
    Department,
    Hospital,
    LegacyHierarchyMapping,
    LegacyLocation,
    LegacyMainSection,
    LegacySubSection,
    OrgSubSection,
    Section,
    SubSection,
    Organization,
    Patient,
    Staff,
)


class OrganizationSerializer(serializers.ModelSerializer):
    """Organization serializer"""

    hospitals_count = serializers.SerializerMethodField()

    class Meta:
        model = Organization
        fields = [
            "id",
            "name",
            "name_ar",
            "code",
            "address",
            "city",
            "phone",
            "email",
            "website",
            "status",
            "license_number",
            "logo",
            "hospitals_count",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_hospitals_count(self, obj):
        """Get count of hospitals in this organization"""
        return obj.hospitals.count()


class HospitalSerializer(serializers.ModelSerializer):
    """Hospital serializer"""

    organization_name = serializers.CharField(source="organization.name", read_only=True)
    departments_count = serializers.SerializerMethodField()

    class Meta:
        model = Hospital
        fields = [
            "id",
            "organization",
            "organization_name",
            "name",
            "name_ar",
            "display_name",
            "display_name_ar",
            "code",
            "address",
            "city",
            "phone",
            "email",
            "status",
            "license_number",
            "capacity",
            "departments_count",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_departments_count(self, obj):
        """Get count of departments in this hospital"""
        return obj.departments.count()


class DepartmentSerializer(serializers.ModelSerializer):
    """Department serializer"""

    hospital_name = serializers.CharField(source="hospital.name", read_only=True)
    parent_name = serializers.CharField(source="parent.name", read_only=True)
    manager_name = serializers.SerializerMethodField()

    class Meta:
        model = Department
        fields = [
            "id",
            "hospital",
            "hospital_name",
            "name",
            "name_en",
            "name_ar",
            "code",
            "category",
            "parent",
            "parent_name",
            "manager",
            "manager_name",
            "phone",
            "email",
            "location",
            "status",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_manager_name(self, obj):
        """Get manager full name"""
        if obj.manager:
            return obj.manager.get_full_name()
        return None


class StaffSerializer(serializers.ModelSerializer):
    """Staff serializer"""

    hospital_name = serializers.CharField(source="hospital.name", read_only=True)
    department_name_display = serializers.CharField(source="department.name", read_only=True)
    department_name = serializers.CharField(read_only=True)
    full_name = serializers.CharField(source="get_full_name", read_only=True)
    localized_name = serializers.CharField(source="get_localized_name", read_only=True)
    org_info = serializers.CharField(source="get_org_info", read_only=True)
    user_email = serializers.EmailField(source="user.email", read_only=True, allow_null=True)
    has_user_account = serializers.BooleanField(read_only=True)
    report_to_name = serializers.SerializerMethodField()
    direct_reports_count = serializers.SerializerMethodField()

    # User creation fields (write-only)
    create_user = serializers.BooleanField(write_only=True, required=False, default=False)
    user_username = serializers.CharField(write_only=True, required=False, allow_blank=True)
    user_password = serializers.CharField(write_only=True, required=False, allow_blank=True)
    send_email = serializers.BooleanField(write_only=True, required=False, default=True)

    class Meta:
        model = Staff
        fields = [
            "id",
            "user",
            "name",
            "first_name",
            "last_name",
            "first_name_ar",
            "last_name_ar",
            "full_name",
            "localized_name",
            "org_info",
            "staff_type",
            "department_type",
            "job_title",
            "license_number",
            "specialization",
            "employee_id",
            "email",
            "phone",
            "hospital",
            "hospital_name",
            "department",
            "department_name",
            "department_name_display",
            "location",
            "section",
            "subsection",
            "country",
            "gender",
            "report_to",
            "report_to_name",
            "direct_reports_count",
            "user_email",
            "has_user_account",
            "status",
            "created_at",
            "updated_at",
            "create_user",
            "user_username",
            "user_password",
            "send_email",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_report_to_name(self, obj):
        if obj.report_to:
            return obj.report_to.get_localized_name()
        return None

    def get_direct_reports_count(self, obj):
        """Get count of direct reports"""
        return obj.direct_reports.count()

    def to_representation(self, instance):
        """Customize representation"""
        data = super().to_representation(instance)
        data["has_user_account"] = instance.user is not None
        return data

    def create(self, validated_data):
        """Create staff with optional user account"""
        # Extract user creation fields
        create_user = validated_data.pop("create_user", False)
        user_username = validated_data.pop("user_username", "")
        user_password = validated_data.pop("user_password", "")
        send_email = validated_data.pop("send_email", True)

        # Create staff instance
        staff = Staff.objects.create(**validated_data)

        # Optionally create user account
        if create_user and not staff.user:
            from .services import StaffService

            # Determine role based on staff_type
            role = 'staff'

            # Create user account
            try:
                user, was_created, password = StaffService.create_user_for_staff(
                    staff, role=role, request=self.context.get("request")
                )

                # Send email if requested and user was created
                if was_created and user and send_email and self.context.get("request"):
                    try:
                        StaffService.send_password_reset_email(staff, self.context["request"])
                    except Exception as e:
                        # Log but don't fail if email sending fails
                        pass
            except ValueError as e:
                # If user creation fails, still return the staff
                pass

        return staff

    def update(self, instance, validated_data):
        """Update staff with optional user account creation"""
        # Extract user creation fields
        create_user = validated_data.pop("create_user", False)
        user_username = validated_data.pop("user_username", "")
        user_password = validated_data.pop("user_password", "")
        send_email = validated_data.pop("send_email", True)

        # Update staff fields
        for attr, value in validated_data.items():
            setattr(instance, value)

        instance.save()

        # Optionally create user account if it doesn't exist
        if create_user and not instance.user:
            from .services import StaffService

            # Determine role based on staff_type
            role = 'staff'

            try:
                user, was_created, password = StaffService.create_user_for_staff(
                    instance, role=role, request=self.context.get("request")
                )

                # Send email if requested and user was created
                if was_created and user and send_email and self.context.get("request"):
                    try:
                        StaffService.send_password_reset_email(instance, self.context["request"])
                    except Exception as e:
                        pass
            except ValueError as e:
                pass

        return instance


class PatientSerializer(serializers.ModelSerializer):
    """Patient serializer"""

    primary_hospital_name = serializers.CharField(source="primary_hospital.name", read_only=True)
    full_name = serializers.CharField(source="get_full_name", read_only=True)
    age = serializers.SerializerMethodField()
    national_id = serializers.SerializerMethodField()
    national_id_masked = serializers.SerializerMethodField()

    class Meta:
        model = Patient
        fields = [
            "id",
            "mrn",
            "national_id",
            "national_id_masked",
            "first_name",
            "last_name",
            "first_name_ar",
            "last_name_ar",
            "full_name",
            "date_of_birth",
            "age",
            "gender",
            "phone",
            "email",
            "address",
            "city",
            "primary_hospital",
            "primary_hospital_name",
            "status",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_national_id(self, obj):
        request = self.context.get("request")
        if request and request.user and request.user.is_superuser:
            return obj.national_id
        return None

    def get_national_id_masked(self, obj):
        return obj.get_masked_national_id()

    def get_age(self, obj):
        """Calculate patient age"""
        if obj.date_of_birth:
            from datetime import date

            today = date.today()
            return (
                today.year
                - obj.date_of_birth.year
                - ((today.month, today.day) < (obj.date_of_birth.month, obj.date_of_birth.day))
            )
        return None


class PatientListSerializer(serializers.ModelSerializer):
    """Simplified patient serializer for list views"""

    full_name = serializers.CharField(source="get_full_name", read_only=True)
    primary_hospital_name = serializers.CharField(source="primary_hospital.name", read_only=True)
    national_id_masked = serializers.CharField(source="get_masked_national_id", read_only=True)

    class Meta:
        model = Patient
        fields = ["id", "mrn", "full_name", "national_id_masked", "phone", "email", "primary_hospital_name", "status"]


class LegacyLocationSerializer(serializers.ModelSerializer):
    """Location serializer for dropdown"""

    name = serializers.SerializerMethodField()

    class Meta:
        model = LegacyLocation
        fields = ["id", "name"]

    def get_name(self, obj):
        """Return name based on current language"""
        from django.utils.translation import get_language

        lang = get_language()

        if lang == "ar" and obj.name_ar:
            return obj.name_ar
        return obj.name_en if obj.name_en else obj.name_ar


class LegacyMainSectionSerializer(serializers.ModelSerializer):
    """MainSection serializer for dropdown"""

    name = serializers.SerializerMethodField()

    class Meta:
        model = LegacyMainSection
        fields = ["id", "name"]

    def get_name(self, obj):
        """Return name based on current language"""
        from django.utils.translation import get_language

        lang = get_language()

        if lang == "ar" and obj.name_ar:
            return obj.name_ar
        return obj.name_en if obj.name_en else obj.name_ar


class LegacySubSectionSerializer(serializers.ModelSerializer):
    """SubSection serializer for dropdown"""

    id = serializers.IntegerField(source="internal_id", read_only=True)
    name = serializers.SerializerMethodField()
    location_name = serializers.SerializerMethodField()
    main_section_name = serializers.SerializerMethodField()

    class Meta:
        model = LegacySubSection
        fields = ["id", "name", "location", "main_section", "location_name", "main_section_name"]

    def get_name(self, obj):
        """Return name based on current language"""
        from django.utils.translation import get_language

        lang = get_language()

        if lang == "ar" and obj.name_ar:
            return obj.name_ar
        return obj.name_en if obj.name_en else obj.name_ar

    def get_location_name(self, obj):
        """Return location name based on current language"""
        from django.utils.translation import get_language

        lang = get_language()

        if lang == "ar" and obj.location.name_ar:
            return obj.location.name_ar
        return obj.location.name_en if obj.location.name_en else obj.location.name_ar

    def get_main_section_name(self, obj):
        """Return main section name based on current language"""
        from django.utils.translation import get_language

        lang = get_language()

        if lang == "ar" and obj.main_section.name_ar:
            return obj.main_section.name_ar
        return obj.main_section.name_en if obj.main_section.name_en else obj.main_section.name_ar


class OrgSubSectionSerializer(serializers.ModelSerializer):
    department_name = serializers.SerializerMethodField()
    display_name = serializers.SerializerMethodField()

    class Meta:
        model = Section
        fields = "__all__"

    def get_department_name(self, obj):
        return str(obj.department)

    def get_display_name(self, obj):
        return obj.get_localized_display_name()


# Backward compatibility alias
SectionSerializer = OrgSubSectionSerializer


class SubSectionSerializer(serializers.ModelSerializer):
    section_name = serializers.SerializerMethodField()
    display_name = serializers.SerializerMethodField()

    class Meta:
        model = SubSection
        fields = "__all__"

    def get_section_name(self, obj):
        return str(obj.section)

    def get_display_name(self, obj):
        return obj.get_localized_name()


class LegacyHierarchyMappingSerializer(serializers.ModelSerializer):
    class Meta:
        model = LegacyHierarchyMapping
        fields = "__all__"


# Backward-compatible aliases
LocationSerializer = LegacyLocationSerializer
MainSectionSerializer = LegacyMainSectionSerializer


class AreaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Area
        fields = ["id", "hospital", "name_en", "name_ar", "code", "location_type", "status"]
