#!/usr/bin/env python3
"""
Gera arquivos ASS de karaoke para todos os cortes do lote v2.
Cada corte tem timestamps independentes relativos ao inicio do segmento.
Padrao: Liberation Sans Bold 54px, highlight laranja #F97316, MarginV=380.
"""

import json
from pathlib import Path

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

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

# Configuracao visual (identica ao piloto aprovado)
COLOR_BASE      = "&H00FFFFFF"
COLOR_HIGHLIGHT = "&H0016A3F9"   # laranja #F97316 em BGR ASS
COLOR_SHADOW    = "&H80000000"
FONT_NAME = "Liberation Sans"
FONT_SIZE = 54
MARGIN_V  = 380
CONTEXT_BEFORE = 2
CONTEXT_AFTER  = 2

# Tabela de cortes: nome -> (start_s, end_s)
CUTS = {
    # 5 Virais refeitos
    "viral_01": (677.52,  745.98),   # Cancer/AVC/leucemia - Toda casa tem isso. Todas.
    "viral_02": (1076.24, 1131.52),  # Casos reais de morte nas casas - real e verdadeiro
    "viral_03": (1413.50, 1470.20),  # Aposta impossivel + 64 pontos - 'muito veneno muito'
    "viral_04": (782.76,  837.24),   # Cruzamento = folha de papel, cancer 3 meses Dr. Hartmann
    "viral_05": (1145.00, 1193.60),  # Raio 1 metro na cama pega sem estar em cima
    # Explicativos refeitos
    "explicativo_01": (120.0,  437.96),  # Introducao completa: o que e energia telúrica
    "explicativo_02": (2285.0, 2485.22), # Apartamento vs casa, placa vs agulha, arvore/cerca viva
    "explicativo_03": (1555.0, 1876.26), # Mapeamento Hartmann + tipos de pontos + fecho natural
}


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: list, active_idx: int) -> str:
    start = max(0, active_idx - CONTEXT_BEFORE)
    end = min(len(words), active_idx + CONTEXT_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(data: dict, seg_start: float, seg_end: float) -> list:
    return [
        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
    ]


def build_ass_header() -> str:
    return (
        "[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 gen_ass(name: str, seg_start: float, seg_end: float, data: dict) -> Path:
    words = load_words(data, seg_start, seg_end)
    print(f"  [{name}] {len(words)} palavras ({seg_start:.2f}s - {seg_end:.2f}s = {seg_end-seg_start:.1f}s)")

    lines = [build_ass_header()]
    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)
        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 = EDIT_DIR / f"karaoke_{name}.ass"
    out_path.write_text("\n".join(lines), encoding="utf-8")
    print(f"  -> {out_path} ({n_cues} cues)")
    return out_path


def main():
    print("Carregando transcricao...")
    data = json.loads(TR_PATH.read_text())
    print(f"  {len(data['words'])} tokens totais\n")

    for name, (start, end) in CUTS.items():
        gen_ass(name, start, end, data)

    print("\nTodos os ASS gerados.")


if __name__ == "__main__":
    main()
