"""Sites & pages API tests — Phase 11.1."""
from __future__ import annotations

import pytest

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


async def _workspace(client, code="ws1"):
    resp = await client.post(
        "/api/v1/workspaces",
        json={"code": code, "name": "Workspace", "status": "active"},
        headers=tenant_headers(TENANT_A),
    )
    assert resp.status_code == 201, resp.text
    return resp.json()


@pytest.mark.asyncio
async def test_health_phase_111(client):
    resp = await client.get("/health")
    assert resp.status_code == 200
    # Health version tracks current service version (forward-compatible).
    assert resp.json()["version"].startswith("0.11.")

    caps = await client.get("/capabilities")
    body = caps.json()
    assert body["features"]["sites"] is True
    assert body["features"]["pages"] is True
    assert body["features"]["page_builder"] is False
    assert "landing" in body["page_types"]
    assert "digital_menu" in body["page_types"]


@pytest.mark.asyncio
async def test_sites_pages_domains_publish_flow(client):
    ws = await _workspace(client)
    workspace_id = ws["id"]

    site = await client.post(
        "/api/v1/sites",
        json={
            "workspace_id": workspace_id,
            "code": "main",
            "name": "Main Site",
            "default_locale": "fa",
            "default_direction": "rtl",
        },
        headers=tenant_headers(TENANT_A),
    )
    assert site.status_code == 201, site.text
    site_id = site.json()["id"]
    assert site.json()["publish_status"] == "draft"

    page = await client.post(
        "/api/v1/pages",
        json={
            "workspace_id": workspace_id,
            "site_id": site_id,
            "code": "home",
            "slug": "home",
            "title": "Home",
            "page_type": "landing",
            "is_home": True,
        },
        headers=tenant_headers(TENANT_A),
    )
    assert page.status_code == 201, page.text
    page_id = page.json()["id"]
    assert page.json()["page_type"] == "landing"

    menu = await client.post(
        "/api/v1/pages",
        json={
            "workspace_id": workspace_id,
            "site_id": site_id,
            "code": "menu",
            "slug": "menu",
            "title": "Digital Menu",
            "page_type": "digital_menu",
            "external_refs": {"hospitality_menu_ref": "menu-1"},
        },
        headers=tenant_headers(TENANT_A),
    )
    assert menu.status_code == 201, menu.text

    domain = await client.post(
        "/api/v1/site-domains",
        json={
            "workspace_id": workspace_id,
            "site_id": site_id,
            "host": "pages.example.local",
            "domain_kind": "subdomain",
            "is_primary": True,
        },
        headers=tenant_headers(TENANT_A),
    )
    assert domain.status_code == 201, domain.text
    assert domain.json()["is_primary"] is True

    published_page = await client.post(
        f"/api/v1/pages/{page_id}/publish",
        headers=tenant_headers(TENANT_A),
    )
    assert published_page.status_code == 200
    assert published_page.json()["publish_status"] == "published"

    published_site = await client.post(
        f"/api/v1/sites/{site_id}/publish",
        headers=tenant_headers(TENANT_A),
    )
    assert published_site.status_code == 200
    assert published_site.json()["publish_status"] == "published"
    assert published_site.json()["primary_domain"] == "pages.example.local"

    archived = await client.post(
        f"/api/v1/sites/{site_id}/archive",
        headers=tenant_headers(TENANT_A),
    )
    assert archived.status_code == 200
    assert archived.json()["publish_status"] == "archived"

    events = {e.event_type for e in get_event_publisher().published}
    assert ExperienceEventType.SITE_CREATED.value in events
    assert ExperienceEventType.PAGE_CREATED.value in events
    assert ExperienceEventType.PAGE_PUBLISHED.value in events
    assert ExperienceEventType.SITE_PUBLISHED.value in events
    assert ExperienceEventType.SITE_DOMAIN_BOUND.value in events
    assert ExperienceEventType.SITE_ARCHIVED.value in events


@pytest.mark.asyncio
async def test_site_tenant_isolation(client):
    ws = await _workspace(client, code="iso")
    site = await client.post(
        "/api/v1/sites",
        json={"workspace_id": ws["id"], "code": "s1", "name": "S1"},
        headers=tenant_headers(TENANT_A),
    )
    assert site.status_code == 201
    site_id = site.json()["id"]

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


@pytest.mark.asyncio
async def test_archive_blocks_publish(client):
    ws = await _workspace(client, code="arch")
    site = await client.post(
        "/api/v1/sites",
        json={"workspace_id": ws["id"], "code": "s2", "name": "S2"},
        headers=tenant_headers(TENANT_A),
    )
    site_id = site.json()["id"]
    await client.post(
        f"/api/v1/sites/{site_id}/archive",
        headers=tenant_headers(TENANT_A),
    )
    again = await client.post(
        f"/api/v1/sites/{site_id}/publish",
        headers=tenant_headers(TENANT_A),
    )
    assert again.status_code == 409
