"""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"] == "delivery-service"

    caps = await client.get("/capabilities")
    assert caps.status_code == 200
    c = caps.json()
    assert c["phase"] == "10.8"
    assert c["commercial_product"] == "Torbat Driver"
    assert c["features"]["foundation"] is True
    assert c["features"]["drivers"] is True
    assert c["features"]["dispatch_engine"] is True
    assert c["features"]["settlement"] is True
    assert c["independence"]["integration_mode"] == "api_and_events_only"
    assert c["independence"]["no_journal_entries_in_delivery_db"] is True

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


async def test_foundation_flow_and_events(client):
    headers = tenant_headers(TENANT_A)
    org = await client.post(
        "/api/v1/organizations",
        headers=headers,
        json={"code": "ORG1", "name": "Fleet Alpha", "status": "active"},
    )
    assert org.status_code == 201, org.text
    org_id = org.json()["id"]

    hub = await client.post(
        "/api/v1/hubs",
        headers=headers,
        json={
            "organization_id": org_id,
            "code": "HUB1",
            "name": "Central Hub",
        },
    )
    assert hub.status_code == 201, hub.text

    provider = await client.post(
        "/api/v1/external-providers",
        headers=headers,
        json={
            "organization_id": org_id,
            "code": "FLEET_X",
            "name": "External Fleet X",
            "provider_kind": "fleet",
            "adapter_key": "mock_fleet",
        },
    )
    assert provider.status_code == 201, provider.text

    engine = await client.post(
        "/api/v1/routing-engines",
        headers=headers,
        json={
            "organization_id": org_id,
            "code": "ROUTE_A",
            "name": "Future Engine A",
            "adapter_key": "mock_router",
            "status": "ready",
        },
    )
    assert engine.status_code == 201, engine.text

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

    setting = await client.put(
        "/api/v1/settings",
        headers=headers,
        json={
            "organization_id": org_id,
            "key": "default_currency",
            "value": {"code": "IRR"},
        },
    )
    assert setting.status_code == 200, setting.text

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

    published = [e.event_type for e in get_event_publisher().published]
    assert "delivery.organization.created" in published
    assert "delivery.hub.created" in published
    assert "delivery.external_provider.registered" in published
    assert "delivery.routing_engine.registered" 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/organizations",
        headers=headers_a,
        json={"code": "ISO1", "name": "Tenant A Org"},
    )
    assert created.status_code == 201
    org_id = created.json()["id"]

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

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

    listed_a = await client.get("/api/v1/organizations", 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/organizations")
    assert res.status_code in (400, 422)
