"""Registered scorer (protocol-memory.json): persona against memory (record plus earlier answers to
related questions), pooled over the test halves of the 2006, 2008 and 2010 GSS panels. Multi-category
Brier score per person and question (probabilities renormalised), paired by person; bootstrap 95%
interval of the mean difference persona - memory (2000 draws, seed 7), resampling people.
Usage: score_panel3w.py <people06.json> <persona06.jsonl> <memory06.jsonl> <people08.json> ... (three per panel)"""
import json, sys, numpy as np
Q = ["happy", "satfin", "finalter", "health"]
def load(f):
    out = {}
    for l in open(f):
        r = json.loads(l)
        if not r["p"] or len(r["p"]) != len(r["ids"]): continue
        for i, x in zip(r["ids"], r["p"]): out[i] = x
    return out
def brier(pr, y, n):
    v = np.clip(np.array(pr[:n], float), 0, None)
    if len(v) != n or v.sum() <= 0: return None
    v = v / v.sum(); t = np.zeros(n); t[y - 1] = 1; return float(((v - t) ** 2).sum())
people, per_q, per_panel = {}, {q: [] for q in Q}, {}
args = sys.argv[1:]
for k in range(0, len(args), 3):
    D = json.load(open(args[k])); P = {p["id"]: p for p in D["people"] if p["split"] == "test"}; A, B = load(args[k + 1]), load(args[k + 2])
    tag = str(D["year"]); per_panel[tag] = []
    for i in set(A) & set(B) & set(P):
        rows = []
        for q in Q:
            y = P[i]["target"][q]; n = len(D["options"][q])
            if y is None or not (1 <= y <= n): continue
            a, b = brier(A[i].get(q, []), y, n), brier(B[i].get(q, []), y, n)
            if a is not None and b is not None: rows.append((q, a, b))
        if rows:
            people[(tag, i)] = rows; per_panel[tag] += [(a, b) for _, a, b in rows]
            for q, a, b in rows: per_q[q].append((a, b))
for q in Q:
    x = np.array(per_q[q]); print(f"{q:9s} n {len(x):4d}  persona {x[:, 0].mean():.4f}  memory {x[:, 1].mean():.4f}  memory better by {(x[:, 0] - x[:, 1]).mean():+.4f}")
for t, r in per_panel.items():
    x = np.array(r); print(f"panel ending {t}: n {len(x)}  persona {x[:, 0].mean():.4f}  memory {x[:, 1].mean():.4f}  diff {(x[:, 0] - x[:, 1]).mean():+.4f}")
keys = list(people); d_person = np.array([np.mean([a - b for _, a, b in people[k]]) for k in keys]); w = np.array([len(people[k]) for k in keys])
diff = float((d_person * w).sum() / w.sum())
rng = np.random.default_rng(7); bs = []
for _ in range(2000):
    ix = rng.integers(0, len(keys), len(keys)); bs.append(float((d_person[ix] * w[ix]).sum() / w[ix].sum()))
lo, hi = np.quantile(bs, [0.025, 0.975])
allr = [r for k in keys for r in people[k]]; pa = np.mean([a for _, a, _ in allr]); pb = np.mean([b for _, _, b in allr])
print(json.dumps({"people": len(keys), "answers": len(allr), "persona": round(pa, 4), "memory": round(pb, 4), "diff": round(diff, 4), "ci95": [round(lo, 4), round(hi, 4)], "relative_pct": round(diff / pa * 100, 2), "primary_met": bool(lo > 0)}))
