"""INDL-59 — Plan-based feature gating for the Sales module.

The entire `/api/v1/sales/*` router is gated behind
`require_feature("sales")` (src/apps/sales/router.py). Starter tenants must
get a 403 server-side, independent of any UI state; Professional and
Enterprise must pass through unaffected.
"""
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

OPPORTUNITIES_URL = "/api/v1/sales/opportunities"


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-sales-{uid}",
        contact_email=f"admin-{uid}@plangate.test",
        plan=plan,
        status="active",
    )
    db.add(acc)
    await db.flush()
    return acc


async def _make_admin_token(db: AsyncSession, account: Account) -> str:
    user = User(
        tenant_id=account.id,
        email=f"admin-{uuid4().hex[:6]}@plangate.test",
        password_hash=hash_password("Test1234!"),
        first_name="Admin",
        last_name="User",
        role="administrator",
        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_tenant_is_403_on_sales_router(client: AsyncClient, db_session: AsyncSession):
    acc = await _make_account(db_session, plan="starter")
    token = await _make_admin_token(db_session, acc)

    resp = await client.get(OPPORTUNITIES_URL, headers=_headers(token, acc))

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


@pytest.mark.asyncio
async def test_professional_tenant_passes_sales_plan_gate(client: AsyncClient, db_session: AsyncSession):
    acc = await _make_account(db_session, plan="professional")
    token = await _make_admin_token(db_session, acc)

    resp = await client.get(OPPORTUNITIES_URL, headers=_headers(token, acc))

    assert resp.status_code == 200


@pytest.mark.asyncio
async def test_enterprise_tenant_passes_sales_plan_gate(client: AsyncClient, db_session: AsyncSession):
    acc = await _make_account(db_session, plan="enterprise")
    token = await _make_admin_token(db_session, acc)

    resp = await client.get(OPPORTUNITIES_URL, headers=_headers(token, acc))

    assert resp.status_code == 200
