"""
Integrations serializers
"""

from rest_framework import serializers

from .models import EventMapping, InboundEvent, IntegrationConfig, SurveyTemplateMapping


class InboundEventSerializer(serializers.ModelSerializer):
    """Inbound event serializer"""

    class Meta:
        model = InboundEvent
        fields = [
            "id",
            "source_system",
            "event_code",
            "encounter_id",
            "patient_identifier",
            "payload_json",
            "status",
            "received_at",
            "processed_at",
            "error",
            "processing_attempts",
            "physician_license",
            "department_code",
            "metadata",
            "created_at",
            "updated_at",
        ]
        read_only_fields = [
            "id",
            "status",
            "received_at",
            "processed_at",
            "error",
            "processing_attempts",
            "metadata",
            "created_at",
            "updated_at",
        ]


class InboundEventCreateSerializer(serializers.ModelSerializer):
    """
    Serializer for creating inbound events via API.

    External systems POST to /api/integrations/events/ with:
    {
        "source_system": "his",
        "event_code": "OPD_VISIT_COMPLETED",
        "encounter_id": "ENC123456",
        "patient_identifier": "MRN789",
        "payload_json": {
            "physician_license": "PHY001",
            "department_code": "DEPT_OPD",
            "timestamp": "2025-12-14T10:30:00Z",
            ...
        }
    }
    """

    class Meta:
        model = InboundEvent
        fields = ["source_system", "event_code", "encounter_id", "patient_identifier", "payload_json"]

    def create(self, validated_data):
        """
        Create event and extract context from payload.
        Event will be processed asynchronously by Celery task.
        """
        payload = validated_data.get("payload_json", {})

        # Extract physician and department from payload
        validated_data["physician_license"] = payload.get("physician_license", "")
        validated_data["department_code"] = payload.get("department_code", "")

        event = InboundEvent.objects.create(**validated_data)

        # Queue event for processing (will be implemented in tasks.py)
        # from apps.integrations.tasks import process_inbound_event
        # process_inbound_event.delay(event.id)

        return event


class InboundEventListSerializer(serializers.ModelSerializer):
    """Simplified inbound event serializer for list views"""

    class Meta:
        model = InboundEvent
        fields = ["id", "source_system", "event_code", "encounter_id", "status", "processing_attempts", "received_at"]


class EventMappingSerializer(serializers.ModelSerializer):
    """Event mapping serializer"""

    integration_name = serializers.CharField(source="integration_config.name", read_only=True)

    class Meta:
        model = EventMapping
        fields = [
            "id",
            "integration_config",
            "integration_name",
            "external_event_code",
            "internal_event_code",
            "field_mappings",
            "is_active",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class SurveyTemplateMappingSerializer(serializers.ModelSerializer):
    """Survey template mapping serializer"""

    hospital_name = serializers.CharField(source="hospital.name", read_only=True)
    survey_template_name = serializers.CharField(source="survey_template.name", read_only=True)
    patient_type_display = serializers.CharField(source="get_patient_type_display", read_only=True)

    class Meta:
        model = SurveyTemplateMapping
        fields = [
            "id",
            "hospital",
            "hospital_name",
            "patient_type",
            "patient_type_display",
            "survey_template",
            "survey_template_name",
            "send_delay_hours",
            "is_active",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class IntegrationConfigSerializer(serializers.ModelSerializer):
    """Integration configuration serializer"""

    event_mappings = EventMappingSerializer(many=True, read_only=True)

    class Meta:
        model = IntegrationConfig
        fields = [
            "id",
            "name",
            "source_system",
            "description",
            "api_url",
            "is_active",
            "config_json",
            "event_mappings",
            "last_sync_at",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "last_sync_at", "created_at", "updated_at"]
        extra_kwargs = {
            "api_key": {"write_only": True}  # Don't expose API key in responses
        }


class HISPatientDemographicSerializer(serializers.Serializer):
    """Serializer for HIS patient demographic data"""

    Type = serializers.CharField()
    PatientID = serializers.CharField()
    AdmissionID = serializers.CharField()
    HospitalID = serializers.CharField(required=False, allow_blank=True)
    HospitalName = serializers.CharField()
    PatientType = serializers.CharField(required=False, allow_blank=True)
    AdmitDate = serializers.CharField()
    DischargeDate = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    RegCode = serializers.CharField(required=False, allow_blank=True)
    SSN = serializers.CharField(required=False, allow_blank=True)
    PatientName = serializers.CharField()
    GenderID = serializers.CharField(required=False, allow_blank=True)
    Gender = serializers.CharField(required=False, allow_blank=True)
    FullAge = serializers.CharField(required=False, allow_blank=True)
    PatientNationality = serializers.CharField(required=False, allow_blank=True)
    MobileNo = serializers.CharField()
    DOB = serializers.CharField(required=False, allow_blank=True)
    ConsultantID = serializers.CharField(required=False, allow_blank=True)
    PrimaryDoctor = serializers.CharField(required=False, allow_blank=True)
    CompanyID = serializers.CharField(required=False, allow_blank=True)
    GradeID = serializers.CharField(required=False, allow_blank=True)
    CompanyName = serializers.CharField(required=False, allow_blank=True)
    GradeName = serializers.CharField(required=False, allow_blank=True)
    InsuranceCompanyName = serializers.CharField(required=False, allow_blank=True)
    BillType = serializers.CharField(required=False, allow_blank=True)
    IsVIP = serializers.CharField(required=False, allow_blank=True)


class HISVisitDataSerializer(serializers.Serializer):
    """Serializer for HIS visit/timeline data"""

    Type = serializers.CharField()
    BillDate = serializers.CharField()
    PatientType = serializers.CharField(required=False, allow_blank=True)
    AdmissionID = serializers.CharField(required=False, allow_blank=True)
    PatientID = serializers.CharField(required=False, allow_blank=True)
    RegCode = serializers.CharField(required=False, allow_blank=True)
    SSN = serializers.CharField(required=False, allow_blank=True)
    MobileNo = serializers.CharField(required=False, allow_blank=True)


class HISPatientDataSerializer(serializers.Serializer):
    """
    Serializer for real HIS patient data format.

    This validates the structure of HIS data received from the simulator
    or actual HIS system.

    Example structure:
    {
        "FetchPatientDataTimeStampList": [{...patient demographics...}],
        "FetchPatientDataTimeStampVisitEDDataList": [...],
        "FetchPatientDataTimeStampVisitIPDataList": [...],
        "FetchPatientDataTimeStampVisitOPDataList": [...],
        "Code": 200,
        "Status": "Success",
        "Message": "",
        "Message2L": "",
        "MobileNo": "",
        "ValidateMessage": ""
    }
    """

    FetchPatientDataTimeStampList = HISPatientDemographicSerializer(many=True)
    FetchPatientDataTimeStampVisitEDDataList = HISVisitDataSerializer(many=True, required=False)
    FetchPatientDataTimeStampVisitIPDataList = HISVisitDataSerializer(many=True, required=False)
    FetchPatientDataTimeStampVisitOPDataList = HISVisitDataSerializer(many=True, required=False)
    FetchPatientDataTimeStampVisitDataList = HISVisitDataSerializer(many=True, required=False)
    Code = serializers.IntegerField()
    Status = serializers.CharField()
    Message = serializers.CharField(required=False, allow_blank=True)
    Message2L = serializers.CharField(required=False, allow_blank=True)
    MobileNo = serializers.CharField(required=False, allow_blank=True)
    ValidateMessage = serializers.CharField(required=False, allow_blank=True)

    def validate(self, data):
        """Validate HIS data structure"""
        # Validate status
        if data.get("Code") != 200:
            raise serializers.ValidationError(f"HIS returned error code: {data.get('Code')}")

        if data.get("Status") != "Success":
            raise serializers.ValidationError(f"HIS status not successful: {data.get('Status')}")

        # Ensure patient data exists
        patient_list = data.get("FetchPatientDataTimeStampList", [])
        if not patient_list:
            raise serializers.ValidationError("No patient data found in FetchPatientDataTimeStampList")

        return data
