"""
Projects route – full CRUD + generate action.
Generate now dispatches a real BackgroundTask instead of a TODO comment.
"""
from typing import Optional
from fastapi import APIRouter, Depends, Query, BackgroundTasks
from app.middleware.auth import require_auth
from app.repository.store import projects_store, avatars_store
from app.schemas.schemas import ProjectCreate, ProjectUpdate
from app.utils.response import ok, err
from app.services.pipeline import run_pipeline

router = APIRouter()


@router.get("/")
async def list_projects(
    page: int = Query(1, ge=1),
    per_page: int = Query(10, ge=1, le=100),
    search: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    _: str = Depends(require_auth),
):
    result = projects_store.list(
        filters={"status": status} if status else None,
        search=search, search_fields=["title", "script", "description"],
        page=page, per_page=per_page,
    )
    return ok(result)


@router.post("/")
async def create_project(body: ProjectCreate, _: str = Depends(require_auth)):
    if not avatars_store.get(body.avatar_id):
        return err("Avatar not found", 404)
    project = projects_store.create({
        **body.model_dump(),
        "status": "draft",
        "stage": "idle",
        "stage_label": "Not started",
        "progress": 0,
        "output_url": None,
        "video_id": None,
        "duration_sec": None,
        "error": None,
    })
    return ok(project, "Project created")


@router.get("/{pid}")
async def get_project(pid: str, _: str = Depends(require_auth)):
    p = projects_store.get(pid)
    return ok(p) if p else err("Not found", 404)


@router.put("/{pid}")
async def update_project(pid: str, body: ProjectUpdate, _: str = Depends(require_auth)):
    updates = {k: v for k, v in body.model_dump().items() if v is not None}
    p = projects_store.update(pid, updates)
    return ok(p, "Updated") if p else err("Not found", 404)


@router.delete("/{pid}")
async def delete_project(pid: str, _: str = Depends(require_auth)):
    return ok(None, "Deleted") if projects_store.delete(pid) else err("Not found", 404)


@router.post("/{pid}/generate")
async def generate(pid: str, background_tasks: BackgroundTasks, _: str = Depends(require_auth)):
    """
    Kick off video generation as a background task.
    Returns immediately with status=queued; client should poll GET /{pid}.
    """
    p = projects_store.get(pid)
    if not p:
        return err("Project not found", 404)
    if p["status"] == "processing":
        return err("Already processing")
    if p["status"] == "completed":
        return err("Already completed – duplicate or re-create to regenerate")

    # Mark as queued
    projects_store.update(pid, {
        "status": "queued",
        "stage": "queued",
        "stage_label": "Queued – starting soon…",
        "progress": 0,
        "error": None,
    })

    # ✅ Dispatch real background task (no Celery needed)
    background_tasks.add_task(run_pipeline, pid)
    return ok({"id": pid, "status": "queued"}, "Generation started")


@router.get("/{pid}/status")
async def get_status(pid: str, _: str = Depends(require_auth)):
    """Lightweight polling endpoint – returns just status/progress fields."""
    p = projects_store.get(pid)
    if not p:
        return err("Not found", 404)
    return ok({
        "id":          p["id"],
        "status":      p.get("status"),
        "stage":       p.get("stage"),
        "stage_label": p.get("stage_label", ""),
        "progress":    p.get("progress", 0),
        "error":       p.get("error"),
        "did_error":   p.get("did_error"),
        "voice_warning": p.get("voice_warning"),
        "video_id":    p.get("video_id"),
        "output_url":  p.get("output_url"),
        "duration_sec":p.get("duration_sec"),
    })
