"""
Multi-variant video export system.
Generates 4 fundamentally different video edits from the same project assets.
Each variant has distinct transitions, pacing, subtitles, color grading, and camera movements.
"""

import random
from typing import List, Dict, Any, Optional


# ── Transition pools per editing style ──────────────────────────────────

_CINEMATIC_TRANSITIONS = ["fade", "dissolve", "fadeblack", "fadewhite", "fadeslow"]
_DYNAMIC_TRANSITIONS = [
    "wipeleft",
    "wiperight",
    "slideup",
    "slidedown",
    "slideleft",
    "slideright",
    "circleopen",
    "radial",
    "smoothleft",
    "smoothright",
]
_MINIMAL_TRANSITIONS = []  # hard cuts only
_ENERGETIC_TRANSITIONS = [
    "zoomin",
    "smoothup",
    "smoothdown",
    "diagtl",
    "diagbr",
    "squeezeh",
    "squeezev",
    "pixelize",
    "hblur",
    "vertopen",
    "horzopen",
    "circleclose",
    "hlslice",
]


# ── 4 Variant Presets ───────────────────────────────────────────────────

VARIANT_PRESETS: Dict[str, Dict[str, Any]] = {
    "cinematic": {
        "description": "Slow atmospheric fades, cinematic color grading, classic bottom subtitles",
        "transitions": {
            "pool": _CINEMATIC_TRANSITIONS,
            "duration_range": [0.8, 1.2],
        },
        "subtitleStyle": {
            "preset": "classic_bottom",
            "karaoke": False,
        },
        "colorGrading": "cinematic",
        "camera": {
            "enabled": True,
            "startScale": 1.0,
            "endScale": 1.06,
            "pan_range": 0.03,
        },
        "quality": {"crf": "18", "preset": "slow"},
    },
    "dynamic": {
        "description": "Fast wipe/slide transitions, vibrant colors, TikTok karaoke subtitles",
        "transitions": {
            "pool": _DYNAMIC_TRANSITIONS,
            "duration_range": [0.3, 0.5],
        },
        "subtitleStyle": {
            "preset": "tiktok_karaoke",
            "karaoke": True,
        },
        "colorGrading": "vibrant",
        "camera": {
            "enabled": True,
            "startScale": 1.0,
            "endScale": 1.15,
            "pan_range": 0.08,
        },
        "quality": {"crf": "20", "preset": "medium"},
    },
    "minimal": {
        "description": "Clean hard cuts, no color grading, subtle zoom, minimal white subtitles",
        "transitions": {
            "pool": _MINIMAL_TRANSITIONS,
            "duration_range": [0.0, 0.0],
        },
        "subtitleStyle": {
            "preset": "minimal",
            "karaoke": False,
        },
        "colorGrading": "",
        "camera": {
            "enabled": True,
            "startScale": 1.0,
            "endScale": 1.04,
            "pan_range": 0.02,
        },
        "quality": {"crf": "18", "preset": "slow"},
    },
    "energetic": {
        "description": "Creative mixed transitions, teal-orange grade, bold centered karaoke",
        "transitions": {
            "pool": _ENERGETIC_TRANSITIONS,
            "duration_range": [0.4, 0.7],
        },
        "subtitleStyle": {
            "preset": "bold_center",
            "karaoke": True,
        },
        "colorGrading": "teal-orange",
        "camera": {
            "enabled": True,
            "startScale": 1.0,
            "endScale": 1.12,
            "pan_range": 0.06,
        },
        "quality": {"crf": "20", "preset": "medium"},
    },
}


def generate_variant_payload(
    project_data: Dict[str, Any],
    variant_name: str,
    seed: int = 42,
) -> Dict[str, Any]:
    """
    Build a complete editor export payload for a given variant.

    Args:
        project_data: Full project dict (with images, videos, audios arrays).
        variant_name: Key from VARIANT_PRESETS.
        seed: RNG seed for reproducible transition/camera selection.

    Returns:
        Editor payload dict ready for POST /api/projects/{id}/export-video.
    """
    if variant_name not in VARIANT_PRESETS:
        raise ValueError(
            f"Unknown variant '{variant_name}'. Choose from: {list(VARIANT_PRESETS)}"
        )

    preset = VARIANT_PRESETS[variant_name]
    rng = random.Random(seed)

    pid = project_data["id"]
    audios = sorted(project_data.get("audios", []), key=lambda a: a["scene_number"])
    videos = sorted(project_data.get("videos", []), key=lambda v: v["scene_number"])
    images = sorted(project_data.get("images", []), key=lambda i: i["scene_number"])

    video_clips: List[Dict[str, Any]] = []
    audio_clips: List[Dict[str, Any]] = []
    transitions: List[Dict[str, Any]] = []
    t = 0.0

    tr_pool = preset["transitions"]["pool"]
    tr_dur_min, tr_dur_max = preset["transitions"]["duration_range"]
    camera_cfg = preset["camera"]

    for idx, aud in enumerate(audios):
        sn = aud["scene_number"]
        dur = aud.get("duration_seconds") or 5.0

        clip_id = f"clip_{sn}"
        clip: Dict[str, Any] = {
            "id": clip_id,
            "sceneNumber": sn,
            "startTime": t,
            "duration": dur,
            "videoUrl": f"/output/{pid}/assets/frame_{sn:02d}.mp4",
            "imageUrl": f"/output/{pid}/assets/frame_{sn:02d}.png",
        }

        # Ken Burns camera movement
        if camera_cfg.get("enabled"):
            pan = camera_cfg.get("pan_range", 0.05)
            sx = 0.5 + rng.uniform(-pan, pan)
            sy = 0.5 + rng.uniform(-pan, pan)
            ex = 0.5 + rng.uniform(-pan, pan)
            ey = 0.5 + rng.uniform(-pan, pan)
            s_scale = camera_cfg.get("startScale", 1.0)
            e_scale = camera_cfg.get("endScale", 1.1)
            # 30% chance to reverse zoom direction
            if rng.random() < 0.3:
                s_scale, e_scale = e_scale, s_scale
            clip["kenBurns"] = {
                "enabled": True,
                "startScale": round(s_scale, 3),
                "endScale": round(e_scale, 3),
                "startX": round(sx, 3),
                "startY": round(sy, 3),
                "endX": round(ex, 3),
                "endY": round(ey, 3),
            }

        video_clips.append(clip)
        audio_clips.append(
            {
                "id": f"audio_{sn}",
                "sceneNumber": sn,
                "startTime": t,
                "duration": dur,
                "src": f"/output/{pid}/assets/frame_{sn:02d}.mp3",
            }
        )

        # Transition to next clip
        if idx < len(audios) - 1 and tr_pool:
            next_sn = audios[idx + 1]["scene_number"]
            transitions.append(
                {
                    "fromClipId": clip_id,
                    "toClipId": f"clip_{next_sn}",
                    "type": rng.choice(tr_pool),
                    "duration": round(rng.uniform(tr_dur_min, tr_dur_max), 2),
                }
            )

        t += dur

    return {
        "tracks": [
            {"id": "video", "clips": video_clips},
            {"id": "audio", "clips": audio_clips},
            {"id": "subtitle", "clips": []},
        ],
        "duration": t,
        "transitions": transitions,
        "effects": {
            "videoVolume": 0.3,
            "subtitleStyle": preset["subtitleStyle"],
            "colorGrading": preset.get("colorGrading", ""),
        },
    }


def list_variants() -> List[Dict[str, str]]:
    """Return variant metadata for API responses."""
    return [
        {"id": name, "description": p["description"]}
        for name, p in VARIANT_PRESETS.items()
    ]
