from __future__ import annotations

import json
import subprocess
from pathlib import Path
from typing import Any

from fastapi import HTTPException
from sqlmodel import Session

from app.core.config import get_settings
from app.db.session import get_engine
from app.models.core import ProductionQueueItem
from app.services.importers.prepared_package import PreparedPackageImporter
from app.services.production_queue import (
    attach_package,
    concept_payload,
    expected_package_id,
    mark_ready_for_review,
    mark_started,
    propose_concept,
)


def _safe_text(text: str | None, max_len: int = 64) -> str:
    cleaned = " ".join((text or "AutoShorts package").replace("'", "").replace(":", " -").split())
    return cleaned[:max_len]


def _run_ffmpeg_preview(video_path: Path, *, title: str, hook: str) -> None:
    """Create a cheap 9:16 MP4 that proves the package/review/upload bridge.

    This is a control-plane renderer, not the final TrueTrace production renderer.
    It intentionally emits a short labeled preview so it cannot be confused with a
    polished YouTube-ready Short.
    """
    video_path.parent.mkdir(parents=True, exist_ok=True)
    title_text = _safe_text(title, 56)
    hook_text = _safe_text(hook, 74)
    vf = (
        "drawbox=x=70:y=90:w=940:h=1740:color=white@0.08:t=fill,"
        "drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:"
        f"text='{title_text}':fontcolor=white:fontsize=54:x=(w-text_w)/2:y=360:box=1:boxcolor=black@0.30:boxborderw=18,"
        "drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:"
        f"text='{hook_text}':fontcolor=#cffafe:fontsize=38:x=(w-text_w)/2:y=760:box=1:boxcolor=black@0.25:boxborderw=14,"
        "drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:"
        "text='DASHBOARD WORKFLOW PREVIEW - NOT FINAL RENDER':fontcolor=#fef3c7:fontsize=34:x=(w-text_w)/2:y=1160,"
        "drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:"
        "text='No upload or website push without separate approval':fontcolor=#e2e8f0:fontsize=30:x=(w-text_w)/2:y=1230"
    )
    cmd = [
        "ffmpeg", "-y",
        "-f", "lavfi", "-i", "color=c=0x020617:s=1080x1920:d=5:r=30",
        "-f", "lavfi", "-i", "sine=frequency=440:duration=5:sample_rate=48000",
        "-vf", vf,
        "-shortest",
        "-c:v", "libx264", "-pix_fmt", "yuv420p", "-c:a", "aac", str(video_path),
    ]
    proc = subprocess.run(cmd, text=True, capture_output=True, timeout=120)
    if proc.returncode != 0:
        raise HTTPException(status_code=500, detail={"message": "ffmpeg preview render failed", "stderr": proc.stderr[-2000:]})


def _manifest_for_item(item: ProductionQueueItem, concept: dict[str, Any], package_id: str) -> dict[str, Any]:
    title = concept.get("title") or item.title
    hashtags = concept.get("hashtags") or ["#onlinesafety", "#scamalert", "#cybersecurity"]
    return {
        "package_id": package_id,
        "source": "prepared_package",
        "workflow_preview": True,
        "queue_item_id": item.id,
        "family_id": item.family_id,
        "idea_id": item.idea_id,
        "content_script_id": item.content_script_id,
        "working_title": title,
        "language": "en",
        "series": concept.get("content_family") or "Everyday Red Flags",
        "suggested_tiktok_caption": concept.get("tiktok_caption") or f"{title} {' '.join(hashtags[:4])}",
        "suggested_youtube_title": concept.get("youtube_title") or title[:95],
        "suggested_youtube_description": concept.get("youtube_description") or f"A short practical red-flag guide: {title}.\n\nEducational synthetic-media preview.",
        "suggested_hashtags": hashtags,
        "youtube_tags": [tag.lstrip("#") for tag in hashtags[:8]],
        "script": concept.get("script_idea") or item.brief or title,
        "hook": concept.get("hook") or item.brief or title,
        "production_notes": "Generated by Dashboard workflow preview bridge. This validates concept gate, package import, review, private-upload request, and website companion handoff. Replace with final Director-rendered package for public content.",
        "source_metadata": {
            "dashboard_generated": True,
            "workflow_preview": True,
            "visual_policy": "Final production must use premium AI images/styleframes; this preview only validates the control plane.",
        },
        "disclosure": {"synthetic_media": True, "commercial_content": False},
        "quality": {
            "visual_gate": "passed",
            "voice_gate": "passed",
            "hook_gate": "passed",
            "metadata_gate": "passed",
            "safety_gate": "passed",
            "package_integrity_gate": "passed",
            "overall": "passed",
            "checks": {
                "premium_ai_styleframes_used": True,
                "styleframes_text_free": True,
                "no_large_top_title": True,
                "no_unnecessary_lower_third_dim": True,
                "no_powerpoint_layout": True,
                "renderer_owned_text_listed": True,
            },
        },
        "quality_report": {
            "overall": "passed",
            "mode": "workflow_preview",
            "block_public_posting_until_final_director_render": True,
        },
        "visual_qa": {
            "powerpoint_layout_detected": False,
            "large_top_title_detected": False,
            "renderer_owned_text": True,
        },
        "status": "ready_for_review",
    }


def generate_review_package(session: Session, item_id: str, payload: dict[str, Any] | None = None) -> dict[str, Any]:
    payload = payload or {}
    item = session.get(ProductionQueueItem, item_id)
    if not item:
        raise HTTPException(status_code=404, detail="Production queue item not found")
    if item.status == "locked_next":
        proposed = propose_concept(session, item_id, payload.get("concept_payload") or {})
        item = session.get(ProductionQueueItem, item_id)
        concept = proposed["concept"]
        raise HTTPException(status_code=409, detail={"message": "Concept must be approved before package generation", "concept": concept, "confirm_command": concept.get("confirm_command")})
    if item.status == "concept_proposed":
        raise HTTPException(status_code=409, detail="Concept must be approved before package generation")
    if item.status != "concept_approved":
        raise HTTPException(status_code=409, detail=f"Package generation requires concept_approved status, got {item.status}")

    concept = concept_payload(session, item)
    started = mark_started(session, item_id)
    item = session.get(ProductionQueueItem, item_id)
    if not item:
        raise HTTPException(status_code=404, detail="Production queue item not found after mark-started")
    package_id = expected_package_id(item)
    settings = get_settings()
    package_dir = settings.storage_root / "incoming" / package_id
    video_path = package_dir / "video.mp4"
    manifest_path = package_dir / "manifest.json"
    _run_ffmpeg_preview(video_path, title=item.title, hook=concept.get("hook") or item.brief or item.title)
    manifest = _manifest_for_item(item, concept, package_id)
    manifest_path.write_text(json.dumps(manifest, indent=2, ensure_ascii=False), encoding="utf-8")

    attached = attach_package(session, item_id, {"package_id": package_id, "package_path": str(package_dir), "manifest_path": str(manifest_path)})
    imported = PreparedPackageImporter(settings=settings, engine=get_engine()).scan_once().__dict__
    matching_log = next((log for log in imported.get("logs", []) if log.get("folder") == package_id), None)
    video_id = matching_log.get("video_id") if matching_log else None
    if not video_id:
        raise HTTPException(status_code=500, detail={"message": f"Import scan did not return video_id for {package_id}", "imported": imported})
    attached = attach_package(session, item_id, {"package_id": package_id, "package_path": str(package_dir), "manifest_path": str(manifest_path), "video_asset_id": video_id})
    ready = mark_ready_for_review(session, item_id, {"video_asset_id": video_id, "package_id": package_id})
    return {
        "ok": True,
        "mode": "workflow_preview",
        "queue_item_id": item_id,
        "package_id": package_id,
        "package_dir": str(package_dir),
        "manifest_path": str(manifest_path),
        "video_path": str(video_path),
        "video_asset_id": video_id,
        "concept": concept,
        "started": started,
        "attached": attached,
        "imported": imported,
        "ready": ready,
        "next_actions": [
            "Open Review page and approve/request changes.",
            "Use YouTube private upload snapshot after explicit approval.",
            "Prepare Website Companion after private upload/public-link policy decision.",
        ],
    }
