"""④ FastAPI orchestration — LLM → Higgsfield → Remotion wrapper.

POST /api/generate  (multipart: photos[] + interview fields)
    → build_spec (Claude)  → higgsfield.generate  → remotion.render  → mp4
GET  /api/health
Static: /outputs/<file>  (final videos),  /  (the web app)
"""
from __future__ import annotations

import shutil
import uuid
from pathlib import Path

from fastapi import FastAPI, File, Form, UploadFile, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles

from app.schemas import GenerateRequest, GenerateResult, ScriptResult
from app.pipeline import spec_builder, higgsfield_client, remotion_render

ENGINE = Path(__file__).resolve().parents[2]          # engine/higgsfield_shorts
WEBAPP = ENGINE / "webapp"
OUTPUTS = ENGINE / "server" / "outputs"
UPLOADS = ENGINE / "server" / ".uploads"
OUTPUTS.mkdir(parents=True, exist_ok=True)

app = FastAPI(title="ADO2 Higgsfield Shorts")
app.add_middleware(
    CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"],
)


@app.get("/api/health")
def health():
    return {"ok": True}


@app.post("/api/captions", response_model=ScriptResult)
def captions(req: GenerateRequest):
    """인터뷰 답변 → 인트로·셀링포인트·감성스토리·CTA 4블록 (Claude)."""
    try:
        return spec_builder.build_script(req)
    except Exception as e:
        raise HTTPException(502, f"자막 생성 실패: {e}") from e


@app.post("/api/generate", response_model=GenerateResult)
async def generate(
    photos: list[UploadFile] = File(...),
    kind: str = Form(...),
    biz_name: str = Form(...),
    selling: str = Form(...),
    addr: str | None = Form(None),
    price: str | None = Form(None),
    dry_run: bool = Form(False),
):
    if len(photos) < 4:
        raise HTTPException(400, "사진 4장 이상이 필요합니다.")

    # 1. Persist uploaded photos
    job = uuid.uuid4().hex[:8]
    job_dir = UPLOADS / job
    job_dir.mkdir(parents=True, exist_ok=True)
    photo_paths: list[Path] = []
    for i, up in enumerate(photos):
        dest = job_dir / f"{i:02d}_{Path(up.filename or 'img').name}"
        with dest.open("wb") as f:
            shutil.copyfileobj(up.file, f)
        photo_paths.append(dest)

    req = GenerateRequest(kind=kind, biz_name=biz_name, addr=addr, price=price, selling=selling)

    # 2. LLM → spec
    try:
        spec = spec_builder.build_spec(req)
    except Exception as e:  # surface as a clean 502, don't swallow
        raise HTTPException(502, f"spec 생성 실패: {e}") from e

    # 3. Higgsfield → base video
    try:
        base_video, credits = higgsfield_client.generate(
            spec.higgsfield_prompt, photo_paths, dry_run=dry_run
        )
    except Exception as e:
        raise HTTPException(502, f"Higgsfield 생성 실패: {e}") from e

    # 4. Remotion → final with overlays
    try:
        final = remotion_render.render(spec, base_video)
    except Exception as e:
        raise HTTPException(502, f"Remotion 합성 실패: {e}") from e

    served = OUTPUTS / f"{job}.mp4"
    shutil.copy(final, served)

    return GenerateResult(
        video_url=f"/outputs/{job}.mp4",
        caption=spec.caption,
        profile=spec.profile,
        cost_credits=credits,
        job_id=job,
    )


# Static mounts (after API routes)
app.mount("/outputs", StaticFiles(directory=str(OUTPUTS)), name="outputs")


@app.get("/")
def index():
    return FileResponse(str(WEBAPP / "index.html"))


app.mount("/", StaticFiles(directory=str(WEBAPP)), name="webapp")
