#!/usr/bin/env python3
"""DIRECTOR nativo: usa visual_index (SigLIP Apache-2.0 local) p/ achar momentos-chave do casamento
e mapeia os hits (segundos-FONTE por câmera) pra TIMELINE. Vira o storyboard de momentos (sem áudio,
sem CLIP externo). Saída: moments.json {query: [{tc, t, cam, score}]}.

  ./venv/bin/python director_moments.py [workdir]

PORT VideoTask: substitui chamada MCP (app GPL, search_media) por visual_index.py local
(SigLIP Apache-2.0 via transformers). Mesmo contrato de saída, resultado equivalente."""
import json, os, sys
import vlib as V

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)
from visual_index import search as visual_search, ensure_index

WORKDIR = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()

# nome-fonte -> (cam, startFrame timeline)
P = json.load(open(os.path.join(WORKDIR, "placements.json")))["clips"]


def src_to_tl(name, src_sec):
    """nome de asset (ex C5338cerimoniacam2) + segundo-fonte -> tempo de timeline."""
    for c in P:
        n = V.footage_key(c["name"], cam=c.get("cam"))
        # do-zero: search devolve o nome COMPLETO do asset (camN_slug_FOOTAGE); casa por
        # sufixo do footage (n), não igualdade exata.
        if n == name or name.endswith(n) or c["name"].rstrip(".wav").endswith(name):
            return int(c["startFrame"]) / V.TL_FPS + src_sec
    # tenta por sufixo do mediaRef name
    for c in P:
        if name in c["name"]:
            return int(c["startFrame"]) / V.TL_FPS + src_sec
    return None


QUERIES = {
    "oficiante": "the officiant speaking at the altar",
    "celebrante_close": "close-up of the celebrant or priest speaking into a microphone",
    "speaker_mic": "a person speaking at a microphone front-facing close-up",
    "entrada_maes": "a mother being escorted down the aisle",
    "entrada_noivo": "the groom walking down the aisle",
    "entrada_padrinhos": "groomsmen and bridesmaids walking down the aisle",
    "entrada_florista": "a flower girl or child walking down the aisle",
    "noiva_entrando": "the bride in a white dress walking down the aisle",
    "noiva_porta": "the bride arriving at the doorway entrance of the venue",
    "reacao_noivo": "close-up of the groom's emotional face reacting",
    "votos": "a person reading vows from paper, speaking",
    "resposta_sim": "the bride or groom saying I do, nodding yes, front-facing",
    "aliancas": "exchanging wedding rings close-up on hands",
    "aliancas_entrada": "the wedding rings being brought in on a cushion or tray",
    "maos_dadas": "couple holding hands at the altar",
    "beijo": "the couple kissing",
    "declaracao": "the couple pronounced married, raising hands",
    "choro_emocao": "a person crying with tears of joy",
    "vo_lagrima": "an elderly woman wiping away a tear and smiling",
    "abraco": "people hugging and congratulating",
    "saida": "the married couple walking back down the aisle together",
    "aplausos": "guests applauding and standing up",
    "publico_assistindo": "wedding guests seated watching the ceremony",
    "reacao_publico": "emotional reaction of guests in the audience, moved",
    "orquestra": "orchestra and string musicians playing instruments",
    "flauta": "a flutist playing the flute",
    "sax": "a saxophone player performing",
    "violino": "a violinist or cellist playing",
    "musicos": "live musicians performing at the wedding",
    "corredor_nave": "camera gliding forward down the center aisle of the church nave toward the altar",
    "corredor_movimento": "a cinematic moving shot traveling down the aisle",
}

if __name__ == "__main__":
    os.chdir(WORKDIR)

    # Garante índice visual construído (idempotente, cache em .search_cache/)
    print("Construindo índice visual (SigLIP)...", flush=True)
    ensure_index(WORKDIR)

    out = {}
    for key, q in QUERIES.items():
        print(f"\n=== {key} ('{q}') ===", flush=True)
        d = visual_search(WORKDIR, q, limit=50)
        hits = []
        for h in d.get("moments", []):
            t = src_to_tl(h.get("name", ""),
                          (h.get("startSeconds", 0) + h.get("endSeconds", 0)) / 2)
            if t is not None:
                nm = h.get("name", "")
                cam = next((c["cam"] for c in P
                           if nm.endswith(V.footage_key(c["name"], cam=c.get("cam")))), "?")
                hits.append({"t": round(t, 1), "tc": V.tc(t), "cam": cam,
                             "score": round(h.get("score", 0), 3)})
        hits.sort(key=lambda x: -x["score"])
        out[key] = hits
        for x in hits[:6]:
            print(f"  {x['tc']} {x['cam']} score={x['score']}")

    json.dump(out, open("moments.json", "w"), indent=1)
    print("\nmoments.json salvo")
