from __future__ import annotations

import pytest
import respx
from httpx import Response

from acs_cli.census_api.client import ACS_BASE_URL, MICHIGAN_FIPS


# ── Helpers ──────────────────────────────────────────────────────────────────

MOCK_COUNTIES = [
    ("Washtenaw County, Michigan", "161"),
    ("Wayne County, Michigan", "163"),
    ("Oakland County, Michigan", "125"),
]


def census_url(year: int = 2024) -> str:
    return ACS_BASE_URL.format(year=year)


def build_census_response(
    variable_codes: list[str],
    counties: list[tuple[str, str]] | None = None,
    values_fn=None,
) -> list[list[str]]:
    """Build a Census API JSON response (list-of-lists format).

    values_fn(county_index, var_code) -> str  controls per-cell values.
    Defaults to sequential integers starting at 1000.
    """
    if counties is None:
        counties = MOCK_COUNTIES

    if values_fn is None:
        counter = {"n": 1000}

        def values_fn(_ci, _code):
            counter["n"] += 1
            return str(counter["n"])

    header = ["NAME"] + variable_codes + ["state", "county"]
    rows = []
    for ci, (name, fips) in enumerate(counties):
        row = [name] + [values_fn(ci, c) for c in variable_codes] + [MICHIGAN_FIPS, fips]
        rows.append(row)
    return [header] + rows


# ── Fixtures ─────────────────────────────────────────────────────────────────

@pytest.fixture()
def api_key(monkeypatch):
    """Ensure CENSUS_API_KEY is set for every test that needs it."""
    monkeypatch.setenv("CENSUS_API_KEY", "test-key-123")
    return "test-key-123"


@pytest.fixture()
def no_api_key(monkeypatch, tmp_path):
    """Ensure no API key is available (env or config file)."""
    monkeypatch.setenv("CENSUS_API_KEY", "")
    # Also prevent the config file fallback from finding a key
    monkeypatch.setattr(
        "acs_cli.census_api.client.CONFIG_FILE",
        tmp_path / "nonexistent_config",
    )


@pytest.fixture()
def mock_census(api_key):
    """Activate respx and return a helper to register mock Census responses.

    Usage:
        def test_something(mock_census):
            mock_census(year=2024, codes=["B01003_001E"], response=[[...], [...]])
    """
    with respx.mock(assert_all_called=False) as router:

        def _register(
            year: int = 2024,
            codes: list[str] | None = None,
            response: list[list[str]] | None = None,
            counties: list[tuple[str, str]] | None = None,
        ):
            if codes is None:
                codes = ["B01003_001E"]
            if response is None:
                response = build_census_response(codes, counties=counties)
            route = router.get(census_url(year)).mock(
                return_value=Response(200, json=response)
            )
            return route

        yield _register
