"""The collector and catalogue review area: /collectors.

Sources of truth: app/services/collector_view.py. Read-only, owner-only (the same
`sources.manage` permission as the kill switch), and computed on every request, so
nothing here can show a number the database no longer agrees with.
"""

from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session

from app.db import get_db
from app.services import collector_view as view

router = APIRouter(prefix="/api/collectors", tags=["collectors"])


@router.get("")
def read_collectors(db: Session = Depends(get_db)) -> dict:
    return view.collectors(db)


@router.get("/catalogue")
def read_catalogue(db: Session = Depends(get_db)) -> dict:
    return view.catalogue(db)


@router.get("/runs")
def read_runs(
    collector: str | None = None,
    limit: int = Query(default=60, ge=1, le=400),
    db: Session = Depends(get_db),
) -> dict:
    return view.runs(db, collector=collector, limit=limit)


@router.get("/problems")
def read_problems(db: Session = Depends(get_db)) -> dict:
    return view.problems(db)


@router.get("/products")
def read_products(
    q: str | None = None,
    collector: str | None = None,
    airport: str | None = None,
    category: str | None = None,
    vertical: str | None = None,
    brand: str | None = None,
    size_ml: float | None = Query(default=None, ge=0),
    missing: str | None = Query(default=None, pattern="^(image|size|gtin|category|brand)$"),
    min_airports: int | None = Query(default=None, ge=1, le=25),
    group: str | None = Query(default=None, pattern="^(brand|category|vertical|size)$"),
    sort: str = Query(default="name", pattern="^(name|brand|category|size|airports|newest)$"),
    descending: bool = False,
    page: int = Query(default=1, ge=1),
    per_page: int = Query(default=50, ge=1, le=200),
    db: Session = Depends(get_db),
) -> dict:
    filters = dict(q=q, collector=collector, airport=airport, category=category,
                   vertical=vertical, missing=missing, min_airports=min_airports,
                   brand=brand, size_ml=size_ml)
    if group:
        return view.grouped(db, group=group, **filters)
    return view.products(db, sort=sort, descending=descending, page=page, per_page=per_page, **filters)
