"""
Catering service routes
"""
from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, HTTPException, Query
from sqlmodel import Session

from app.models import (
    ServiceCateringOut, ServiceCreateCatering, ServiceUpdateCatering, ServiceCateringsOut, Service, Catering, TipoCatering, TipoMenu, TipoEntrega, TipoArticulo
)
from app import crud
from app.api.deps import (
    CurrentUser,
    SessionDep,
    get_current_active_superuser,
)

router = APIRouter()


@router.post("/", response_model=ServiceCateringOut)
def create_service_catering(
    *,
    catering_in: ServiceCreateCatering,
    session: SessionDep,
    current_user: CurrentUser
) -> ServiceCateringOut:
    """
    Create a new catering service.
    """
    if not current_user.is_superuser and not crud.user.is_user_vendor(session=session, user_id=current_user.id):
        raise HTTPException(status_code=403, detail="User must be a vendor or superuser")

    return crud.catering.create_catering_service(
        session=session,
        obj_in=catering_in,
        account_id=current_user.id
    )


@router.get("/by_id/{service_id}", response_model=ServiceCateringOut)
def read_service_catering_by_id(
    *,
    service_id: UUID,
    session: SessionDep
) -> ServiceCateringOut:
    """
    Get a specific catering service by ID.
    """
    service = crud.catering.get_catering_service(session=session, service_id=service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Catering service not found")
    return service


@router.get("/all", response_model=ServiceCateringsOut)
def read_all_caterings(
    *,
    session: SessionDep,
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=100)
) -> ServiceCateringsOut:
    """
    Get all catering services.
    """
    services, count = crud.catering.get_all_caterings(
        session=session,
        skip=skip,
        limit=limit
    )
    return ServiceCateringsOut(data=services, count=count)


@router.get("/all_me", response_model=ServiceCateringsOut)
def read_all_caterings_me(
    *,
    session: SessionDep,
    current_user: CurrentUser,
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=100)
) -> ServiceCateringsOut:
    """
    Get all catering services for the current user.
    """
    services, count = crud.catering.get_caterings_by_account(
        session=session,
        account_id=current_user.id,
        skip=skip,
        limit=limit
    )
    return ServiceCateringsOut(data=services, count=count)


@router.get("/filter", response_model=ServiceCateringsOut)
def read_caterings_filtered(
    *,
    session: SessionDep,
    tipo_entrega: Optional[TipoEntrega] = None,
    tipo_catering: Optional[TipoCatering] = None,
    num_comensales: Optional[int] = None,
    duracion: Optional[float] = None,
    menu_or_articulo: Optional[bool] = None,
    tipo_menu: Optional[TipoMenu] = None,
    tipo_articulo: Optional[TipoArticulo] = None,
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=100)
) -> ServiceCateringsOut:
    """
    Get filtered catering services.
    """
    services, count = crud.catering.get_caterings_filtered(
        session=session,
        tipo_entrega=tipo_entrega,
        tipo_catering=tipo_catering,
        num_comensales=num_comensales,
        duracion=duracion,
        menu_or_articulo=menu_or_articulo,
        tipo_menu=tipo_menu,
        tipo_articulo=tipo_articulo,
        skip=skip,
        limit=limit
    )
    return ServiceCateringsOut(data=services, count=count)


@router.get("/filter_me", response_model=ServiceCateringsOut)
def read_caterings_filtered_me(
    *,
    session: SessionDep,
    current_user: CurrentUser,
    tipo_entrega: Optional[TipoEntrega] = None,
    tipo_catering: Optional[TipoCatering] = None,
    num_comensales: Optional[int] = None,
    duracion: Optional[float] = None,
    tipo_menu: Optional[TipoMenu] = None,
    tipo_articulo: Optional[TipoArticulo] = None,
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=100)
) -> ServiceCateringsOut:
    """
    Get filtered catering services for the current user.
    """
    services, count = crud.catering.get_caterings_filtered_me(
        session=session,
        account_id=current_user.id,
        tipo_entrega=tipo_entrega,
        tipo_catering=tipo_catering,
        num_comensales=num_comensales,
        duracion=duracion,
        tipo_menu=tipo_menu,
        tipo_articulo=tipo_articulo,
        skip=skip,
        limit=limit
    )
    return ServiceCateringsOut(data=services, count=count)


@router.put("/{service_id}", response_model=ServiceCateringOut)
def update_service_catering_full(
    *,
    service_id: UUID,
    catering_in: ServiceUpdateCatering,
    session: SessionDep,
    current_user: CurrentUser
) -> ServiceCateringOut:
    """
    Update a catering service (full update).
    """
    service = crud.catering.get_catering_service(session=session, service_id=service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Catering service not found")
    
    if service.account_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    
    # Get related objects
    db_service = session.get(Service, service_id)
    db_catering = session.get(Catering, service_id)  # Using same ID
    
    return crud.catering.update_catering_service(
        session=session,
        service=db_service,
        catering=db_catering,
        obj_in=catering_in
    )


@router.patch("/{service_id}", response_model=ServiceCateringOut)
def update_service_catering_partial(
    *,
    service_id: UUID,
    catering_in: ServiceUpdateCatering,
    session: SessionDep,
    current_user: CurrentUser
) -> ServiceCateringOut:
    """
    Update a catering service (partial update).
    """
    service = crud.catering.get_catering_service(session=session, service_id=service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Catering service not found")
    
    if service.account_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    
    # Get related objects
    db_service = session.get(Service, service_id)
    db_catering = session.get(Catering, service_id)  # Using same ID
    
    return crud.catering.update_catering_service(
        session=session,
        service=db_service,
        catering=db_catering,
        obj_in=catering_in
    )


@router.delete("/{service_id}")
def delete_service_catering(
    *,
    service_id: UUID,
    session: SessionDep,
    current_user: CurrentUser
) -> dict:
    """
    Delete a catering service.
    """
    service = session.get(Service, service_id)
    catering = session.get(Catering, service_id)
    if not service or not catering:
        raise HTTPException(status_code=404, detail="Catering service not found")
    
    if service.account_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(status_code=403, detail="Not enough permissions")

    crud.catering.delete_catering_service(
        session=session,
        service=service,
        catering=catering
    )
    
    return {"Servicio de catering eliminado correctamente": True}