"""
Complaints serializers
"""

from rest_framework import serializers

from .models import (
    Complaint,
    ComplaintAttachment,
    ComplaintMeeting,
    ComplaintPRInteraction,
    ComplaintUpdate,
    Inquiry,
    ComplaintExplanation,
)


class ComplaintAttachmentSerializer(serializers.ModelSerializer):
    """Complaint attachment serializer"""

    uploaded_by_name = serializers.SerializerMethodField()

    class Meta:
        model = ComplaintAttachment
        fields = [
            "id",
            "complaint",
            "file",
            "filename",
            "file_type",
            "file_size",
            "uploaded_by",
            "uploaded_by_name",
            "description",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "file_size", "created_at", "updated_at"]

    def get_uploaded_by_name(self, obj):
        """Get uploader name"""
        if obj.uploaded_by:
            return obj.uploaded_by.get_full_name()
        return None


class ComplaintUpdateSerializer(serializers.ModelSerializer):
    """Complaint update serializer"""

    created_by_name = serializers.SerializerMethodField()

    class Meta:
        model = ComplaintUpdate
        fields = [
            "id",
            "complaint",
            "update_type",
            "message",
            "created_by",
            "created_by_name",
            "old_status",
            "new_status",
            "metadata",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_created_by_name(self, obj):
        """Get creator name"""
        if obj.created_by:
            return obj.created_by.get_full_name()
        return None


class ComplaintPRInteractionSerializer(serializers.ModelSerializer):
    """PR Interaction serializer"""

    complaint_title = serializers.CharField(source="complaint.title", read_only=True)
    pr_staff_name = serializers.SerializerMethodField()
    created_by_name = serializers.SerializerMethodField()
    contact_method_display = serializers.CharField(source="get_contact_method_display", read_only=True)

    class Meta:
        model = ComplaintPRInteraction
        fields = [
            "id",
            "complaint",
            "complaint_title",
            "contact_date",
            "contact_method",
            "contact_method_display",
            "pr_staff",
            "pr_staff_name",
            "statement_text",
            "procedure_explained",
            "notes",
            "created_by",
            "created_by_name",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_pr_staff_name(self, obj):
        """Get PR staff name"""
        if obj.pr_staff:
            return obj.pr_staff.get_full_name()
        return None

    def get_created_by_name(self, obj):
        """Get creator name"""
        if obj.created_by:
            return obj.created_by.get_full_name()
        return None


class ComplaintMeetingSerializer(serializers.ModelSerializer):
    """Complaint Meeting serializer"""

    complaint_title = serializers.CharField(source="complaint.title", read_only=True)
    created_by_name = serializers.SerializerMethodField()
    meeting_type_display = serializers.CharField(source="get_meeting_type_display", read_only=True)

    class Meta:
        model = ComplaintMeeting
        fields = [
            "id",
            "complaint",
            "complaint_title",
            "meeting_date",
            "meeting_type",
            "meeting_type_display",
            "outcome",
            "notes",
            "created_by",
            "created_by_name",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_created_by_name(self, obj):
        """Get creator name"""
        if obj.created_by:
            return obj.created_by.get_full_name()
        return None


class ComplaintSerializer(serializers.ModelSerializer):
    """Complaint serializer"""

    patient_name = serializers.CharField(source="patient.get_full_name", read_only=True)
    patient_mrn = serializers.CharField(source="patient.mrn", read_only=True)
    hospital_name = serializers.CharField(source="hospital.name", read_only=True)
    department_name = serializers.CharField(source="department.name", read_only=True)
    staff_name = serializers.SerializerMethodField()
    assigned_to_name = serializers.SerializerMethodField()
    created_by_name = serializers.SerializerMethodField()
    source_name = serializers.CharField(source="source.name_en", read_only=True)
    source_code = serializers.CharField(source="source.code", read_only=True)
    complaint_source_type_display = serializers.CharField(source="get_complaint_source_type_display", read_only=True)
    complaint_type_display = serializers.CharField(source="get_complaint_type_display", read_only=True)
    attachments = ComplaintAttachmentSerializer(many=True, read_only=True)
    updates = ComplaintUpdateSerializer(many=True, read_only=True)
    sla_status = serializers.SerializerMethodField()

    # 4-level taxonomy fields
    domain_details = serializers.SerializerMethodField()
    category_details = serializers.SerializerMethodField()
    subcategory_details = serializers.SerializerMethodField()
    classification_details = serializers.SerializerMethodField()
    taxonomy_path = serializers.SerializerMethodField()

    class Meta:
        model = Complaint
        fields = [
            "id",
            "patient",
            "patient_name",
            "patient_mrn",
            "encounter_id",
            "hospital",
            "hospital_name",
            "department",
            "department_name",
            "staff",
            "staff_name",
            "title",
            "description",
            "reference_number",
            "domain",
            "domain_details",
            "category",
            "category_details",
            "subcategory",
            "subcategory_details",
            "subcategory_obj",
            "classification",
            "classification_obj",
            "classification_details",
            "taxonomy_path",
            "priority",
            "severity",
            "complaint_type",
            "complaint_type_display",
            "complaint_source_type",
            "complaint_source_type_display",
            "source",
            "source_name",
            "source_code",
            "status",
            "patient_contact_status",
            "patient_contact_status_at",
            "created_by",
            "created_by_name",
            "assigned_to",
            "assigned_to_name",
            "assigned_at",
            "activated_at",
            "due_at",
            "is_overdue",
            "sla_status",
            "reminder_sent_at",
            "escalated_at",
            "legacy_location",
            "legacy_main_section",
            "legacy_subsection",
            "section",
            
            "resolution",
            "resolution_category",
            "resolution_outcome",
            "resolved_at",
            "resolved_by",
            "reopened_at",
            "reopened_by",
            "closed_at",
            "closed_by",
            "resolution_survey",
            "resolution_survey_sent_at",
            "contact_name",
            "contact_phone",
            "national_id",
            "incident_date",
            "attachments",
            "updates",
            "metadata",
            "created_at",
            "updated_at",
        ]
        read_only_fields = [
            "id",
            "created_by",
            "assigned_at",
            "is_overdue",
            "reference_number",
            "reminder_sent_at",
            "escalated_at",
            "resolved_at",
            "closed_at",
            "resolution_survey_sent_at",
            "created_at",
            "updated_at",
        ]

    def get_domain_details(self, obj):
        """Get domain details"""
        if obj.domain:
            return {
                "id": str(obj.domain.id),
                "code": obj.domain.code or obj.domain.name_en.upper(),
                "name_en": obj.domain.name_en,
                "name_ar": obj.domain.name_ar,
            }
        return None

    def get_category_details(self, obj):
        """Get category details"""
        if obj.category:
            return {
                "id": str(obj.category.id),
                "code": obj.category.code or obj.category.name_en.upper(),
                "name_en": obj.category.name_en,
                "name_ar": obj.category.name_ar,
            }
        return None

    def get_subcategory_details(self, obj):
        """Get subcategory details"""
        if obj.subcategory_obj:
            return {
                "id": str(obj.subcategory_obj.id),
                "code": obj.subcategory_obj.code or obj.subcategory_obj.name_en.upper(),
                "name_en": obj.subcategory_obj.name_en,
                "name_ar": obj.subcategory_obj.name_ar,
            }
        return None

    def get_classification_details(self, obj):
        """Get classification details"""
        if obj.classification_obj:
            return {
                "id": str(obj.classification_obj.id),
                "code": obj.classification_obj.code,
                "name_en": obj.classification_obj.name_en,
                "name_ar": obj.classification_obj.name_ar,
            }
        return None

    def get_taxonomy_path(self, obj):
        """Get full taxonomy path as a string"""
        parts = []
        if obj.domain:
            parts.append(obj.domain.name_en)
        if obj.category:
            parts.append(obj.category.name_en)
        if obj.subcategory_obj:
            parts.append(obj.subcategory_obj.name_en)
        if obj.classification_obj:
            parts.append(obj.classification_obj.name_en)
        return " > ".join(parts) if parts else None

    def create(self, validated_data):
        """
        Create complaint with auto-setting of department from AI analysis.

        If metadata contains AI analysis with department name,
        automatically set the department field by querying the database.
        """
        from apps.organizations.models import Department
        import logging

        logger = logging.getLogger(__name__)

        # Extract metadata if present
        metadata = validated_data.get("metadata", {})

        # Check if department is not already set and AI analysis contains department info
        if not validated_data.get("department") and metadata.get("ai_analysis"):
            ai_analysis = metadata["ai_analysis"]
            department_name = ai_analysis.get("department")

            # If AI identified a department, try to match it in the database
            if department_name:
                hospital = validated_data.get("hospital")

                if hospital:
                    try:
                        # Try exact match first
                        department = Department.objects.filter(
                            hospital=hospital, status="active", name__iexact=department_name
                        ).first()

                        # If no exact match, try partial match
                        if not department:
                            department = Department.objects.filter(
                                hospital=hospital, status="active", name__icontains=department_name
                            ).first()

                        if department:
                            validated_data["department"] = department
                            logger.info(
                                f"Auto-set department '{department.name}' from AI analysis "
                                f"for complaint (matched from '{department_name}')"
                            )
                        else:
                            logger.warning(
                                f"AI suggested department '{department_name}' but no match found "
                                f"in hospital '{hospital.name}'"
                            )
                    except Exception as e:
                        logger.error(f"Error auto-setting department: {e}")

        # Create the complaint
        return super().create(validated_data)

    def get_staff_name(self, obj):
        """Get staff name"""
        if obj.staff:
            return f"{obj.staff.first_name} {obj.staff.last_name}"
        return None

    def get_assigned_to_name(self, obj):
        """Get assigned user name"""
        if obj.assigned_to:
            return obj.assigned_to.get_full_name()
        return None

    def get_created_by_name(self, obj):
        """Get creator name"""
        if obj.created_by:
            return obj.created_by.get_full_name()
        return None

    def get_sla_status(self, obj):
        """Get SLA status"""
        return obj.sla_status if hasattr(obj, "sla_status") else "on_track"


class ComplaintExplanationSerializer(serializers.ModelSerializer):
    """Complaint explanation serializer"""

    staff_name = serializers.SerializerMethodField()
    requested_by_name = serializers.SerializerMethodField()
    attachment_count = serializers.SerializerMethodField()

    class Meta:
        model = ComplaintExplanation
        fields = [
            "id",
            "complaint",
            "staff",
            "staff_name",
            "explanation",
            "token",
            "is_used",
            "email_sent_at",
            "responded_at",
            "submitted_via",
            "requested_by",
            "requested_by_name",
            "request_message",
            "attachment_count",
            "created_at",
        ]
        read_only_fields = ["id", "email_sent_at", "responded_at", "created_at"]

    def get_staff_name(self, obj):
        if obj.staff:
            return f"{obj.staff.first_name} {obj.staff.last_name}" if obj.staff.last_name else ""
        return ""

    def get_requested_by_name(self, obj):
        if obj.requested_by:
            return obj.requested_by.get_full_name()
        return None

    def get_attachment_count(self, obj):
        return obj.attachments.count()


class ComplaintListSerializer(serializers.ModelSerializer):
    """Simplified complaint serializer for list views"""

    patient_name = serializers.CharField(source="patient.get_full_name", read_only=True)
    patient_mrn = serializers.CharField(source="patient.mrn", read_only=True)
    hospital_name = serializers.CharField(source="hospital.name", read_only=True)
    department_name = serializers.CharField(source="department.name", read_only=True)
    staff_name = serializers.SerializerMethodField()
    assigned_to_name = serializers.SerializerMethodField()
    source_name = serializers.CharField(source="source.name_en", read_only=True)
    complaint_source_type_display = serializers.CharField(source="get_complaint_source_type_display", read_only=True)
    complaint_type_display = serializers.CharField(source="get_complaint_type_display", read_only=True)
    sla_status = serializers.SerializerMethodField()
    taxonomy_summary = serializers.SerializerMethodField()

    class Meta:
        model = Complaint
        fields = [
            "id",
            "reference_number",
            "patient_name",
            "patient_mrn",
            "encounter_id",
            "hospital_name",
            "department_name",
            "staff_name",
            "title",
            "ai_brief_en",
            "ai_brief_ar",
            "category",
            "subcategory",
            "taxonomy_summary",
            "priority",
            "severity",
            "complaint_type",
            "complaint_type_display",
            "complaint_source_type",
            "complaint_source_type_display",
            "source_name",
            "status",
            "patient_contact_status",
            "assigned_to_name",
            "assigned_at",
            "due_at",
            "is_overdue",
            "sla_status",
            "resolution",
            "resolved_at",
            "closed_at",
            "created_at",
            "updated_at",
        ]

    def get_staff_name(self, obj):
        """Get staff name"""
        if obj.staff:
            return f"{obj.staff.first_name} {obj.staff.last_name}"
        return None

    def get_assigned_to_name(self, obj):
        """Get assigned user name"""
        if obj.assigned_to:
            return obj.assigned_to.get_full_name()
        return None

    def get_sla_status(self, obj):
        """Get SLA status"""
        return obj.sla_status if hasattr(obj, "sla_status") else "on_track"

    def get_taxonomy_summary(self, obj):
        """Get brief taxonomy summary"""
        parts = []
        if obj.domain:
            parts.append(obj.domain.name_en)
        if obj.category:
            parts.append(obj.category.name_en)
        return " > ".join(parts) if parts else None


class InquirySerializer(serializers.ModelSerializer):
    """Inquiry serializer"""

    patient_name = serializers.CharField(source="patient.get_full_name", read_only=True)
    hospital_name = serializers.CharField(source="hospital.name", read_only=True)
    department_name = serializers.CharField(source="department.name", read_only=True)
    assigned_to_name = serializers.SerializerMethodField()
    created_by_name = serializers.SerializerMethodField()

    class Meta:
        model = Inquiry
        fields = [
            "id",
            "reference_number",
            "patient",
            "patient_name",
            "contact_name",
            "contact_phone",
            "contact_email",
            "hospital",
            "hospital_name",
            "department",
            "department_name",
            "subject",
            "message",
            "category",
            "priority",
            "ai_brief_en",
            "ai_brief_ar",
            "source",
            "status",
            "legacy_location",
            "legacy_main_section",
            "legacy_subsection",
            "section",
            
            "is_outgoing",
            "outgoing_department",
            "is_straightforward",
            "created_by",
            "created_by_name",
            "assigned_to",
            "assigned_to_name",
            "assigned_at",
            "activated_at",
            "due_at",
            "is_overdue",
            "breached_at",
            "escalated_at",
            "reminder_sent_at",
            "second_reminder_sent_at",
            "response",
            "response_en",
            "response_ar",
            "response_sent_at",
            "responded_at",
            "responded_by",
            "department_response_en",
            "department_response_ar",
            "department_response_summary_en",
            "department_response_summary_ar",
            "department_responded_at",
            "department_responded_by",
            "requires_follow_up",
            "follow_up_due_at",
            "follow_up_completed_at",
            "follow_up_completed_by",
            "follow_up_notes",
            "metadata",
            "created_at",
            "updated_at",
        ]
        read_only_fields = [
            "id",
            "reference_number",
            "created_by",
            "responded_at",
            "response_sent_at",
            "created_at",
            "updated_at",
        ]

    def get_assigned_to_name(self, obj):
        """Get assigned user name"""
        if obj.assigned_to:
            return obj.assigned_to.get_full_name()
        return None

    def get_created_by_name(self, obj):
        """Get creator name"""
        if obj.created_by:
            return obj.created_by.get_full_name()
        return None
