#!/usr/bin/env python3
from __future__ import annotations

import hashlib
import json
import math
import os
import subprocess
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
RECEIPT = ROOT / "log/footage-job-v2.json"
OUT = ROOT / "work/footage-audit-v3b"
SAMPLES = (0.1, 0.3, 0.5, 0.7, 0.9)
CLIPS_PER_SHEET = 4


def sha256(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as handle:
        for chunk in iter(lambda: handle.read(8 * 1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()


def main() -> int:
    if OUT.exists() and any(OUT.rglob("*")):
        raise RuntimeError("audit directory is not virgin")
    frames = OUT / "frames"
    sheets = OUT / "sheets"
    frames.mkdir(parents=True, exist_ok=True)
    sheets.mkdir(parents=True, exist_ok=True)
    receipt = json.loads(RECEIPT.read_text(encoding="utf-8"))
    selected = (receipt.get("latest_response") or {}).get("selected_footage") or []
    unique: dict[str, dict] = {}
    for item in selected:
        name = Path(item["path"]).name
        if name not in unique:
            source = Path("/data/video-pipeline/GacMaiAudio/footage") / name
            unique[name] = {"name": name, "source": str(source), "duration": float(item["source_duration"])}
    clips = list(unique.values())
    for clip_index, clip in enumerate(clips, 1):
        source = Path(clip["source"])
        clip_frames = []
        for sample_index, fraction in enumerate(SAMPLES, 1):
            timestamp = max(0.0, min(clip["duration"] - 0.05, clip["duration"] * fraction))
            output = frames / f"{clip_index:02d}-{clip['name'][:-4]}-{sample_index}.jpg"
            subprocess.run([
                "ffmpeg", "-v", "error", "-y", "-ss", f"{timestamp:.3f}", "-i", str(source),
                "-frames:v", "1", "-vf", "scale=304:540:force_original_aspect_ratio=increase,crop=304:540",
                "-q:v", "2", str(output),
            ], check=True)
            clip_frames.append({"fraction": fraction, "timestamp": timestamp, "path": str(output), "sha256": sha256(output)})
        clip["frames"] = clip_frames
    sheet_docs = []
    for sheet_index in range(math.ceil(len(clips) / CLIPS_PER_SHEET)):
        batch = clips[sheet_index * CLIPS_PER_SHEET:(sheet_index + 1) * CLIPS_PER_SHEET]
        inputs = []
        for clip in batch:
            for frame in clip["frames"]:
                inputs.extend(["-i", frame["path"]])
        labels = []
        for row, clip in enumerate(batch):
            for col, frame in enumerate(clip["frames"]):
                idx = row * len(SAMPLES) + col
                label = f"{clip['name']}  p{int(frame['fraction'] * 100)}"
                labels.append(
                    f"[{idx}:v]drawtext=text='{label}':x=6:y=6:fontsize=16:fontcolor=white:box=1:boxcolor=black@0.75[t{idx}]"
                )
        rows = []
        for row in range(len(batch)):
            row_labels = "".join(f"[t{row * len(SAMPLES) + col}]" for col in range(len(SAMPLES)))
            rows.append(f"{row_labels}hstack=inputs={len(SAMPLES)}[r{row}]")
        if len(batch) == 1:
            stack = "[r0]null[out]"
        else:
            stack = "".join(f"[r{row}]" for row in range(len(batch))) + f"vstack=inputs={len(batch)}[out]"
        filter_complex = ";".join(labels + rows + [stack])
        output = sheets / f"sheet-{sheet_index + 1:02d}.jpg"
        subprocess.run(["ffmpeg", "-v", "error", "-y", *inputs, "-filter_complex", filter_complex, "-map", "[out]", "-q:v", "2", str(output)], check=True)
        sheet_docs.append({"path": str(output), "sha256": sha256(output), "clips": [item["name"] for item in batch]})
    manifest = {
        "status": "completed_pending_visual_review", "verified": False,
        "source_render_receipt": str(RECEIPT), "source_render_receipt_sha256": sha256(RECEIPT),
        "sample_fractions": list(SAMPLES), "unique_selected_count": len(clips),
        "clips": clips, "sheets": sheet_docs,
        "review_contract": "Review every tile for burned-in subtitle, foreign text, watermark, QR, or prominent brand. A sampled PASS limits claims to sampled frames.",
    }
    (OUT / "audit-manifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
    print(json.dumps({"status": manifest["status"], "clips": len(clips), "sheets": len(sheet_docs), "manifest": str(OUT / "audit-manifest.json")}, ensure_ascii=False))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
