"""Phase 13.7 — Delivery Integration tests."""
from __future__ import annotations

import pytest

from app.events.publisher import get_event_publisher
from app.events.types import HealthcareEventType
from app.providers.mocks import MockDeliveryProvider
from app.tests.conftest import TENANT_A, tenant_headers


async def _seed_ready_prescription(client):
    headers = tenant_headers(TENANT_A)
    clinic = await client.post(
        "/api/v1/clinics",
        headers=headers,
        json={"code": "CLN137", "name": "Delivery Clinic", "status": "active"},
    )
    clinic_id = clinic.json()["id"]
    doctor = await client.post(
        "/api/v1/doctors",
        headers=headers,
        json={"user_id": "doc-137", "clinic_id": clinic_id, "code": "DOC137", "display_name": "Dr Del"},
    )
    doctor_id = doctor.json()["id"]
    patient = await client.post(
        "/api/v1/patients",
        headers=headers,
        json={"user_id": "pat-137", "code": "PAT137", "display_name": "Del Patient"},
    )
    patient_id = patient.json()["id"]
    pharmacy = await client.post(
        "/api/v1/pharmacies",
        headers=headers,
        json={"code": "PH137", "name": "Delivery Pharmacy"},
    )
    pharmacy_id = pharmacy.json()["id"]
    order = await client.post(
        "/api/v1/prescription-orders",
        headers=headers,
        json={
            "pharmacy_id": pharmacy_id,
            "patient_id": patient_id,
            "doctor_id": doctor_id,
            "code": "RX137",
            "lines": [{"line_no": 1, "medication_code": "M1", "display": "Med", "quantity": 1}],
        },
    )
    oid = order.json()["id"]
    version = order.json()["version"]
    for action in ("accept", "prepare", "mark-ready"):
        resp = await client.post(
            f"/api/v1/prescription-orders/{oid}/{action}",
            headers=headers,
            json={"version": version},
        )
        version = resp.json()["version"]
    registration = await client.post(
        "/api/v1/delivery-integrations",
        headers=headers,
        json={
            "pharmacy_id": pharmacy_id,
            "code": "DELREG1",
            "name": "Pharmacy Delivery",
            "delivery_merchant_ref": "merchant-137",
        },
    )
    assert registration.status_code == 201
    return oid, registration.json()["id"]


@pytest.mark.asyncio
async def test_delivery_intent_idempotency_and_webhook(client):
    MockDeliveryProvider.reset()
    order_id, reg_id = await _seed_ready_prescription(client)
    headers = tenant_headers(TENANT_A)
    payload = {
        "registration_id": reg_id,
        "idempotency_key": "idem-137",
        "code": "DJ1",
        "pickup_address": {"line1": "Pharmacy"},
        "dropoff_address": {"line1": "Home"},
    }

    first = await client.post(
        f"/api/v1/delivery-job-intents/prescription-orders/{order_id}",
        headers=headers,
        json=payload,
    )
    assert first.status_code == 201, first.text
    ref = first.json()["delivery_job_ref"]
    assert ref.startswith("mock-delivery-")

    second = await client.post(
        f"/api/v1/delivery-job-intents/prescription-orders/{order_id}",
        headers=headers,
        json=payload,
    )
    assert second.status_code == 201
    assert second.json()["id"] == first.json()["id"]

    webhook = await client.post(
        "/api/v1/webhooks/delivery-status",
        headers=headers,
        json={"delivery_job_ref": ref, "status": "delivered", "external_status": "DELIVERED"},
    )
    assert webhook.status_code == 200
    assert webhook.json()["status"] == "delivered"

    events = {e.event_type for e in get_event_publisher().published}
    assert HealthcareEventType.DELIVERY_JOB_INTENT_CREATED.value in events
    assert HealthcareEventType.DELIVERY_JOB_STATUS_UPDATED.value in events


@pytest.mark.asyncio
async def test_phase_137_capabilities(client):
    caps = await client.get("/capabilities")
    assert caps.json()["phase"] == "13.7"
    assert caps.json()["features"]["delivery_integration"] is True
