#!/usr/bin/env python3
"""
gallery_coverage_per_film.py — fraction of each film's X-Ray credited cast
that has a reference embedding in the gallery, computed per film rather than
as a single benchmark-wide average.

Usage: python3 scripts/docs/gallery_coverage_per_film.py --out docs_data/gallery_coverage_per_film.json
"""
import argparse
import csv
import json
import sys
from pathlib import Path

import h5py

REPO = Path(__file__).resolve().parent.parent.parent
sys.path.insert(0, str(REPO / "scripts" / "validation"))
from identity import keys_for  # noqa: E402


def main():
    p = argparse.ArgumentParser()
    p.add_argument("--gallery", default=str(REPO / "experiments/galleries/gallery_LVFace-B_Glint360K.h5"))
    p.add_argument("--films", default=str(REPO / "experiments/manifests/films.json"))
    p.add_argument("--out", required=True)
    args = p.parse_args()

    films = json.load(open(args.films))
    with h5py.File(args.gallery, "r") as f:
        names = [n.decode() if isinstance(n, bytes) else n for n in f["name"][:]]
        jids = [j.decode() if isinstance(j, bytes) else j for j in f["jellyfin_id"][:]]
        imdbs = [j.decode() if isinstance(j, bytes) else j for j in f["imdb_id"][:]]
    gallery_keys = set()
    for n, j, im in zip(names, jids, imdbs):
        gallery_keys |= keys_for(imdb_id=im, name=n, jellyfin_id=j)

    out = []
    for film in films:
        xray_dir = REPO / film["xray"]
        id_to_name = {}
        with open(xray_dir / "people.csv", newline="", encoding="utf-8") as fh:
            for r in csv.DictReader(fh):
                nm = (r.get("name_id") or "").strip()
                if nm:
                    id_to_name[nm] = (r.get("person") or "").strip()
        cast_keys = [keys_for(imdb_id=nm, name=name) for nm, name in id_to_name.items()]
        covered = sum(1 for ck in cast_keys if ck & gallery_keys)
        total = len(cast_keys)
        out.append({"film": film["name"], "cast_total": total, "covered": covered,
                   "coverage_pct": round(covered / total * 100, 1) if total else 0.0})

    out.sort(key=lambda x: x["coverage_pct"])
    Path(args.out).parent.mkdir(parents=True, exist_ok=True)
    json.dump(out, open(args.out, "w"), indent=1)
    for o in out:
        print(f"{o['film']:45s} {o['covered']:3d}/{o['cast_total']:3d} ({o['coverage_pct']}%)",
              file=sys.stderr)


if __name__ == "__main__":
    main()
