"""§22.4a SLICE-3 integration — faceted list endpoint (PUC-3, §6.4).

Through the real API: schema-declared facets, filter params (OR within / AND
across), drill-down counts, malformed toggle, unknown-field 400, and meta_json
persistence. Reuses the fake-Gitea harness from test_metadata_cache.
"""
from __future__ import annotations

import asyncio
import json

import yaml
from fastapi.testclient import TestClient

from app import cache, db, gitea as gitea_mod
from app.config import load_config

from test_propose_vertical import (  # noqa: F401 (fixtures)
    app_with_fake_gitea,
    tmp_env,
)

# The fake-Gitea harness seeds a single project whose id is the literal
# 'default' (see test_s1_collection_grain_vertical), served at
# /api/projects/default/rfcs.
PID = "default"


def _refresh():
    cfg = load_config()
    asyncio.run(cache.refresh_meta_repo(cfg, gitea_mod.Gitea(cfg)))


def _set_default_fields_schema(schema):
    db.conn().execute(
        "UPDATE collections SET config_json = ? WHERE id = 'default'",
        (json.dumps({"fields": schema}),))


def _seed(fake, slug, *, state="active", **front):
    fm = {"slug": slug, "title": slug.title(), "state": state, **front}
    body = yaml.safe_dump(fm, sort_keys=False).strip()
    fake.files[("wiggleverse", "meta", "main", f"rfcs/{slug}.md")] = {
        "content": f"---\n{body}\n---\n\nBody.\n", "sha": slug}


def test_facets_and_counts_returned(app_with_fake_gitea):
    app, fake = app_with_fake_gitea
    with TestClient(app) as client:
        _set_default_fields_schema({
            "priority": {"type": "enum", "values": ["P0", "P1", "P2"]},
            "tags": {"type": "tags"},
        })
        _seed(fake, "a", priority="P0", tags=["checkout"])
        _seed(fake, "b", priority="P0", tags=["cart"])
        _seed(fake, "c", priority="P1", tags=["checkout", "cart"])
        _refresh()

        res = client.get(f"/api/projects/{PID}/rfcs")
        assert res.status_code == 200
        body = res.json()
        assert {i["slug"] for i in body["items"]} == {"a", "b", "c"}
        assert body["facets"]["priority"] == {"P0": 2, "P1": 1}
        assert body["facets"]["tags"] == {"checkout": 2, "cart": 2}
        assert body["facets"]["state"] == {"active": 3}


def test_filter_params_compose(app_with_fake_gitea):
    app, fake = app_with_fake_gitea
    with TestClient(app) as client:
        _set_default_fields_schema({
            "priority": {"type": "enum", "values": ["P0", "P1"]},
            "tags": {"type": "tags"},
        })
        _seed(fake, "a", priority="P0", tags=["checkout"])
        _seed(fake, "b", priority="P0", tags=["cart"])
        _seed(fake, "c", priority="P1", tags=["checkout"])
        _refresh()

        res = client.get(
            f"/api/projects/{PID}/rfcs",
            params={"priority": "P0", "tags": "checkout"})
        assert {i["slug"] for i in res.json()["items"]} == {"a"}


def test_unknown_filter_field_400(app_with_fake_gitea):
    app, fake = app_with_fake_gitea
    with TestClient(app) as client:
        _set_default_fields_schema(
            {"priority": {"type": "enum", "values": ["P0"]}})
        _seed(fake, "a", priority="P0")
        _refresh()

        res = client.get(f"/api/projects/{PID}/rfcs",
                         params={"nonsense": "x"})
        assert res.status_code == 400


def test_malformed_toggle(app_with_fake_gitea):
    app, fake = app_with_fake_gitea
    with TestClient(app) as client:
        _set_default_fields_schema(
            {"priority": {"type": "enum", "values": ["P0", "P1"]}})
        _seed(fake, "good", priority="P0")
        _seed(fake, "bad", priority="P9")  # not in values → malformed (INV-3)
        _refresh()

        res = client.get(f"/api/projects/{PID}/rfcs",
                         params={"malformed": "true"})
        slugs = {i["slug"] for i in res.json()["items"]}
        assert slugs == {"bad"}


def test_no_schema_no_facets(app_with_fake_gitea):
    # INV-5: the default document collection (no fields) returns empty facets.
    app, fake = app_with_fake_gitea
    with TestClient(app) as client:
        _seed(fake, "plain", tags=["whatever"])
        _refresh()
        body = client.get(f"/api/projects/{PID}/rfcs").json()
        assert body["facets"] == {}


def test_meta_json_persisted_at_ingest(app_with_fake_gitea):
    app, fake = app_with_fake_gitea
    with TestClient(app):
        _seed(fake, "withmeta", priority="P0", tags=["x"])
        _refresh()
        row = db.conn().execute(
            "SELECT meta_json FROM cached_rfcs WHERE slug = 'withmeta'"
        ).fetchone()
        meta = json.loads(row["meta_json"])
        assert meta["priority"] == "P0"
        assert meta["tags"] == ["x"]
