"""Hospitality API foundation flow — Phase 12.0."""
from __future__ import annotations

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


@pytest.mark.asyncio
async def test_health(client):
    resp = await client.get("/health")
    assert resp.status_code == 200
    body = resp.json()
    assert body["service"] == "hospitality-service"
    assert body["status"] == "ok"
    assert body["version"] == "0.12.8.0"


@pytest.mark.asyncio
async def test_capabilities(client):
    resp = await client.get("/capabilities")
    assert resp.status_code == 200
    body = resp.json()
    assert body["phase"] == "12.8"
    assert body["product"] == "Torbat Food"
    assert body["features"]["foundation"] is True
    assert body["features"]["bundle_based_licensing"] is True
    assert body["features"]["digital_menu_catalog"] is True
    assert body["features"]["qr_menu"] is True
    assert body["features"]["qr_ordering"] is True
    assert body["features"]["table_service"] is True
    assert body["features"]["reservation"] is True
    assert body["features"]["pos_lite"] is True
    assert body["features"]["pos_pro"] is True
    assert body["features"]["kitchen"] is True
    assert body["features"]["delivery_integration"] is True
    assert body["features"]["accounting_integration"] is True
    assert body["features"]["analytics"] is True
    assert body["features"]["pos_engine"] is False
    assert "digital_menu" in body["bundles"]
    assert "cafe" in body["venue_formats"]
    assert body["independence"]["integration_mode"] == "api_and_events_only"


@pytest.mark.asyncio
async def test_foundation_flow_and_events(client):
    venue = await client.post(
        "/api/v1/venues",
        json={
            "code": "main",
            "name": "Main Cafe",
            "status": "active",
            "venue_format": "cafe",
        },
        headers=tenant_headers(TENANT_A),
    )
    assert venue.status_code == 201, venue.text
    venue_id = venue.json()["id"]
    assert venue.json()["code"] == "MAIN"
    assert venue.json()["venue_format"] == "cafe"

    branch = await client.post(
        "/api/v1/branches",
        json={"venue_id": venue_id, "code": "b1", "name": "Branch 1"},
        headers=tenant_headers(TENANT_A),
    )
    assert branch.status_code == 201, branch.text

    area = await client.post(
        "/api/v1/dining-areas",
        json={"venue_id": venue_id, "code": "hall", "name": "Main Hall"},
        headers=tenant_headers(TENANT_A),
    )
    assert area.status_code == 201, area.text
    area_id = area.json()["id"]

    table = await client.post(
        "/api/v1/tables",
        json={
            "venue_id": venue_id,
            "dining_area_id": area_id,
            "code": "t1",
            "name": "Table 1",
            "capacity": 4,
        },
        headers=tenant_headers(TENANT_A),
    )
    assert table.status_code == 201, table.text

    menu = await client.post(
        "/api/v1/menus",
        json={"venue_id": venue_id, "code": "day", "name": "Day Menu"},
        headers=tenant_headers(TENANT_A),
    )
    assert menu.status_code == 201, menu.text
    menu_id = menu.json()["id"]

    category = await client.post(
        "/api/v1/menu-categories",
        json={
            "venue_id": venue_id,
            "menu_id": menu_id,
            "code": "drinks",
            "name": "Drinks",
        },
        headers=tenant_headers(TENANT_A),
    )
    assert category.status_code == 201, category.text
    category_id = category.json()["id"]

    item = await client.post(
        "/api/v1/menu-items",
        json={
            "venue_id": venue_id,
            "menu_id": menu_id,
            "category_id": category_id,
            "code": "latte",
            "name": "Latte",
            "base_price": 150000,
        },
        headers=tenant_headers(TENANT_A),
    )
    assert item.status_code == 201, item.text

    bundle = await client.post(
        "/api/v1/bundle-definitions",
        json={
            "code": "dm",
            "bundle_key": "digital_menu",
            "name": "Digital Menu",
            "feature_keys": ["hospitality.digital_menu"],
            "permission_prefixes": ["hospitality.digital_menu."],
            "api_prefixes": ["/api/v1/menus"],
        },
        headers=tenant_headers(TENANT_A),
    )
    assert bundle.status_code == 201, bundle.text
    bundle_id = bundle.json()["id"]

    activated = await client.post(
        "/api/v1/tenant-bundles/activate",
        json={"bundle_definition_id": bundle_id, "venue_id": venue_id},
        headers=tenant_headers(TENANT_A),
    )
    assert activated.status_code == 201, activated.text
    assert activated.json()["bundle_key"] == "digital_menu"
    assert activated.json()["status"] == "active"

    toggle = await client.post(
        "/api/v1/feature-toggles/upsert",
        json={
            "feature_key": "hospitality.digital_menu",
            "enabled": True,
            "venue_id": venue_id,
            "bundle_key": "digital_menu",
        },
        headers=tenant_headers(TENANT_A),
    )
    assert toggle.status_code == 200, toggle.text
    assert toggle.json()["enabled"] is True

    role = await client.post(
        "/api/v1/roles",
        json={"code": "manager", "name": "Manager", "venue_id": venue_id},
        headers=tenant_headers(TENANT_A),
    )
    assert role.status_code == 201, role.text

    cfg = await client.post(
        "/api/v1/configurations",
        json={
            "code": "hours",
            "name": "Working Hours",
            "venue_id": venue_id,
            "config": {"timezone": "Asia/Tehran"},
        },
        headers=tenant_headers(TENANT_A),
    )
    assert cfg.status_code == 201, cfg.text

    published = {e.event_type for e in get_event_publisher().published}
    assert HospitalityEventType.VENUE_CREATED.value in published
    assert HospitalityEventType.MENU_CREATED.value in published
    assert HospitalityEventType.TENANT_BUNDLE_ACTIVATED.value in published
    assert HospitalityEventType.FEATURE_TOGGLE_UPSERTED.value in published


@pytest.mark.asyncio
async def test_tenant_isolation(client):
    venue = await client.post(
        "/api/v1/venues",
        json={"code": "a1", "name": "Tenant A Venue", "status": "active"},
        headers=tenant_headers(TENANT_A),
    )
    assert venue.status_code == 201
    venue_id = venue.json()["id"]

    other = await client.get(
        f"/api/v1/venues/{venue_id}",
        headers=tenant_headers(TENANT_B),
    )
    assert other.status_code == 404

    missing = await client.get("/api/v1/venues")
    assert missing.status_code in (400, 422)
