"""Phase 12.6 Kitchen API / tenant / validation tests."""
from __future__ import annotations

import uuid

import pytest

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


async def _seed_venue(client, tenant_id, *, venue_code: str = "v1"):
    h = tenant_headers(tenant_id)
    venue = await client.post(
        "/api/v1/venues",
        json={"code": venue_code, "name": "Cafe", "status": "active", "venue_format": "cafe"},
        headers=h,
    )
    assert venue.status_code == 201, venue.text
    return {"headers": h, "venue_id": venue.json()["id"]}


@pytest.mark.asyncio
async def test_kitchen_station_ticket_item_lifecycle(client):
    seed = await _seed_venue(client, TENANT_A, venue_code="kit-v1")
    h = seed["headers"]

    station = await client.post(
        "/api/v1/kitchen-stations",
        json={"venue_id": seed["venue_id"], "code": "grill", "name": "Grill Station"},
        headers=h,
    )
    assert station.status_code == 201, station.text
    station_id = station.json()["id"]

    source_id = str(uuid.uuid4())
    ticket = await client.post(
        "/api/v1/kitchen-tickets",
        json={
            "venue_id": seed["venue_id"],
            "station_id": station_id,
            "source_type": "pos_ticket",
            "source_id": source_id,
            "code": "kt-1",
        },
        headers=h,
    )
    assert ticket.status_code == 201, ticket.text
    ticket_id = ticket.json()["id"]
    assert ticket.json()["status"] == "queued"

    item = await client.post(
        "/api/v1/kitchen-ticket-items",
        json={
            "venue_id": seed["venue_id"],
            "kitchen_ticket_id": ticket_id,
            "menu_item_id": str(uuid.uuid4()),
            "quantity": 2,
        },
        headers=h,
    )
    assert item.status_code == 201, item.text
    item_id = item.json()["id"]
    assert item.json()["status"] == "queued"

    item_status = await client.post(
        f"/api/v1/kitchen-ticket-items/{item_id}/status",
        json={"status": "preparing"},
        headers=h,
    )
    assert item_status.status_code == 200, item_status.text
    assert item_status.json()["status"] == "preparing"

    ticket_status = await client.post(
        f"/api/v1/kitchen-tickets/{ticket_id}/status",
        json={"status": "ready"},
        headers=h,
    )
    assert ticket_status.status_code == 200, ticket_status.text
    assert ticket_status.json()["status"] == "ready"

    bumped = await client.post(
        f"/api/v1/kitchen-tickets/{ticket_id}/status",
        json={"status": "bumped"},
        headers=h,
    )
    assert bumped.status_code == 200, bumped.text

    blocked = await client.post(
        f"/api/v1/kitchen-tickets/{ticket_id}/status",
        json={"status": "queued"},
        headers=h,
    )
    assert blocked.status_code == 409

    published = {e.event_type for e in get_event_publisher().published}
    assert HospitalityEventType.KITCHEN_STATION_CREATED.value in published
    assert HospitalityEventType.KITCHEN_TICKET_CREATED.value in published
    assert HospitalityEventType.KITCHEN_TICKET_STATUS_CHANGED.value in published
    assert HospitalityEventType.KITCHEN_TICKET_ITEM_ADDED.value in published


@pytest.mark.asyncio
async def test_kitchen_tenant_isolation(client):
    seed = await _seed_venue(client, TENANT_A, venue_code="kit-iso-v1")
    station = await client.post(
        "/api/v1/kitchen-stations",
        json={"venue_id": seed["venue_id"], "code": "iso-station", "name": "Iso Station"},
        headers=seed["headers"],
    )
    assert station.status_code == 201, station.text
    station_id = station.json()["id"]

    denied = await client.get(
        f"/api/v1/kitchen-stations/{station_id}", headers=tenant_headers(TENANT_B)
    )
    assert denied.status_code == 404


@pytest.mark.asyncio
async def test_kitchen_ticket_item_quantity_validation(client):
    seed = await _seed_venue(client, TENANT_A, venue_code="kit-qty-v1")
    h = seed["headers"]

    ticket = await client.post(
        "/api/v1/kitchen-tickets",
        json={
            "venue_id": seed["venue_id"],
            "source_type": "pos_ticket",
            "source_id": str(uuid.uuid4()),
            "code": "kit-qty-t1",
        },
        headers=h,
    )
    assert ticket.status_code == 201, ticket.text
    ticket_id = ticket.json()["id"]

    bad = await client.post(
        "/api/v1/kitchen-ticket-items",
        json={
            "venue_id": seed["venue_id"],
            "kitchen_ticket_id": ticket_id,
            "menu_item_id": str(uuid.uuid4()),
            "quantity": 0,
        },
        headers=h,
    )
    assert bad.status_code == 422


@pytest.mark.asyncio
async def test_capabilities_phase_12_6(client):
    resp = await client.get("/capabilities")
    assert resp.status_code == 200
    body = resp.json()
    assert body["features"]["kitchen"] is True
    assert body["features"]["kitchen_engine"] is True
    assert body["features"]["pos_engine"] is False
