"""Phase 0 smoke tests — the scaffold is wired correctly.

Real behavioural tests arrive with the features they cover; these exist so CI has
something meaningful to fail on from day one.
"""

import os

import pytest

from app.config import Settings
from app.models import Base


def test_dev_defaults_to_dry_run() -> None:
    """Task 8.8: a local run must never be able to email real guests by default."""
    settings = Settings()
    assert settings.dry_run is True
    assert settings.environment == "dev"


def test_every_table_is_registered() -> None:
    """Alembic autogenerate only sees models imported by app.models."""
    expected = {
        "wedding",
        "event",
        "guest",
        "invitation",
        "rsvp",
        "rsvp_history",
        "message_template",
        "reminder_schedule",
        "message_job",
        "admin_user",
        "audit_log",
        "rate_limit",
    }
    assert expected <= set(Base.metadata.tables)


def test_message_job_has_idempotency_constraint() -> None:
    """Design D5: this single constraint is what stops a duplicated planner run from
    messaging every guest twice."""
    table = Base.metadata.tables["message_job"]
    constraint_names = {c.name for c in table.constraints}
    assert "uq_message_job_idempotency" in constraint_names


def test_message_job_claim_index_exists() -> None:
    """Design D3: the sender claims rows by (status, scheduled_for)."""
    table = Base.metadata.tables["message_job"]
    assert "ix_message_job_claim" in {i.name for i in table.indexes}


def test_admin_user_stores_a_hash_and_never_a_second_factor() -> None:
    """`add-admin-access-control` reverses half of design D7.

    D7 said Google owns credential security and this table holds no password column. It now
    holds one, because a super admin can create username-and-password accounts — and the
    assertion that used to forbid it is kept here, inverted, so the reversal is visible
    rather than silently absent.

    TOTP stays out: that change restored passwords, not the whole of PRD FR-4.1.
    """
    columns = set(Base.metadata.tables["admin_user"].columns.keys())
    assert "password_hash" in columns
    assert "totp_secret" not in columns


@pytest.mark.skipif(
    not os.getenv("DATABASE_URL", "").startswith("postgresql"),
    reason="requires a Postgres connection",
)
async def test_health_endpoint_reports_database() -> None:
    from httpx import ASGITransport, AsyncClient

    from app.main import app

    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        response = await client.get("/api/health")

    assert response.status_code == 200
    body = response.json()
    assert body["checks"]["database"]["status"] == "ok"
    # Task 5.6: a worker that has stopped planning reminders is otherwise invisible, so
    # the endpoint must always report it — present and dead, never simply absent.
    assert set(body["checks"]["worker"]["tasks"]) == {"planner", "sender"}
    assert body["checks"]["provider"]["mode"] in {"dry_run", "live"}
