#!/usr/bin/env python3
"""filter_gallery.py — restrict a global gallery.h5 to one title's known cast.

make_jellyfin_gallery.py builds a single gallery spanning the whole Jellyfin
library, so identity_matcher can recognise any actor from any film. For a
single-title run you may instead want to restrict matching to that title's
credited cast only — fewer candidates means faster matching and fewer
look-alike false positives.

This script looks up the title's cast live from Jellyfin and writes a
filtered gallery.h5 containing only those actors, matched via the
"jellyfin_person_id" field recorded by make_jellyfin_gallery.py.

Usage:
    python scripts/filter_gallery.py \\
        --gallery gallery.h5 \\
        --jellyfin-url http://jellyfin.local:8096 \\
        --api-key YOUR_API_KEY \\
        --item-id <jellyfin item id> \\
        --output gallery_movie.h5

    # Or search by title:
    python scripts/filter_gallery.py \\
        --gallery gallery.h5 \\
        --jellyfin-url http://jellyfin.local:8096 \\
        --api-key YOUR_API_KEY \\
        --title "The Matrix" \\
        --output gallery_movie.h5
"""

import argparse
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
# Re-exported for backwards compatibility — run_from_jellyfin.py and external
# callers historically imported these from filter_gallery.
from sae_jellyfin import (  # noqa: F401
    jf_get,
    find_item_id,
    fetch_cast_person_ids,
    actor_jellyfin_id,
)
from sae_gallery import load_gallery_hdf5, save_gallery_hdf5


def main():
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument("--gallery", required=True,
                         help="Global gallery.h5 built by make_jellyfin_gallery.py")
    parser.add_argument("--jellyfin-url", required=True)
    parser.add_argument("--api-key", required=True)
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--item-id", help="Jellyfin item id of the title")
    group.add_argument("--title", help="Title to search for (uses first match)")
    parser.add_argument("--item-types", default="Movie,Series",
                         help="Item types to search when using --title (default: Movie,Series)")
    parser.add_argument("--output", required=True, help="Output filtered gallery.h5 path")
    args = parser.parse_args()

    gallery = load_gallery_hdf5(Path(args.gallery))

    item_id = args.item_id
    if item_id is None:
        item_id = find_item_id(args.jellyfin_url, args.api_key, args.title, args.item_types.split(","))
        print(f"Resolved title to item id {item_id}", file=sys.stderr)

    cast_ids = fetch_cast_person_ids(args.jellyfin_url, args.api_key, item_id)
    print(f"Title has {len(cast_ids)} credited cast member(s)", file=sys.stderr)

    actors = [a for a in gallery.get("actors", [])
              if actor_jellyfin_id(a) in cast_ids]
    missing = len(cast_ids) - len(actors)
    if missing > 0:
        print(f"[warn] {missing} cast member(s) not present in gallery (not yet embedded)", file=sys.stderr)

    # TRACES: GR-004 | SR-001
    # a filtered gallery holds the SAME vectors as its
    # source, so it inherits the source's binding. Dropping the stamp here would
    # silently launder a stamped gallery into an unstamped one.
    save_gallery_hdf5({"actors": actors}, Path(args.output),
                      gallery.get("embedder"))
    print(f"Saved {len(actors)} actor(s) to {args.output}", file=sys.stderr)


if __name__ == "__main__":
    main()
