"""API, health, tenant isolation, and foundation flow tests."""
from __future__ import annotations

from app.events.publisher import get_event_publisher
from app.tests.conftest import TENANT_A, TENANT_B, tenant_headers


async def test_health_capabilities_metrics(client):
    health = await client.get("/health")
    assert health.status_code == 200
    body = health.json()
    assert body["status"] == "ok"
    assert body["service"] == "healthcare-service"

    caps = await client.get("/capabilities")
    assert caps.status_code == 200
    c = caps.json()
    assert c["phase"] == "13.7"
    assert c["commercial_product"] == "Torbat Healthcare"
    assert c["features"]["foundation"] is True
    assert c["features"]["doctors"] is True
    assert c["features"]["appointments"] is True
    assert c["features"]["visits"] is True
    assert c["features"]["patient_portal"] is True
    assert c["features"]["medical_records"] is True
    assert c["features"]["pharmacy"] is True
    assert c["features"]["delivery_integration"] is True
    assert c["independence"]["integration_mode"] == "api_and_events_only"

    metrics = await client.get("/metrics")
    assert metrics.status_code == 200
    assert metrics.json()["phase"] == "13.7"


async def test_foundation_flow_and_events(client):
    headers = tenant_headers(TENANT_A)
    clinic = await client.post(
        "/api/v1/clinics",
        headers=headers,
        json={"code": "CLN1", "name": "City Clinic", "status": "active"},
    )
    assert clinic.status_code == 201, clinic.text
    clinic_id = clinic.json()["id"]

    branch = await client.post(
        "/api/v1/branches",
        headers=headers,
        json={
            "clinic_id": clinic_id,
            "code": "BR1",
            "name": "Main Branch",
        },
    )
    assert branch.status_code == 201, branch.text

    department = await client.post(
        "/api/v1/departments",
        headers=headers,
        json={
            "clinic_id": clinic_id,
            "code": "CARDIO",
            "name": "Cardiology",
        },
    )
    assert department.status_code == 201, department.text

    doctor = await client.post(
        "/api/v1/doctors",
        headers=headers,
        json={
            "user_id": "user-doctor-1",
            "clinic_id": clinic_id,
            "code": "DOC1",
            "display_name": "Dr. Smith",
        },
    )
    assert doctor.status_code == 201, doctor.text

    patient = await client.post(
        "/api/v1/patients",
        headers=headers,
        json={
            "user_id": "user-patient-1",
            "code": "PAT1",
            "display_name": "Jane Doe",
        },
    )
    assert patient.status_code == 201, patient.text

    provider = await client.post(
        "/api/v1/external-providers",
        headers=headers,
        json={
            "clinic_id": clinic_id,
            "code": "COMM_X",
            "name": "External Comm X",
            "provider_kind": "communication",
            "adapter_key": "mock_comm",
        },
    )
    assert provider.status_code == 201, provider.text

    cfg = await client.post(
        "/api/v1/configurations",
        headers=headers,
        json={"clinic_id": clinic_id, "code": "DEFAULT"},
    )
    assert cfg.status_code == 201, cfg.text

    setting = await client.put(
        "/api/v1/settings",
        headers=headers,
        json={
            "clinic_id": clinic_id,
            "key": "default_locale",
            "value": {"code": "fa"},
        },
    )
    assert setting.status_code == 200, setting.text

    audit = await client.get(
        "/api/v1/audit",
        headers=headers,
        params={"entity_type": "clinic", "entity_id": clinic_id},
    )
    assert audit.status_code == 200
    assert len(audit.json()) >= 1

    published = [e.event_type for e in get_event_publisher().published]
    assert "healthcare.clinic.created" in published
    assert "healthcare.branch.created" in published
    assert "healthcare.department.created" in published
    assert "healthcare.doctor.created" in published
    assert "healthcare.patient.created" in published
    assert "healthcare.external_provider.registered" in published
    assert "healthcare.setting.updated" in published


async def test_tenant_isolation(client):
    headers_a = tenant_headers(TENANT_A)
    headers_b = tenant_headers(TENANT_B)

    created = await client.post(
        "/api/v1/clinics",
        headers=headers_a,
        json={"code": "ISO1", "name": "Tenant A Clinic"},
    )
    assert created.status_code == 201
    clinic_id = created.json()["id"]

    denied = await client.get(f"/api/v1/clinics/{clinic_id}", headers=headers_b)
    assert denied.status_code == 404

    listed_b = await client.get("/api/v1/clinics", headers=headers_b)
    assert listed_b.status_code == 200
    assert listed_b.json() == []

    listed_a = await client.get("/api/v1/clinics", headers=headers_a)
    assert listed_a.status_code == 200
    assert len(listed_a.json()) == 1


async def test_missing_tenant_header_rejected(client):
    res = await client.get("/api/v1/clinics")
    assert res.status_code in (400, 422)
