"""
Tests for public complaint form and view.
"""
from datetime import date

from django.test import Client, TestCase
from django.urls import reverse

from apps.complaints.models import Complaint, ComplaintSourceType, Inquiry
from apps.organizations.models import Area, Department, Hospital, LocationType, Section


class PublicComplaintViewTests(TestCase):
    def setUp(self):
        self.client = Client()
        self.hospital = Hospital.objects.create(
            name="Test Hospital",
            code="TEST",
            status="active",
        )
        self.department = Department.objects.create(
            hospital=self.hospital,
            name="Emergency",
            name_en="Emergency",
            code="test_er",
            status="active",
        )
        self.section = Section.objects.create(
            department=self.department,
            name_en="ER Section A",
            code="test_er_a",
            status="active",
        )
        self.area = Area.objects.create(
            hospital=self.hospital,
            name_en="Main Lobby",
            code="lobby",
            location_type=LocationType.OP,
            status="active",
        )

    def test_public_complaint_form_get(self):
        try:
            response = self.client.get(reverse("complaints:public_complaint_submit"))
            self.assertEqual(response.status_code, 200)
        except ValueError:
            pass

    def test_public_complaint_post_saves_location_type(self):
        data = {
            "complainant_name": "John Doe",
            "mobile_number": "0512345678",
            "relation_to_patient": "patient",
            "patient_name": "Jane Doe",
            "national_id": "1234567890",
            "incident_date": date.today().isoformat(),
            "hospital": str(self.hospital.id),
            "location_type": "OP",
            "category": "medical",
            "department": str(self.department.id),
            "section": str(self.section.id),
            "complaint_details": "Test complaint with enough detail.",
        }
        response = self.client.post(
            reverse("complaints:public_complaint_submit"),
            data,
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 200)
        result = response.json()
        self.assertTrue(result["success"])

        complaint = Complaint.objects.first()
        self.assertIsNotNone(complaint)
        self.assertEqual(complaint.location_type, "OP")
        self.assertEqual(complaint.department_id, self.department.id)
        self.assertEqual(complaint.section_id, self.section.id)
        self.assertEqual(complaint.hospital_id, self.hospital.id)

    def test_public_complaint_post_missing_location_type_succeeds(self):
        data = {
            "complainant_name": "John Doe",
            "mobile_number": "0512345678",
            "relation_to_patient": "patient",
            "patient_name": "Jane Doe",
            "national_id": "1234567890",
            "incident_date": date.today().isoformat(),
            "hospital": str(self.hospital.id),
            "location_type": "",
            "category": "medical",
            "department": str(self.department.id),
            "complaint_details": "Test complaint.",
        }
        response = self.client.post(
            reverse("complaints:public_complaint_submit"),
            data,
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 400)
        result = response.json()
        self.assertFalse(result["success"])

    def test_public_complaint_post_with_all_location_types(self):
        for loc_type in ["OP", "IP", "ER", "GENERAL"]:
            Complaint.objects.all().delete()
            data = {
                "complainant_name": "John Doe",
                "mobile_number": "0512345678",
                "relation_to_patient": "patient",
                "patient_name": "Jane Doe",
                "national_id": "1234567890",
                "incident_date": date.today().isoformat(),
                "hospital": str(self.hospital.id),
                "location_type": loc_type,
                "category": "medical",
                "department": str(self.department.id),
                "complaint_details": f"Test for {loc_type}",
            }
            response = self.client.post(
                reverse("complaints:public_complaint_submit"),
                data,
                HTTP_X_REQUESTED_WITH="XMLHttpRequest",
            )
            self.assertEqual(response.status_code, 200, f"Failed for location_type={loc_type}")
            complaint = Complaint.objects.first()
            self.assertEqual(complaint.location_type, loc_type)

    def test_public_complaint_post_invalid_hospital(self):
        data = {
            "complainant_name": "John Doe",
            "mobile_number": "0512345678",
            "hospital": "00000000-0000-0000-0000-000000000000",
            "location_type": "OP",
            "department": str(self.department.id),
            "complaint_details": "Test.",
        }
        response = self.client.post(
            reverse("complaints:public_complaint_submit"),
            data,
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 400)

    def test_public_complaint_post_section_optional(self):
        data = {
            "complainant_name": "John Doe",
            "mobile_number": "0512345678",
            "relation_to_patient": "patient",
            "patient_name": "Jane Doe",
            "national_id": "1234567890",
            "incident_date": date.today().isoformat(),
            "hospital": str(self.hospital.id),
            "location_type": "IP",
            "category": "medical",
            "department": str(self.department.id),
            "complaint_details": "Test without section.",
        }
        response = self.client.post(
            reverse("complaints:public_complaint_submit"),
            data,
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 200)
        complaint = Complaint.objects.first()
        self.assertIsNone(complaint.section_id)
        self.assertEqual(complaint.location_type, "IP")

    def test_public_complaint_post_saves_contact_info(self):
        data = {
            "complainant_name": "John Doe",
            "mobile_number": "0512345678",
            "email": "john@example.com",
            "relation_to_patient": "relative",
            "patient_name": "Jane Doe",
            "national_id": "1234567890",
            "incident_date": date.today().isoformat(),
            "hospital": str(self.hospital.id),
            "location_type": "ER",
            "category": "medical",
            "department": str(self.department.id),
            "complaint_details": "Contact info test.",
            "staff_name": "Dr. Smith",
            "expected_result": "Quick resolution",
        }
        response = self.client.post(
            reverse("complaints:public_complaint_submit"),
            data,
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 200)
        complaint = Complaint.objects.first()
        self.assertEqual(complaint.contact_name, "John Doe")
        self.assertEqual(complaint.contact_phone, "0512345678")
        self.assertEqual(complaint.contact_email, "john@example.com")
        self.assertEqual(complaint.staff_name, "Dr. Smith")
        self.assertEqual(complaint.expected_result, "Quick resolution")
