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

Fee Schedule (`/settings/fees*`) and Email Templates (`/settings/email-templates*`)
are gated behind `require_feature("feeSchedule")` / `require_feature("emailTemplates")`
respectively. Cemetery Profile, QR Codes, and Plot Types stay ungated on every
plan (AC-10/AC-11).
"""
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

FEES_URL = "/api/v1/settings/fees"
EMAIL_TEMPLATES_URL = "/api/v1/settings/email-templates"
PROFILE_URL = "/api/v1/settings/profile"


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-settings-{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)}


@pytest.mark.parametrize("path", [FEES_URL, EMAIL_TEMPLATES_URL])
@pytest.mark.asyncio
async def test_starter_tenant_is_403_on_gated_settings_tabs(
    client: AsyncClient, db_session: AsyncSession, path
):
    acc = await _make_account(db_session, plan="starter")
    token = await _make_token(db_session, acc, role="administrator")

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

    assert resp.status_code == 403


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

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

    assert resp.status_code == 200


@pytest.mark.asyncio
async def test_starter_tenant_still_reaches_ungated_profile_endpoint(
    client: AsyncClient, db_session: AsyncSession
):
    """Cemetery Profile is not part of any plan gate — always on (AC-10)."""
    acc = await _make_account(db_session, plan="starter")
    token = await _make_token(db_session, acc, role="administrator")

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

    assert resp.status_code == 200
