"""Phase 12.5 POS Pro API / tenant / validation tests."""
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


async def _seed_venue_ticket(client, tenant_id, *, venue_code: str = "v1", ticket_code: str = "t1"):
    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
    venue_id = venue.json()["id"]

    register = await client.post(
        "/api/v1/pos-registers",
        json={"venue_id": venue_id, "code": f"{ticket_code}-reg", "name": "Register"},
        headers=h,
    )
    assert register.status_code == 201, register.text
    register_id = register.json()["id"]

    ticket = await client.post(
        "/api/v1/pos-tickets",
        json={"venue_id": venue_id, "register_id": register_id, "code": ticket_code},
        headers=h,
    )
    assert ticket.status_code == 201, ticket.text
    return {"headers": h, "venue_id": venue_id, "register_id": register_id, "ticket_id": ticket.json()["id"]}


@pytest.mark.asyncio
async def test_pos_pro_payment_discount_tax_happy_path(client):
    seed = await _seed_venue_ticket(client, TENANT_A, venue_code="pro-v1", ticket_code="pro-t1")
    h = seed["headers"]

    payment = await client.post(
        "/api/v1/pos-payments",
        json={
            "venue_id": seed["venue_id"],
            "ticket_id": seed["ticket_id"],
            "method": "cash",
            "amount": 100000,
        },
        headers=h,
    )
    assert payment.status_code == 201, payment.text
    assert payment.json()["status"] == "active"

    discount = await client.post(
        "/api/v1/pos-discounts",
        json={
            "venue_id": seed["venue_id"],
            "ticket_id": seed["ticket_id"],
            "code": "disc-1",
            "kind": "percent",
            "value": 10,
        },
        headers=h,
    )
    assert discount.status_code == 201, discount.text

    tax = await client.post(
        "/api/v1/pos-tax-lines",
        json={
            "venue_id": seed["venue_id"],
            "ticket_id": seed["ticket_id"],
            "code": "vat",
            "name": "VAT",
            "rate_bps": 900,
            "amount": 9000,
        },
        headers=h,
    )
    assert tax.status_code == 201, tax.text

    floor_plan = await client.post(
        "/api/v1/pos-floor-plans",
        json={"venue_id": seed["venue_id"], "code": "fp-1", "name": "Main Floor"},
        headers=h,
    )
    assert floor_plan.status_code == 201, floor_plan.text
    floor_plan_id = floor_plan.json()["id"]

    station = await client.post(
        "/api/v1/pos-stations",
        json={
            "venue_id": seed["venue_id"],
            "floor_plan_id": floor_plan_id,
            "code": "st-1",
            "name": "Bar",
        },
        headers=h,
    )
    assert station.status_code == 201, station.text

    published = {e.event_type for e in get_event_publisher().published}
    assert HospitalityEventType.POS_PAYMENT_RECORDED.value in published
    assert HospitalityEventType.POS_DISCOUNT_APPLIED.value in published
    assert HospitalityEventType.POS_TAX_LINE_ADDED.value in published
    assert HospitalityEventType.POS_FLOOR_PLAN_CREATED.value in published
    assert HospitalityEventType.POS_STATION_CREATED.value in published


@pytest.mark.asyncio
async def test_pos_pro_tenant_isolation(client):
    seed = await _seed_venue_ticket(client, TENANT_A, venue_code="pro-iso-v1", ticket_code="pro-iso-t1")
    payment = await client.post(
        "/api/v1/pos-payments",
        json={
            "venue_id": seed["venue_id"],
            "ticket_id": seed["ticket_id"],
            "method": "card",
            "amount": 50000,
        },
        headers=seed["headers"],
    )
    assert payment.status_code == 201, payment.text
    payment_id = payment.json()["id"]

    denied = await client.get(
        f"/api/v1/pos-payments/{payment_id}", headers=tenant_headers(TENANT_B)
    )
    assert denied.status_code == 404


@pytest.mark.asyncio
async def test_pos_discount_percent_over_100_rejected(client):
    seed = await _seed_venue_ticket(client, TENANT_A, venue_code="pro-disc-v1", ticket_code="pro-disc-t1")
    bad = await client.post(
        "/api/v1/pos-discounts",
        json={
            "venue_id": seed["venue_id"],
            "ticket_id": seed["ticket_id"],
            "code": "bad-disc",
            "kind": "percent",
            "value": 150,
        },
        headers=seed["headers"],
    )
    assert bad.status_code == 422


@pytest.mark.asyncio
async def test_pos_payment_zero_amount_rejected(client):
    seed = await _seed_venue_ticket(client, TENANT_A, venue_code="pro-pay-v1", ticket_code="pro-pay-t1")
    bad = await client.post(
        "/api/v1/pos-payments",
        json={
            "venue_id": seed["venue_id"],
            "ticket_id": seed["ticket_id"],
            "method": "cash",
            "amount": 0,
        },
        headers=seed["headers"],
    )
    assert bad.status_code == 422


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