"""INDL-59 — Plan-based feature gating for AI record extraction.

`POST /api/v1/ai/extract-record` is the backing route for the "Upload &
auto-fill" AI record-extraction feature referenced in the PRD — it exists
today only as a 501 stub (GPT-4o Vision extraction is not implemented yet),
but is gated behind `require_feature("aiRecordExtraction")` now so the gate
is already correct once the extraction itself ships. Starter (manual upload
only) must 403; Professional and Enterprise both pass the gate and reach the
pre-existing 501 stub — corrected on stakeholder review from an earlier
Enterprise-only iteration of this matrix.
"""
from uuid import uuid4

import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession

from src.apps.auth.models.user import User
from src.apps.tenants.models.account import Account
from src.core.security import build_token_payload, create_access_token, hash_password

URL = "/api/v1/ai/extract-record"


async def _make_account(db: AsyncSession, *, plan: str) -> Account:
    uid = uuid4().hex[:8]
    acc = Account(
        organization_name=f"Plan Gate Cemetery {uid}",
        subdomain=f"plangate-ai-{uid}",
        contact_email=f"admin-{uid}@plangate.test",
        plan=plan,
        status="active",
    )
    db.add(acc)
    await db.flush()
    return acc


async def _make_token(db: AsyncSession, account: Account) -> str:
    user = User(
        tenant_id=account.id,
        email=f"staff-{uuid4().hex[:6]}@plangate.test",
        password_hash=hash_password("Test1234!"),
        first_name="Staff",
        last_name="User",
        role="staff",
        status="active",
    )
    db.add(user)
    await db.flush()
    return create_access_token(build_token_payload(user, account))


def _headers(token: str, account: Account) -> dict:
    return {"Authorization": f"Bearer {token}", "X-Tenant-ID": str(account.id)}


@pytest.mark.asyncio
async def test_starter_is_403_on_ai_extract_record(client: AsyncClient, db_session: AsyncSession):
    acc = await _make_account(db_session, plan="starter")
    token = await _make_token(db_session, acc)

    resp = await client.post(URL, headers=_headers(token, acc))

    assert resp.status_code == 403
    assert "Professional and Enterprise" in resp.json()["message"]


@pytest.mark.parametrize("plan", ["professional", "enterprise"])
@pytest.mark.asyncio
async def test_professional_and_enterprise_pass_gate_and_reach_501_stub(
    client: AsyncClient, db_session: AsyncSession, plan
):
    acc = await _make_account(db_session, plan=plan)
    token = await _make_token(db_session, acc)

    resp = await client.post(URL, headers=_headers(token, acc))

    assert resp.status_code == 501
