from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import date, datetime, time

# --- Configuración de Respuesta (Read/Response) ---
class ConfigRead(BaseModel):
    """Configuración compartida para todos los esquemas de lectura/respuesta."""
    class Config:
        from_attributes = True
        json_encoders = {
            date: lambda v: v.isoformat() if v else None,
            datetime: lambda v: v.isoformat() if v else None,
            time: lambda v: v.isoformat() if v else None,
        }

# ============================================================
# 1. 🏢 RESTAURANTE
# ============================================================

class RestauranteCreate(BaseModel):
    """DTO para crear un Restaurante (Input)."""
    ruc: str = Field(..., max_length=15, description="RUC único del restaurante.")
    nombre: str
    razon_social: str
    email: str = Field(..., description="Email único de contacto.")
    whatsapp: str = Field(..., description="WhatsApp único de contacto.")

class RestauranteRead(ConfigRead):
    """DTO para leer un Restaurante (Output)."""
    id: int
    ruc: str
    nombre: str
    razon_social: str
    email: str
    whatsapp: str


# ============================================================
# 2. 🏪 SUCURSAL
# ============================================================

class SucursalCreate(BaseModel):
    """DTO para crear una Sucursal (Input)."""
    id_restaurante: int = Field(..., description="ID del restaurante al que pertenece.")
    direccion: str
    ciudad: str

class SucursalRead(ConfigRead):
    """DTO para leer una Sucursal (Output)."""
    id: int
    id_restaurante: int
    direccion: str
    ciudad: str


# ============================================================
# 3. 🍽️ MESA
# ============================================================

class MesaCreate(BaseModel):
    """DTO para crear una Mesa (Input)."""
    id_sucursal: int
    identificador_mesa: int = Field(..., ge=1, description="Número de mesa dentro de la sucursal.")
    capacidad: int = Field(..., ge=1, description="Número máximo de personas.")
    ubicacion: str = Field(..., description="Ubicación (ej: 'Terraza', 'Salón principal').")
    disponible: bool = True

class MesaRead(ConfigRead):
    """DTO para leer una Mesa (Output)."""
    id: int
    id_sucursal: int
    identificador_mesa: int
    capacidad: int
    ubicacion: str
    disponible: bool


# ============================================================
# 4. 🧍‍♂️ CLIENTE
# ============================================================

class ClienteCreate(BaseModel):
    """DTO para crear un Cliente (Input)."""
    whatsapp: str = Field(..., description="Número de WhatsApp único del cliente.")
    nombre: str

class ClienteRead(ConfigRead):
    """DTO para leer un Cliente (Output)."""
    id: int
    whatsapp: str
    nombre: str
    fecha_registro: datetime
    
    model_config = {
        "from_attributes": True 
    }

# ============================================================
# 5. 📅 RESERVA
# ============================================================

class ReservaCreate(BaseModel):
    """DTO para crear una Reserva (Input)."""
    id_sucursal: int
    id_cliente: int
    id_mesa: int
    fecha_reserva: datetime
    estado: str = Field(..., description="Estado de la reserva (ej: CONFIRMADA, PENDIENTE).")

class ReservaRead(ConfigRead):
    id: int
    id_sucursal: int
    id_cliente: int
    id_mesa: int
    fecha_reserva: datetime
    estado: str
    fecha_registro: datetime

class ReservaResponse(ConfigRead):
    id: int
    mesa: str  # ejemplo: "Mesa 5"
    ubicacion: str  # ejemplo: "Terraza"
    fecha_reserva: datetime
    estado: str
    fecha_registro: datetime

# ============================================================
# 6. 💬 CONVERSACIÓN
# ============================================================

class ConversacionCreate(BaseModel):
    """DTO para crear una Conversación (Input)."""
    wamid: Optional[str] = Field(None, description="ID único del mensaje de WhatsApp (opcional en input).")
    mensaje: str
    whatsapp: str
    username: str
    origen: str = Field(..., pattern="^(USUARIO|BOT)$", description="Origen del mensaje: USUARIO o BOT.")

class ConversacionRead(ConfigRead):
    """DTO para leer una Conversación (Output)."""
    id: int
    wamid: Optional[str]
    mensaje: str
    whatsapp: str
    username: str
    origen: str
    fecha: datetime


# ============================================================
# 7. 🏷️ CATEGORIA
# ============================================================

class CategoriaCreate(BaseModel):
    """DTO para crear una Categoría (Input)."""
    nombre: str
    posicion: int = Field(..., ge=1, description="Orden de visualización en el menú.")

class CategoriaRead(ConfigRead):
    """DTO para leer una Categoría (Output)."""
    id: int
    nombre: str
    posicion: int


# ============================================================
# 8. 🥘 PLATO
# ============================================================

class PlatoCreate(BaseModel):
    """DTO para crear un Plato (Input)."""
    id_categoria: int
    nombre: str
    imagen: Optional[str] = Field(None, description="URL o ruta de la imagen del plato.")
    precio_base: float = Field(..., gt=0)
    disponible: bool = True

class PlatoRead(ConfigRead):
    """DTO para leer un Plato (Output)."""
    id: int
    id_categoria: int
    nombre: str
    imagen: Optional[str]
    precio_base: float
    disponible: bool

class PlatoResponse(ConfigRead):
    id: int
    nombre: str
    categoria: str 
    precio_base: float


# ============================================================
# 9. 📜 MENU
# ============================================================

class MenuCreate(BaseModel):
    """DTO para crear un Menú (Input)."""
    nombre: str
    inicio: datetime = Field(..., description="Fecha y hora de inicio de vigencia.")
    fin: datetime = Field(..., description="Fecha y hora de fin de vigencia.")

class MenuRead(ConfigRead):
    """DTO para leer un Menú (Output)."""
    id: int
    nombre: str
    inicio: datetime
    fin: datetime
    
class ItemMenuResponse(ConfigRead):
    nombre_plato: str
    categoria: str
    precio_base: float
    precio_especial: float

class MenuResponse(ConfigRead):
    nombre: str
    inicio: datetime
    fin: datetime
    items: List[ItemMenuResponse]


# ============================================================
# 10. 📝 ITEM_MENU (Detalle del Menú)
# ============================================================

class ItemMenuCreate(BaseModel):
    """DTO para crear un ItemMenu (Input)."""
    id_menu: int
    id_plato: int
    posicion: int
    precio_especial: Optional[float] = Field(None, gt=0, description="Precio opcional para este ítem en el menú.")

class ItemMenuRead(ConfigRead):
    """DTO para leer un ItemMenu (Output)."""
    id: int
    id_menu: int
    id_plato: int
    posicion: int
    precio_especial: Optional[float]
