"""/api/compare enrichment for the compare redesign: per-school
supplementary blocks, top-level national_averages (shared with the
/api/national-averages endpoint) and computed benchmarks — all additive."""

import types

import numpy as np
import pandas as pd
import pytest
from fastapi.testclient import TestClient

LATEST = 202425

CANNED_SUPPLEMENTARY = {
    "ofsted": {"overall_effectiveness": 2, "grade_source": "graded",
               "report_card": {}, "ofsted_page_url": "https://reports.ofsted.gov.uk/provider/21/100140"},
    "census": {"year": 202526, "fsm_pct": 29.8},
    "admissions": {"year": 202627, "second_preference_offers": 4},
    "admissions_history": [{"year": 202627, "second_preference_offers": 4}],
    "sen_detail": None,
    "phonics": None,
    "deprivation": {"idaci_decile": 4},
    "finance": None,
}


def _two_primary_schools_df() -> pd.DataFrame:
    rows = []
    for urn, name, rwm, dis in ((100140, "Plumcroft Primary School", 79.0, 72.0),
                                (138690, "Barclay Primary School", 87.0, 86.0)):
        rows.append(dict(
            urn=urn, school_name=name, local_authority="Greenwich",
            school_type="Community school", address="1 Road", phase="Primary",
            year=LATEST, rwm_expected_pct=rwm, attainment_8_score=np.nan,
            eligible_pupils=60, rwm_expected_disadvantaged_pct=dis,
            eal_pct=20.0, sen_support_pct=14.0, disadvantaged_pct=25.0,
            total_pupils=1000.0,
        ))
    return pd.DataFrame(rows)


class _StubNatRow:
    year = 202425
    rwm_expected_pct = 62.1
    gps_expected_pct = 72.0
    science_expected_pct = 81.0


class _StubSession:
    def query(self, *a, **k):
        return self

    def order_by(self, *a, **k):
        return self

    def all(self):
        return [_StubNatRow()]

    def close(self):
        pass


@pytest.fixture()
def client(monkeypatch):
    from backend import app as app_module
    from backend import database as database_module

    monkeypatch.setattr(app_module, "load_school_data", _two_primary_schools_df)
    monkeypatch.setattr(
        app_module,
        "get_supplementary_data_batch",
        lambda db, urns: {int(u): dict(CANNED_SUPPLEMENTARY) for u in urns},
    )
    monkeypatch.setattr(database_module, "SessionLocal", _StubSession)
    return TestClient(app_module.app, raise_server_exceptions=False)


def test_existing_shape_is_preserved(client):
    body = client.get("/api/compare?urns=100140,138690").json()
    school = body["comparison"]["100140"]
    assert school["school_info"]["rwm_expected_pct"] == 79.0
    assert school["yearly_data"][0]["year"] == LATEST


def test_each_school_gains_supplementary_blocks(client):
    body = client.get("/api/compare?urns=100140,138690").json()
    for urn in ("100140", "138690"):
        school = body["comparison"][urn]
        assert school["ofsted"]["grade_source"] == "graded"
        assert school["census"]["fsm_pct"] == 29.8
        assert school["admissions"]["second_preference_offers"] == 4
        assert school["admissions_history"][0]["year"] == 202627
        assert school["deprivation"]["idaci_decile"] == 4


def test_top_level_national_averages_and_benchmarks(client):
    body = client.get("/api/compare?urns=100140,138690").json()
    assert body["national_averages"]["year"] == LATEST
    assert body["benchmarks"]["source"] == "state-school average (computed from our dataset)"
    # weighted over equal cohorts of 72 and 86 = 79.0
    assert body["benchmarks"]["primary"]["disadvantaged_rwm_expected_pct"] == 79.0


def test_supplementary_failure_degrades_not_500(client, monkeypatch):
    from backend import app as app_module

    def _boom(db, urns):
        raise RuntimeError("marts unavailable")

    monkeypatch.setattr(app_module, "get_supplementary_data_batch", _boom)
    resp = client.get("/api/compare?urns=100140")
    assert resp.status_code == 200
    school = resp.json()["comparison"]["100140"]
    assert school["ofsted"] is None
    assert school["admissions_history"] == []


def test_national_averages_endpoint_exposes_gps_science(client):
    body = client.get("/api/national-averages").json()
    latest_primary_by_year = [e["primary"] for e in body["by_year"] if e["primary"]]
    assert latest_primary_by_year, "expected official by_year rows from the stub"
    assert latest_primary_by_year[-1]["gps_expected_pct"] == 72.0
    assert latest_primary_by_year[-1]["science_expected_pct"] == 81.0
