"""INDL-59 — Plan-based feature gating for Crew Members.

The entire `/api/v1/crew-members` router is gated behind
`require_feature("crewMembers")`. Note this router scopes every query off
`current_user.tenant_id` (not `request.state.tenant_id` / X-Tenant-ID header)
— these tests intentionally omit the X-Tenant-ID header to prove the
`require_feature` dependency's fallback to the JWT-derived tenant_id works.
"""
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

BASE = "/api/v1/crew-members"


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-crew-{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"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))


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

    resp = await client.get(BASE, headers={"Authorization": f"Bearer {token}"})

    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_paid_plans_pass_crew_members_plan_gate(
    client: AsyncClient, db_session: AsyncSession, plan
):
    acc = await _make_account(db_session, plan=plan)
    token = await _make_token(db_session, acc)

    resp = await client.get(BASE, headers={"Authorization": f"Bearer {token}"})

    assert resp.status_code == 200
