"""/api/saved-views — per-user named views over a filtered table (M8;
ADR #009). Thin router: every rule lives in services/saved_views.py;
this layer shapes HTTP and maps ServiceError -> the ApiError triple.

Views are personal navigation prefs (not tenant data): mutations here
are DELIBERATELY not written to the tenant audit trail — the security
route-audit meta-test allowlists these routes.

Routes:
  GET    /api/saved-views[?page=entries]   the user's views (pinned first)
  POST   /api/saved-views                  name the current URL state
  PATCH  /api/saved-views/{id}             rename / re-point / pin / reorder
  DELETE /api/saved-views/{id}             remove one
"""

from __future__ import annotations

import uuid

from fastapi import APIRouter
from pydantic import BaseModel

from app.routers.deps import ActorDep, ApiError, SessionDep
from app.services import saved_views as views_svc
from app.services.errors import ServiceError

router = APIRouter()


def _run(fn, *args, **kwargs):
    try:
        return fn(*args, **kwargs)
    except ServiceError as exc:
        raise ApiError(exc.status, exc.code, exc.summary, exc.detail) from exc


class ViewCreate(BaseModel):
    page: str
    name: str
    search: str = ""
    pinned: bool = False


class ViewUpdate(BaseModel):
    name: str | None = None
    search: str | None = None
    pinned: bool | None = None
    sort_order: int | None = None


@router.get("/api/saved-views")
def list_saved_views(
    session: SessionDep, actor: ActorDep, page: str | None = None
) -> dict:
    return _run(views_svc.list_views, session, actor, page)


@router.post("/api/saved-views")
def create_saved_view(
    session: SessionDep, actor: ActorDep, body: ViewCreate
) -> dict:
    row = _run(
        views_svc.create_view,
        session,
        actor,
        page=body.page,
        name=body.name,
        search=body.search,
        pinned=body.pinned,
    )
    return {"ok": True, "view": row}


@router.patch("/api/saved-views/{view_id}")
def update_saved_view(
    session: SessionDep, actor: ActorDep, view_id: uuid.UUID, body: ViewUpdate
) -> dict:
    row = _run(
        views_svc.update_view,
        session,
        actor,
        view_id,
        name=body.name,
        search=body.search,
        pinned=body.pinned,
        sort_order=body.sort_order,
    )
    return {"ok": True, "view": row}


@router.delete("/api/saved-views/{view_id}")
def delete_saved_view(
    session: SessionDep, actor: ActorDep, view_id: uuid.UUID
) -> dict:
    return _run(views_svc.delete_view, session, actor, view_id)
