#!/usr/bin/env python3
"""Format a transcript slice into a screenplay-scroll script.json.

Reads a Scribe-like transcript ({words:[{start,end,text}]}), slices [start,end],
splits into sentences with per-line word-aware wrapping, and emits the JSON the
ScreenplayScroll Remotion comp consumes: {duration,fps,title,lines:[{kind,text,t,end}]}.
Times are remapped to the OUTPUT timeline (0 = clip start).
"""
import argparse
import json


def fmt(words, rs, re_, title, fps=24, width=28, cue="19 KEYS"):
    seg = [w for w in words if w["start"] >= rs - 0.05 and w["end"] <= re_ + 0.05]
    # ALWAYS end on a full point: drop any trailing partial sentence
    last = max((i for i, w in enumerate(seg) if w["text"].rstrip().endswith((".", "?", "!"))),
               default=len(seg) - 1)
    seg = seg[: last + 1]
    if seg:
        re_ = min(re_, seg[-1]["end"] + 0.12)  # keep video end aligned to the full stop
    lines = []

    def push(k, t, tt, end=False):
        lines.append({"kind": k, "text": t, "t": round(max(0, tt), 2), "end": end})

    if seg:
        push("cue", cue, seg[0]["start"] - rs)
        sents, cur = [], []
        for w in seg:
            cur.append(w)
            if w["text"].endswith((".", "?", "!")):
                sents.append(cur); cur = []
        if cur:
            sents.append(cur)
        prev = None
        for sent in sents:
            if prev is not None and (sent[0]["start"] - prev) > 1.3:
                push("cue", cue, sent[0]["start"] - rs)
            line, lt = [], None
            for w in sent:
                if lt is None:
                    lt = w["start"] - rs
                if line and len(" ".join(x["text"] for x in line)) + 1 + len(w["text"]) > width:
                    push("dia", " ".join(x["text"] for x in line), lt); line = []; lt = w["start"] - rs
                line.append(w)
            if line:
                push("dia", " ".join(x["text"] for x in line), lt, end=True)
            prev = sent[-1]["end"]
    return {"duration": round(re_ - rs, 2), "fps": fps, "title": title, "lines": lines}


if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("transcript")
    ap.add_argument("--start", type=float, required=True)
    ap.add_argument("--end", type=float, required=True)
    ap.add_argument("--title", required=True)
    ap.add_argument("--out", action="append", required=True, help="output path(s)")
    a = ap.parse_args()
    d = json.load(open(a.transcript))
    words = d["words"] if isinstance(d, dict) and "words" in d else d
    out = fmt(words, a.start, a.end, a.title)
    for p in a.out:
        json.dump(out, open(p, "w"), indent=1)
    print(f"{out['duration']}s, {len(out['lines'])} lines, title={a.title!r}")
