"""
backend/routers/scenes.py - Video scene map ingestion.
"""

from __future__ import annotations

import csv
import io

import asyncpg
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile

from backend.auth.dependencies import UserPrincipal, require_role
from backend.db.pool import get_pool

router = APIRouter()


@router.post("/upload", summary="Upload a scene CSV for a marketing video")
async def upload_scene_map(
    video_asset_id: str,
    file: UploadFile = File(...),
    pool: asyncpg.Pool = Depends(get_pool),
    user: UserPrincipal = Depends(require_role("SENIOR_BROKER")),
) -> dict[str, int | str]:
    del user
    if not file.filename or not file.filename.lower().endswith(".csv"):
        raise HTTPException(status_code=400, detail="Scene upload must be a CSV file.")

    raw_bytes = await file.read()
    try:
        text = raw_bytes.decode("utf-8-sig")
    except UnicodeDecodeError as exc:
        raise HTTPException(status_code=400, detail="CSV must be UTF-8 encoded.") from exc

    reader = csv.DictReader(io.StringIO(text))
    required = {"scene_no", "start_ms", "end_ms", "room_type"}
    if not reader.fieldnames or not required.issubset(set(reader.fieldnames)):
        raise HTTPException(
            status_code=400,
            detail="CSV must contain scene_no,start_ms,end_ms,room_type columns.",
        )

    rows: list[tuple[str, int, int, int, str, str | None]] = []
    for row in reader:
        try:
            rows.append(
                (
                    video_asset_id,
                    int(row["scene_no"]),
                    int(row["start_ms"]),
                    int(row["end_ms"]),
                    row["room_type"].strip(),
                    (row.get("description") or "").strip() or None,
                )
            )
        except (TypeError, ValueError, KeyError) as exc:
            raise HTTPException(status_code=400, detail=f"Invalid scene row: {row}") from exc

    if not rows:
        raise HTTPException(status_code=400, detail="CSV contains no scene rows.")

    async with pool.acquire() as conn:
        async with conn.transaction():
            await conn.execute(
                "DELETE FROM video_scene_maps WHERE video_asset_id = $1",
                video_asset_id,
            )
            await conn.executemany(
                """
                INSERT INTO video_scene_maps
                  (video_asset_id, scene_no, start_ms, end_ms, room_type, description)
                VALUES ($1, $2, $3, $4, $5, $6)
                """,
                rows,
            )

    return {"status": "uploaded", "video_asset_id": video_asset_id, "row_count": len(rows)}


@router.get("/{video_asset_id}", summary="List the uploaded scene map for a marketing video")
async def get_scene_map(
    video_asset_id: str,
    pool: asyncpg.Pool = Depends(get_pool),
    user: UserPrincipal = Depends(require_role("SENIOR_BROKER")),
) -> dict[str, object]:
    del user
    async with pool.acquire() as conn:
        rows = await conn.fetch(
            """
            SELECT scene_no, start_ms, end_ms, room_type, description
            FROM video_scene_maps
            WHERE video_asset_id = $1
            ORDER BY scene_no ASC
            """,
            video_asset_id,
        )
    return {
        "video_asset_id": video_asset_id,
        "row_count": len(rows),
        "scenes": [dict(row) for row in rows],
    }
