#!/usr/bin/env python3
"""Score a ChatGPT ads check from stored raw responses (no provider call).

Usage: score-chatgpt-ads-check.py <run-dir>
Reads <run-dir>/calls.jsonl and <run-dir>/raw/*.json, writes <run-dir>/summary.json
and <run-dir>/calls.csv (route, prompt, country, ok, ads, sponsored mentions, product cards, sources, ms).
"""
import csv, json, re, sys
from collections import defaultdict
from pathlib import Path

SPONSORED = re.compile(r"\bsponsored\b", re.I)

def score(raw):
    try:
        d = json.loads(raw)
    except Exception:
        return {"ok": False}
    o = d.get("output", d)
    if "result" in o:  # cloro
        r = o["result"] or {}
        ads = r.get("ads") or []
        return {"ok": bool(o.get("success")), "ads": len(ads),
                "advertisers": sorted({a.get("advertiser") or a.get("domain") or a.get("title") or "" for a in ads}),
                "products": len(r.get("shoppingCards") or []) + len(r.get("inlineProducts") or []),
                "sources": len(r.get("sources") or []),
                "sponsored_in_text": len(SPONSORED.findall(r.get("markdown") or r.get("text") or ""))}
    if "tasks" in o:  # dataforseo
        t = (o.get("tasks") or [{}])[0]
        res = (t.get("result") or [{}])[0] or {}
        items = res.get("items") or []
        types = [i.get("type") for i in items]
        ads = [i for i in items if "ad" in (i.get("type") or "").split("_")]
        return {"ok": t.get("status_code") == 20000, "ads": len(ads), "advertisers": [],
                "products": types.count("chat_gpt_products"),
                "sources": len(res.get("sources") or []),
                "sponsored_in_text": len(SPONSORED.findall(res.get("markdown") or "")),
                "item_types": sorted(set(types)), "cost": t.get("cost")}
    return {"ok": False}

def main():
    run = Path(sys.argv[1])
    rows = [json.loads(l) for l in open(run / "calls.jsonl")]
    by = defaultdict(lambda: {"calls": 0, "ok": 0, "with_ads": 0, "ads": 0, "with_products": 0,
                              "sponsored_in_text": 0, "ms": []})
    out = []
    for r in rows:
        s = score((run / "raw" / r["raw"]).read_text())
        r.update(s)
        key = f'{r["route"]} {r["country"]}'
        b = by[key]
        b["calls"] += 1; b["ok"] += s.get("ok", False); b["ads"] += s.get("ads", 0)
        b["with_ads"] += s.get("ads", 0) > 0; b["with_products"] += s.get("products", 0) > 0
        b["sponsored_in_text"] += s.get("sponsored_in_text", 0) > 0; b["ms"].append(r["ms"])
        out.append(r)
    for b in by.values():
        ms = sorted(b.pop("ms")); b["p50_s"] = round(ms[len(ms) // 2] / 1000, 1)
    (run / "summary.json").write_text(json.dumps({"date": run.name, "calls": len(out), "by_route": by}, indent=1))
    with open(run / "calls.csv", "w", newline="") as f:
        w = csv.writer(f)
        w.writerow(["route", "country", "prompt", "ok", "ads", "sponsored_in_text", "product_cards", "sources", "seconds"])
        for r in sorted(out, key=lambda r: (r["route"], r["country"], r["n"])):
            w.writerow([r["route"], r["country"], r["prompt"], r.get("ok"), r.get("ads", 0),
                        r.get("sponsored_in_text", 0), r.get("products", 0), r.get("sources", 0), round(r["ms"] / 1000, 1)])
    print(json.dumps(by, indent=1))

if __name__ == "__main__":
    main()
