"""
batch_karaoke.py - Gera ASS karaoke para multiplos cortes de uma vez.
Mesma logica do build_karaoke_v2.py mas parametrizado por corte.
"""

import json
import sys
from pathlib import Path

TR_PATH = Path(
    "/opt/mia/workspace/videos/borrello_lives/edit/transcripts/"
    "ENERGIAS DO SOBSOLO - CASAS QUE MATAM _ Francisco Borrello.json"
)

CONTEXT_BEFORE = 2
CONTEXT_AFTER  = 2

COLOR_BASE      = "&H00FFFFFF"
COLOR_HIGHLIGHT = "&H0016A3F9"   # laranja #F97316 em BGR do ASS
COLOR_SHADOW    = "&H80000000"

FONT_NAME = "Liberation Sans"
FONT_SIZE = 54
MARGIN_V  = 380


def ass_time(t: float) -> str:
    t = max(0.0, t)
    h = int(t // 3600)
    m = int((t % 3600) // 60)
    s = int(t % 60)
    cs = int((t - int(t)) * 100)
    return f"{h}:{m:02d}:{s:02d}.{cs:02d}"


def escape_ass(text: str) -> str:
    return text.replace("{", "\\{").replace("}", "\\}")


def make_window_line(words, active_idx, ctx_before, ctx_after):
    start = max(0, active_idx - ctx_before)
    end = min(len(words), active_idx + ctx_after + 1)
    window = words[start:end]
    active_in_window = active_idx - start

    parts = []
    for i, w in enumerate(window):
        text = escape_ass(w["text"])
        if i == active_in_window:
            parts.append(f"{{\\c{COLOR_HIGHLIGHT}\\b1}}{text}{{\\b0\\c{COLOR_BASE}}}")
        else:
            parts.append(text)
    return " ".join(parts)


def load_words(tr_path, seg_start, seg_end):
    data = json.loads(tr_path.read_text())
    words = [
        w for w in data["words"]
        if w["type"] == "word"
        and w.get("start") is not None
        and w["start"] >= seg_start - 0.15
        and w["end"] <= seg_end + 0.3
    ]
    return words


ASS_HEADER_TPL = (
    "[Script Info]\n"
    "Title: Borrello Karaoke\n"
    "ScriptType: v4.00+\n"
    "WrapStyle: 2\n"
    "ScaledBorderAndShadow: yes\n"
    "PlayResX: 1080\n"
    "PlayResY: 1920\n"
    "\n"
    "[V4+ Styles]\n"
    "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, "
    "Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, "
    "Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\n"
    f"Style: Default,{FONT_NAME},{FONT_SIZE},{COLOR_BASE},{COLOR_BASE},"
    f"&H00000000,{COLOR_SHADOW},-1,0,0,0,100,100,0.5,0,1,3.5,1.5,2,40,40,{MARGIN_V},1\n"
    "\n"
    "[Events]\n"
    "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n"
)


def generate_ass(seg_start: float, seg_end: float, out_path: Path) -> int:
    words = load_words(TR_PATH, seg_start, seg_end)
    lines = [ASS_HEADER_TPL]
    n_cues = 0

    for i, word in enumerate(words):
        cue_start = max(0.0, word["start"] - seg_start)

        if i + 1 < len(words):
            cue_end = max(0.0, words[i + 1]["start"] - seg_start)
        else:
            cue_end = max(0.0, word["end"] - seg_start + 0.08)

        if cue_end <= cue_start:
            cue_end = cue_start + 0.05

        text = make_window_line(words, i, CONTEXT_BEFORE, CONTEXT_AFTER)
        line = (
            f"Dialogue: 0,{ass_time(cue_start)},{ass_time(cue_end)},"
            f"Default,,0,0,0,,{text}"
        )
        lines.append(line)
        n_cues += 1

    out_path.write_text("\n".join(lines), encoding="utf-8")
    return n_cues


# Cortes definidos
CUTS = [
    # (nome, start_s, end_s)
    ("viral_01",       677.5,  745.4),
    ("viral_02",       903.0,  975.0),
    ("viral_03",      1076.0, 1131.0),
    ("viral_04",      1439.0, 1475.0),
    ("viral_05",      4220.0, 4275.0),
    ("explicativo_01", 148.0,  355.0),
    ("explicativo_02", 517.0,  877.0),
    ("explicativo_03",1555.0, 1855.0),
]

EDIT_DIR = Path("/opt/mia/workspace/videos/borrello_lives/edit")

if __name__ == "__main__":
    filter_name = sys.argv[1] if len(sys.argv) > 1 else None

    for name, start, end in CUTS:
        if filter_name and name != filter_name:
            continue
        out = EDIT_DIR / f"karaoke_{name}.ass"
        n = generate_ass(start, end, out)
        print(f"{name}: {n} cues -> {out}")
