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

Both the legacy `/api/v1/services/*` router and the `/api/v1/scheduling/*`
(Phase 2) router are gated behind `require_feature("scheduling")`. Starter
tenants must get a 403 server-side; Professional and Enterprise pass through.
"""
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


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-sched-{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, *, role: str = "administrator") -> str:
    user = User(
        tenant_id=account.id,
        email=f"user-{uuid4().hex[:6]}@plangate.test",
        password_hash=hash_password("Test1234!"),
        first_name="Test",
        last_name="User",
        role=role,
        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)}


# Legacy /services router has no bare GET route (only POST ""), so use its
# one parameter-free-enough real GET route with the one required query param
# supplied; the Phase 2 /scheduling router has a genuine bare GET "" list route.
_ROUTES = [
    "/api/v1/services/week?week_start=2026-01-05",
    "/api/v1/scheduling",
]


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

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

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


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

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

    assert resp.status_code == 200
