"""Phase 9.1 Membership Catalog API / tenant / business tests."""
from __future__ import annotations

import uuid

import pytest

from app.tests.conftest import TENANT_A, TENANT_B, tenant_headers


async def _create_center(client, tenant_id: uuid.UUID, code: str = "SC-MAIN") -> dict:
    resp = await client.post(
        "/api/v1/sports-centers",
        headers=tenant_headers(tenant_id),
        json={"code": code, "name": "Main Center", "status": "active"},
    )
    assert resp.status_code == 201, resp.text
    return resp.json()


@pytest.mark.asyncio
async def test_membership_catalog_happy_path(client):
    center = await _create_center(client, TENANT_A)
    center_id = center["id"]
    h = tenant_headers(TENANT_A)

    cat = await client.post(
        "/api/v1/sport-categories",
        headers=h,
        json={"sports_center_id": center_id, "code": "AQUA", "name": "Aquatic"},
    )
    assert cat.status_code == 201, cat.text

    age = await client.post(
        "/api/v1/age-groups",
        headers=h,
        json={"sports_center_id": center_id, "code": "ADULT", "name": "Adult", "min_age": 18, "max_age": 64},
    )
    assert age.status_code == 201, age.text

    price = await client.post(
        "/api/v1/pricing-models",
        headers=h,
        json={
            "sports_center_id": center_id,
            "code": "MONTHLY",
            "name": "Monthly Fixed",
            "kind": "fixed",
            "billing_period": "monthly",
            "amount": "1200000",
            "currency_code": "IRR",
        },
    )
    assert price.status_code == 201, price.text
    price_id = price.json()["id"]

    pkg = await client.post(
        "/api/v1/membership-packages",
        headers=h,
        json={
            "sports_center_id": center_id,
            "code": "GOLD-PKG",
            "name": "Gold Package",
            "pricing_model_id": price_id,
            "session_credits": 12,
        },
    )
    assert pkg.status_code == 201, pkg.text

    plan = await client.post(
        "/api/v1/membership-plans",
        headers=h,
        json={
            "sports_center_id": center_id,
            "code": "GOLD-PLAN",
            "name": "Gold Plan",
            "duration_days": 30,
            "pricing_model_id": price_id,
            "package_id": pkg.json()["id"],
            "age_group_id": age.json()["id"],
            "sport_category_id": cat.json()["id"],
        },
    )
    assert plan.status_code == 201, plan.text

    renew = await client.post(
        "/api/v1/renewal-policies",
        headers=h,
        json={"sports_center_id": center_id, "code": "AUTO30", "name": "Auto renew", "auto_renew": True, "grace_period_days": 3},
    )
    assert renew.status_code == 201, renew.text

    freeze = await client.post(
        "/api/v1/freezing-rules",
        headers=h,
        json={"sports_center_id": center_id, "code": "FREEZE30", "name": "Freeze 30", "max_freeze_days": 30},
    )
    assert freeze.status_code == 201, freeze.text

    expire = await client.post(
        "/api/v1/expiration-policies",
        headers=h,
        json={"sports_center_id": center_id, "code": "EXP", "name": "Expire", "warn_before_days": 7},
    )
    assert expire.status_code == 201, expire.text

    mtype = await client.post(
        "/api/v1/membership-types",
        headers=h,
        json={
            "sports_center_id": center_id,
            "code": "GOLD",
            "name": "Gold Membership",
            "duration_days": 30,
            "package_id": pkg.json()["id"],
            "plan_id": plan.json()["id"],
            "pricing_model_id": price_id,
            "age_group_id": age.json()["id"],
            "sport_category_id": cat.json()["id"],
            "renewal_policy_id": renew.json()["id"],
            "freezing_rule_id": freeze.json()["id"],
            "expiration_policy_id": expire.json()["id"],
            "is_transferable": True,
        },
    )
    assert mtype.status_code == 201, mtype.text
    assert mtype.json()["is_transferable"] is True
    assert mtype.json()["plan_id"] == plan.json()["id"]

    rule = await client.post(
        "/api/v1/membership-rules",
        headers=h,
        json={
            "sports_center_id": center_id,
            "code": "ELIG-ADULT",
            "name": "Adult only",
            "kind": "eligibility",
            "membership_type_id": mtype.json()["id"],
            "expression": {"min_age": 18},
        },
    )
    assert rule.status_code == 201, rule.text

    listed = await client.get("/api/v1/membership-plans", headers=h)
    assert listed.status_code == 200
    assert len(listed.json()) >= 1


@pytest.mark.asyncio
async def test_catalog_tenant_isolation(client):
    center_a = await _create_center(client, TENANT_A, code="A1")
    await _create_center(client, TENANT_B, code="B1")
    created = await client.post(
        "/api/v1/pricing-models",
        headers=tenant_headers(TENANT_A),
        json={
            "sports_center_id": center_a["id"],
            "code": "P1",
            "name": "Price A",
            "amount": "1000",
        },
    )
    assert created.status_code == 201
    price_id = created.json()["id"]

    denied = await client.get(
        f"/api/v1/pricing-models/{price_id}",
        headers=tenant_headers(TENANT_B),
    )
    assert denied.status_code == 404


@pytest.mark.asyncio
async def test_age_group_validation(client):
    center = await _create_center(client, TENANT_A, code="AGE1")
    bad = await client.post(
        "/api/v1/age-groups",
        headers=tenant_headers(TENANT_A),
        json={
            "sports_center_id": center["id"],
            "code": "BAD",
            "name": "Bad",
            "min_age": 40,
            "max_age": 10,
        },
    )
    assert bad.status_code == 422


@pytest.mark.asyncio
async def test_capabilities_endpoint(client):
    resp = await client.get("/capabilities")
    assert resp.status_code == 200
    body = resp.json()
    assert body["phase"] == "9.2"
    assert body["features"]["foundation"] is True
    assert body["features"]["membership_catalog"] is True
    assert body["features"]["member_management"] is True
    assert body["independence"]["integration_mode"] == "api_and_events_only"
