"""Endpoints de los catálogos del SAT — **solo lectura**.

No se exponen POST/PUT/PATCH/DELETE a propósito: son catálogos fijos publicados por
el SAT y se mantienen con ``seed_data.sync_catalogs()``, no por API.

Nota: aunque los catálogos son globales, el router del módulo exige ``fin.access``,
permiso que se resuelve sobre una compañía; por eso las peticiones siguen llevando
``company_id`` en la query string.
"""

from typing import Literal

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

from core.database import get_core_db
from core.security import get_current_user

from . import service
from .dto import (
    CfdiUseResponse,
    PaymentFormResponse,
    PaymentMethodResponse,
    ProductServiceResponse,
    TaxObjectResponse,
    TaxRegimeResponse,
    TaxResponse,
    UnitOfMeasureResponse,
    VoucherTypeResponse,
)

router = APIRouter()

_SEARCH = Query(None, description="Búsqueda por clave o descripción")
_ACTIVE_ONLY = Query(True, description="Solo claves vigentes")


@router.get("/catalogs/tax-regimes", response_model=list[TaxRegimeResponse])
def list_tax_regimes(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    person_type: Literal["fisica", "moral"] | None = Query(
        None, description="Acota al régimen de persona física o moral"
    ),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_RegimenFiscal`` — régimen fiscal del emisor/receptor del CFDI."""
    return service.get_tax_regimes(db, search, active_only, person_type)


@router.get("/catalogs/taxes", response_model=list[TaxResponse])
def list_taxes(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_Impuesto`` — impuestos federales trasladados y retenidos."""
    return service.get_taxes(db, search, active_only)


@router.get("/catalogs/payment-forms", response_model=list[PaymentFormResponse])
def list_payment_forms(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_FormaPago`` — medio con el que se liquidó el comprobante."""
    return service.get_payment_forms(db, search, active_only)


@router.get("/catalogs/units-of-measure", response_model=list[UnitOfMeasureResponse])
def list_units_of_measure(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_ClaveUnidad`` — unidad de medida de la partida."""
    return service.get_units_of_measure(db, search, active_only)


@router.get("/catalogs/products-services", response_model=list[ProductServiceResponse])
def list_products_services(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    limit: int = Query(50, ge=1, le=200, description="Máximo de claves devueltas"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_ClaveProdServ`` — clave de producto/servicio; pensado para autocompletado."""
    return service.get_products_services(db, search, active_only, limit)


@router.get("/catalogs/voucher-types", response_model=list[VoucherTypeResponse])
def list_voucher_types(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_TipoDeComprobante`` — ingreso, egreso, traslado, nómina o pago."""
    return service.get_voucher_types(db, search, active_only)


@router.get("/catalogs/payment-methods", response_model=list[PaymentMethodResponse])
def list_payment_methods(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_MetodoPago`` — PUE o PPD."""
    return service.get_payment_methods(db, search, active_only)


@router.get("/catalogs/tax-objects", response_model=list[TaxObjectResponse])
def list_tax_objects(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_ObjetoImp`` — si la partida es objeto de impuesto."""
    return service.get_tax_objects(db, search, active_only)


@router.get("/catalogs/cfdi-uses", response_model=list[CfdiUseResponse])
def list_cfdi_uses(
    search: str | None = _SEARCH,
    active_only: bool = _ACTIVE_ONLY,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_core_db),
):
    """``c_UsoCFDI`` — uso que el receptor le dará al comprobante."""
    return service.get_cfdi_uses(db, search, active_only)
