"""Render a 9:16 YouTube Short from pre-cleaned footage, narration and ASS subtitles."""
import random
import subprocess
from pathlib import Path

from config import FOOTAGE_DIR, OUTPUT_DIR

CLEAN_DIR = FOOTAGE_DIR / "clean"


def _duration(path: Path) -> float:
    out = subprocess.run(
        ["ffprobe", "-v", "error", "-show_entries", "format=duration",
         "-of", "default=nw=1:nk=1", str(path)],
        capture_output=True, text=True, check=True,
    ).stdout
    return float(out.strip())


def _pick_footage() -> Path:
    clips = sorted(CLEAN_DIR.glob("*.mp4"))
    if not clips:
        raise FileNotFoundError("No cleaned footage. Run: python3 prep_footage.py")
    return random.choice(clips)


def render_short(mp3_path: Path, ass_path: Path, audio_duration: float, stem: str,
                 start_offset: float | None = None,
                 footage_path: Path | None = None) -> Path:
    footage = footage_path or _pick_footage()
    output = OUTPUT_DIR / f"{stem}.mp4"
    length = audio_duration + 0.5
    footage_dur = _duration(footage)

    if start_offset is None:
        start_offset = round(random.uniform(0, max(0.0, footage_dur - length - 1)), 2)

    ass_escaped = str(ass_path).replace("\\", "/").replace(":", "\\:")
    cmd = [
        "ffmpeg", "-y",
        "-stream_loop", "-1",          # loop if narration is longer than footage
        "-ss", str(start_offset),
        "-i", str(footage),
        "-i", str(mp3_path),
        "-vf", f"ass={ass_escaped}",
        "-map", "0:v:0", "-map", "1:a:0",
        "-c:v", "libx264", "-preset", "fast", "-crf", "21", "-pix_fmt", "yuv420p",
        "-c:a", "aac", "-b:a", "192k", "-ar", "44100",
        "-t", f"{length:.2f}",
        "-movflags", "+faststart",
        str(output),
    ]
    print(f"[render] {footage.name} start={start_offset:.1f}s len={length:.1f}s")
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        raise RuntimeError(f"FFmpeg failed:\n{result.stderr[-2000:]}")
    return output
