"""
Implementación de modelos Pydantic para MCP-Odoo
"""

from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel, Field

# Modelos para Ventas
class SalesOrderLineCreate(BaseModel):
    """Línea de pedido de venta para creación"""
    product_id: int = Field(description="ID del producto")
    product_uom_qty: float = Field(description="Cantidad")
    price_unit: Optional[float] = Field(None, description="Precio unitario (opcional, Odoo puede calcularlo)")

class SalesOrderCreate(BaseModel):
    """Datos para crear un pedido de venta"""
    partner_id: int = Field(description="ID del cliente")
    order_lines: List[SalesOrderLineCreate] = Field(description="Líneas del pedido")
    date_order: Optional[str] = Field(None, description="Fecha del pedido (YYYY-MM-DD)")

class SalesOrderFilter(BaseModel):
    """Filtros para búsqueda de pedidos de venta"""
    partner_id: Optional[int] = Field(None, description="Filtrar por cliente ID")
    date_from: Optional[str] = Field(None, description="Fecha inicial (YYYY-MM-DD)")
    date_to: Optional[str] = Field(None, description="Fecha final (YYYY-MM-DD)")
    state: Optional[str] = Field(None, description="Estado del pedido (e.g., 'sale', 'draft', 'done')")
    limit: Optional[int] = Field(20, description="Límite de resultados")
    offset: Optional[int] = Field(0, description="Offset para paginación")
    order: Optional[str] = Field(None, description="Criterio de ordenación (e.g., 'date_order DESC')")

class SalesPerformanceInput(BaseModel):
    """Parámetros para análisis de rendimiento de ventas"""
    date_from: str = Field(description="Fecha inicial (YYYY-MM-DD)")
    date_to: str = Field(description="Fecha final (YYYY-MM-DD)")
    group_by: Optional[str] = Field(None, description="Agrupar por ('product', 'customer', 'salesperson')")

# Modelos para Compras
class PurchaseOrderLineCreate(BaseModel):
    """Línea de orden de compra para creación"""
    product_id: int = Field(description="ID del producto")
    product_qty: float = Field(description="Cantidad")
    price_unit: Optional[float] = Field(None, description="Precio unitario (opcional)")

class PurchaseOrderCreate(BaseModel):
    """Datos para crear una orden de compra"""
    partner_id: int = Field(description="ID del proveedor")
    order_lines: List[PurchaseOrderLineCreate] = Field(description="Líneas de la orden")
    date_order: Optional[str] = Field(None, description="Fecha de la orden (YYYY-MM-DD)")

class PurchaseOrderFilter(BaseModel):
    """Filtros para búsqueda de órdenes de compra"""
    partner_id: Optional[int] = Field(None, description="Filtrar por proveedor ID")
    date_from: Optional[str] = Field(None, description="Fecha inicial (YYYY-MM-DD)")
    date_to: Optional[str] = Field(None, description="Fecha final (YYYY-MM-DD)")
    state: Optional[str] = Field(None, description="Estado de la orden (e.g., 'purchase', 'draft', 'done')")
    limit: Optional[int] = Field(20, description="Límite de resultados")
    offset: Optional[int] = Field(0, description="Offset para paginación")
    order: Optional[str] = Field(None, description="Criterio de ordenación (e.g., 'date_order DESC')")

class SupplierPerformanceInput(BaseModel):
    """Parámetros para análisis de rendimiento de proveedores"""
    date_from: str = Field(description="Fecha inicial (YYYY-MM-DD)")
    date_to: str = Field(description="Fecha final (YYYY-MM-DD)")
    supplier_ids: Optional[List[int]] = Field(None, description="Lista de IDs de proveedores (opcional)")

# Modelos para Inventario
class ProductAvailabilityInput(BaseModel):
    """Parámetros para verificar disponibilidad de productos"""
    product_ids: List[int] = Field(description="Lista de IDs de productos")
    location_id: Optional[int] = Field(None, description="ID de la ubicación específica (opcional)")

class InventoryLineAdjustment(BaseModel):
    """Línea de ajuste de inventario"""
    product_id: int = Field(description="ID del producto")
    location_id: int = Field(description="ID de la ubicación")
    product_qty: float = Field(description="Cantidad contada real")

class InventoryAdjustmentCreate(BaseModel):
    """Datos para crear un ajuste de inventario"""
    name: str = Field(description="Nombre o descripción del ajuste")
    adjustment_lines: List[InventoryLineAdjustment] = Field(description="Líneas de ajuste")
    date: Optional[str] = Field(None, description="Fecha del ajuste (YYYY-MM-DD)")

class InventoryTurnoverInput(BaseModel):
    """Parámetros para análisis de rotación de inventario"""
    date_from: str = Field(description="Fecha inicial (YYYY-MM-DD)")
    date_to: str = Field(description="Fecha final (YYYY-MM-DD)")
    product_ids: Optional[List[int]] = Field(None, description="Lista de IDs de productos (opcional)")
    category_id: Optional[int] = Field(None, description="ID de categoría de producto (opcional)")

# Modelos para Contabilidad
class JournalEntryLineCreate(BaseModel):
    """Línea de asiento contable para creación"""
    account_id: int = Field(description="ID de la cuenta contable")
    partner_id: Optional[int] = Field(None, description="ID del partner (opcional)")
    name: Optional[str] = Field(None, description="Descripción de la línea")
    debit: float = Field(0.0, description="Importe al debe")
    credit: float = Field(0.0, description="Importe al haber")

class JournalEntryCreate(BaseModel):
    """Datos para crear un asiento contable"""
    ref: Optional[str] = Field(None, description="Referencia del asiento")
    journal_id: int = Field(description="ID del diario contable")
    date: Optional[str] = Field(None, description="Fecha del asiento (YYYY-MM-DD)")
    lines: List[JournalEntryLineCreate] = Field(description="Líneas del asiento (debe y haber deben cuadrar)")

class JournalEntryFilter(BaseModel):
    """Filtros para búsqueda de asientos contables"""
    date_from: Optional[str] = Field(None, description="Fecha inicial (YYYY-MM-DD)")
    date_to: Optional[str] = Field(None, description="Fecha final (YYYY-MM-DD)")
    journal_id: Optional[int] = Field(None, description="Filtrar por diario contable ID")
    state: Optional[str] = Field(None, description="Estado del asiento (e.g., 'posted', 'draft')")
    limit: Optional[int] = Field(20, description="Límite de resultados")
    offset: Optional[int] = Field(0, description="Offset para paginación")

class FinancialRatioInput(BaseModel):
    """Parámetros para cálculo de ratios financieros"""
    date_from: str = Field(description="Fecha inicial (YYYY-MM-DD)")
    date_to: str = Field(description="Fecha final (YYYY-MM-DD)")
    ratios: List[str] = Field(description="Lista de ratios a calcular (e.g., ['liquidity', 'profitability', 'debt'])")
