"""Registry API test harness — a small SQLite slice of the party graph
(no sidecar Postgres needed; the registry touches only portable SQL) plus
TestClients wired to that engine with the service token monkeypatched on
``settings``.

Fixtures:
  * ``reg_engine`` / ``reg_ids`` — the seeded in-memory DB + the ids of the
    seeded rows (Bowden Works tenant, Brentwood w/ reference facts,
    Brentwood Bay Dental, Google, Heather the person, an INACTIVE Old Co,
    and a Site Rebuild project).
  * ``reg_client`` — a client with the service token CONFIGURED. Send
    ``AUTH`` as the Authorization header.
  * ``reg_client_no_token`` — token UNSET, so the registry fails closed
    (503). Same DB.
"""

from __future__ import annotations

from types import SimpleNamespace

import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool

from app.config import settings as app_settings
from app.main import create_app
from app.models import Base, Organization, Project, Tenant
from app.services.entities.parties import create_org_party, create_person_party

TOKEN = "test-registry-token-3f9a2c17"
AUTH = {"Authorization": f"Bearer {TOKEN}"}


def _seed(engine) -> SimpleNamespace:
    with Session(engine) as s:
        bw = create_org_party(s, name="Bowden Works", slug="bowden-works")
        tenant = Tenant(party_id=bw.id, settings={"default_currency": "CAD"})
        s.add(tenant)
        s.flush()

        brentwood = create_org_party(s, name="Brentwood", slug="brentwood")
        org = s.get(Organization, brentwood.id)
        org.drive_folder_url = "https://drive.example/brentwood"
        org.mosiah_folder = "/mnt/noah/central/Brentwood"

        bbd = create_org_party(
            s, name="Brentwood Bay Dental", slug="brentwood-bay-dental"
        )
        google = create_org_party(s, name="Google", slug="google")
        oldco = create_org_party(
            s, name="Old Co", slug="old-co", is_active=False
        )
        heather = create_person_party(
            s, name="Heather Bowden", slug="heather-bowden", email="heather@example.com"
        )

        project = Project(
            tenant_id=tenant.id,
            operator_party_id=bw.id,
            client_party_id=brentwood.id,
            name="Site Rebuild",
            status="active",
        )
        s.add(project)
        s.flush()

        ids = SimpleNamespace(
            bw=bw.id,
            tenant=tenant.id,
            brentwood=brentwood.id,
            bbd=bbd.id,
            google=google.id,
            oldco=oldco.id,
            heather=heather.id,
            project=project.id,
        )
        s.commit()
    return ids


@pytest.fixture()
def reg_engine():
    engine = create_engine(
        "sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool
    )
    Base.metadata.create_all(engine)
    ids = _seed(engine)
    yield engine, ids
    engine.dispose()


@pytest.fixture()
def reg_ids(reg_engine):
    return reg_engine[1]


def _wire(reg_engine, monkeypatch, token: str) -> TestClient:
    engine, _ = reg_engine
    from app import db as app_db

    monkeypatch.setattr(app_db, "get_engine", lambda: engine)
    monkeypatch.setattr(app_settings, "registry_service_token", token)
    client = TestClient(create_app(), base_url="https://testserver")
    client.__enter__()
    return client


@pytest.fixture()
def reg_client(reg_engine, monkeypatch):
    client = _wire(reg_engine, monkeypatch, TOKEN)
    yield client
    client.__exit__(None, None, None)


@pytest.fixture()
def reg_client_no_token(reg_engine, monkeypatch):
    client = _wire(reg_engine, monkeypatch, "")
    yield client
    client.__exit__(None, None, None)
