"""Admin gallery curation endpoints.

Allows super admins to toggle is_gallery_featured and update gallery_sort_order
on Tree (flows) and ScriptTemplate (scripts) records.
"""
from typing import Annotated
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import require_admin
from app.core.admin_database import get_admin_db
from app.models.script_template import ScriptTemplate
from app.models.tree import Tree
from app.models.user import User

router = APIRouter(prefix="/admin/gallery", tags=["admin-gallery"])


# ---------------------------------------------------------------------------
# Request schemas
# ---------------------------------------------------------------------------


class FeatureToggle(BaseModel):
    is_gallery_featured: bool


class SortOrderUpdate(BaseModel):
    gallery_sort_order: int


# ---------------------------------------------------------------------------
# Response helpers
# ---------------------------------------------------------------------------


def _flow_summary(tree: Tree) -> dict:
    return {
        "id": str(tree.id),
        "name": tree.name,
        "tree_type": tree.tree_type,
        "is_gallery_featured": tree.is_gallery_featured,
        "gallery_sort_order": tree.gallery_sort_order,
        "visibility": tree.visibility,
    }


def _script_summary(script: ScriptTemplate) -> dict:
    return {
        "id": str(script.id),
        "name": script.name,
        "is_gallery_featured": script.is_gallery_featured,
        "gallery_sort_order": script.gallery_sort_order,
        "is_active": script.is_active,
    }


# ---------------------------------------------------------------------------
# Endpoints
# ---------------------------------------------------------------------------


@router.get("/featured")
async def list_featured(
    db: Annotated[AsyncSession, Depends(get_admin_db)],
    current_user: Annotated[User, Depends(require_admin)],
):
    """List all featured flows and scripts (super admin only)."""
    flows_result = await db.execute(
        select(Tree)
        .where(Tree.is_gallery_featured == True)  # noqa: E712
        .order_by(Tree.gallery_sort_order.asc(), Tree.name.asc())
    )
    flows = flows_result.scalars().all()

    scripts_result = await db.execute(
        select(ScriptTemplate)
        .where(ScriptTemplate.is_gallery_featured == True)  # noqa: E712
        .order_by(ScriptTemplate.gallery_sort_order.asc(), ScriptTemplate.name.asc())
    )
    scripts = scripts_result.scalars().all()

    return {
        "flows": [_flow_summary(f) for f in flows],
        "scripts": [_script_summary(s) for s in scripts],
    }


@router.get("/items")
async def list_all_items(
    db: Annotated[AsyncSession, Depends(get_admin_db)],
    current_user: Annotated[User, Depends(require_admin)],
):
    """List ALL flows and scripts with their gallery status (super admin only)."""
    flows_result = await db.execute(
        select(Tree)
        .where(Tree.visibility == "public")
        .order_by(Tree.gallery_sort_order.asc(), Tree.name.asc())
    )
    flows = flows_result.scalars().all()

    scripts_result = await db.execute(
        select(ScriptTemplate)
        .order_by(ScriptTemplate.gallery_sort_order.asc(), ScriptTemplate.name.asc())
    )
    scripts = scripts_result.scalars().all()

    return {
        "flows": [_flow_summary(f) for f in flows],
        "scripts": [_script_summary(s) for s in scripts],
    }


@router.patch("/flows/{flow_id}/feature")
async def toggle_flow_featured(
    flow_id: UUID,
    body: FeatureToggle,
    db: Annotated[AsyncSession, Depends(get_admin_db)],
    current_user: Annotated[User, Depends(require_admin)],
):
    """Toggle is_gallery_featured on a flow (super admin only)."""
    result = await db.execute(select(Tree).where(Tree.id == flow_id))
    tree = result.scalar_one_or_none()
    if not tree:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Flow not found")

    tree.is_gallery_featured = body.is_gallery_featured
    await db.commit()
    await db.refresh(tree)
    return _flow_summary(tree)


@router.patch("/flows/{flow_id}/sort-order")
async def update_flow_sort_order(
    flow_id: UUID,
    body: SortOrderUpdate,
    db: Annotated[AsyncSession, Depends(get_admin_db)],
    current_user: Annotated[User, Depends(require_admin)],
):
    """Update gallery_sort_order on a flow (super admin only)."""
    result = await db.execute(select(Tree).where(Tree.id == flow_id))
    tree = result.scalar_one_or_none()
    if not tree:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Flow not found")

    tree.gallery_sort_order = body.gallery_sort_order
    await db.commit()
    await db.refresh(tree)
    return _flow_summary(tree)


@router.patch("/scripts/{script_id}/feature")
async def toggle_script_featured(
    script_id: UUID,
    body: FeatureToggle,
    db: Annotated[AsyncSession, Depends(get_admin_db)],
    current_user: Annotated[User, Depends(require_admin)],
):
    """Toggle is_gallery_featured on a script (super admin only)."""
    result = await db.execute(select(ScriptTemplate).where(ScriptTemplate.id == script_id))
    script = result.scalar_one_or_none()
    if not script:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Script not found")

    script.is_gallery_featured = body.is_gallery_featured
    await db.commit()
    await db.refresh(script)
    return _script_summary(script)


@router.patch("/scripts/{script_id}/sort-order")
async def update_script_sort_order(
    script_id: UUID,
    body: SortOrderUpdate,
    db: Annotated[AsyncSession, Depends(get_admin_db)],
    current_user: Annotated[User, Depends(require_admin)],
):
    """Update gallery_sort_order on a script (super admin only)."""
    result = await db.execute(select(ScriptTemplate).where(ScriptTemplate.id == script_id))
    script = result.scalar_one_or_none()
    if not script:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Script not found")

    script.gallery_sort_order = body.gallery_sort_order
    await db.commit()
    await db.refresh(script)
    return _script_summary(script)
