from logging import getLogger

from fastapi import APIRouter, Depends

from models.sales import OrderWeb
from models.user import User
from auth.security import get_current_user
from config.messages import ErrorResponse, SuccessResponse
from utils.responses import error_response, success_response
from services.order_service import (
    compare_prices,
    fetch_sorted_products,
    push_items_to_toteat,
    get_active_sale_id,
    update_reward_progress,
    create_sale_record,
)

logger = getLogger(__name__)

order_router = APIRouter()


@order_router.post("/send")
async def printer_order(order: OrderWeb, current_user: User = Depends(get_current_user)):
    """Procesa un pedido: valida, registra en Toteat POS y persiste en BD."""
    items, table = order.items, order.table
    logger.info(f"Order received from {current_user.email} for table {table}")

    # 1. Validación de entrada
    if not items or not table:
        logger.warning(f"Missing fields from {current_user.email}")
        return error_response(message=ErrorResponse.MISSING_FIELDS, status_code=400)
    if not isinstance(table, int):
        logger.warning(f"Invalid table type from {current_user.email}: {type(table)}")
        return error_response(message=ErrorResponse.INVALID_TABLE_TYPE, status_code=400)

    # 2. Verificar precios actuales en BD
    try:
        products = await fetch_sorted_products(items)
        items = sorted(items, key=lambda x: x.id)
        logger.info(f"Retrieved {len(products)} products for table {table}")
    except Exception as e:
        return error_response(message=f"Error getting products: {e}", status_code=500)

    price_changes = compare_prices(products, items)
    if price_changes:
        return success_response(
            data=price_changes,
            message="El estado de los productos y items coincide con el de la venta",
            status_code=409,
        )

    # 3. Registrar en Toteat POS
    try:
        product_errors, beers = push_items_to_toteat(items, products, table, current_user.name)
    except Exception as e:
        return error_response(message=f"Error with Toteat integration: {e}", status_code=500)

    if product_errors:
        logger.error(f"Product errors for table {table}: {product_errors}")
        return error_response(error={"errors": product_errors},
                              message=ErrorResponse.PRODUCT_ADD_ERROR, status_code=424)

    # 4. Venta activa de la mesa
    try:
        active_sale_id = get_active_sale_id(table)
        if not active_sale_id:
            return error_response(message=f"No active sale found for table {table}", status_code=404)
        logger.info(f"Active sale for table {table}: {active_sale_id}")
    except Exception as e:
        return error_response(message=f"Error retrieving active sale: {e}", status_code=500)

    # 5. Puntos de fidelización (no bloquea el pedido si falla)
    new_progress = update_reward_progress(current_user, beers)

    # 6. Persistir en BD
    try:
        sale_id = create_sale_record(order, active_sale_id, items)
        if sale_id <= 0:
            return error_response(message="Failed to create sale record", status_code=500)
    except Exception as e:
        return error_response(message=f"Error creating sale record: {e}", status_code=500)

    logger.info(f"Order completed for table {table}, sale ID: {sale_id}")
    return success_response(data={"new_progress": new_progress}, message=SuccessResponse.ORDER_SUCCESS)
