import json
from pathlib import Path

from autoshorts.growth_plan import load_testbatch
from autoshorts.mechanism_pipeline import build_mechanism_shot_plan
from autoshorts.render_manifest import build_render_manifest, write_render_manifests
from autoshorts.retention_studio import PILOT_IDEAS, build_mechanism_explainer
from autoshorts.shot_planner import build_shot_plan
from autoshorts.voiceover_finalizer import finalize_voiceover


def _shot_plan(script_id: str):
    batch = load_testbatch(Path("data/drafts/testbatch_002.json"))
    idea = next(item for item in batch["ideas"] if item["id"] == script_id)
    return build_shot_plan(finalize_voiceover(idea))


def test_build_render_manifest_maps_shot_plan_to_renderer_contract():
    plan = _shot_plan("ai-004")

    manifest = build_render_manifest(plan)

    assert manifest["schema_version"] == "render_manifest.v1"
    assert manifest["video"]["id"] == "ai-004"
    assert manifest["video"]["aspect_ratio"] == "9:16"
    assert manifest["video"]["resolution"] == {"width": 1080, "height": 1920}
    assert manifest["timeline"][0]["track"] == "visual"
    assert manifest["timeline"][0]["start_ms"] == 0
    assert manifest["timeline"][0]["duration_ms"] > 0
    assert manifest["timeline"][0]["type"] == "kinetic_text"
    assert manifest["timeline"][0]["text"] == plan["scenes"][0]["on_screen_text"]
    assert manifest["timeline"][0]["style"]["safe_area_pct"] == 8
    assert any(item["track"] == "captions" for item in manifest["timeline"])
    assert manifest["render_constraints"]["avoid_static_slideshow"] is True


def test_build_render_manifest_uses_asset_placeholders_by_type():
    plan = _shot_plan("attention-002")

    manifest = build_render_manifest(plan)

    visual_items = [item for item in manifest["timeline"] if item["track"] == "visual"]
    assert any(item["type"] == "stock_broll" for item in visual_items)
    assert any(item["type"] == "card_animation" for item in visual_items)
    assert all(item["asset_ref"].startswith("placeholder://") for item in visual_items)
    assert manifest["asset_requirements"]["stock_broll"]
    assert manifest["asset_requirements"]["screen_recording"]


def test_write_render_manifests_outputs_valid_json_files(tmp_path):
    plans = [_shot_plan("ai-004"), _shot_plan("ai-005"), _shot_plan("attention-002")]

    paths = write_render_manifests(plans, tmp_path)

    assert len(paths) == 3
    assert all(path.suffix == ".json" for path in paths)
    payload = json.loads(paths[0].read_text(encoding="utf-8"))
    assert payload["schema_version"] == "render_manifest.v1"
    assert "timeline" in payload
    assert len(payload["timeline"]) >= 10


def test_build_render_manifest_preserves_mechanism_motion_and_sound_cues():
    explainer = build_mechanism_explainer(PILOT_IDEAS[0])
    plan = build_mechanism_shot_plan(explainer)

    manifest = build_render_manifest(plan)

    visual_items = [item for item in manifest["timeline"] if item["track"] == "visual"]
    assert manifest["video"]["id"] == "hidden-money-systems-warum-ein-billiges-auto-teuer-sein-kann"
    assert [item["type"] for item in visual_items] == [
        "cinematic_ai_video",
        "cinematic_ai_video",
        "mechanism_animation",
        "mechanism_animation",
        "kinetic_text_overlay",
    ]
    assert visual_items[0]["visual_motion"] == "hard zoom, freeze-frame, red signal pulse"
    assert visual_items[0]["sound_cue"] == "bass hit + camera snap"
    assert visual_items[2]["style"]["layout"] == "xray_layer_reveal"
    assert manifest["asset_requirements"]["mechanism_animation"]
    assert manifest["render_constraints"]["max_static_cards"] == 0
    assert manifest["render_constraints"]["visual_change_every_seconds"] == 2
