from fastapi import FastAPI, APIRouter, HTTPException, Depends, UploadFile, File, Query
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from dotenv import load_dotenv
from starlette.middleware.cors import CORSMiddleware
from motor.motor_asyncio import AsyncIOMotorClient
import os
import logging
from pathlib import Path
from pydantic import BaseModel, Field, EmailStr
from typing import List, Optional, Dict, Any
import uuid
from datetime import datetime, timezone, timedelta
import jwt
import bcrypt
import io
import csv

ROOT_DIR = Path(__file__).parent
load_dotenv(ROOT_DIR / '.env')

# MongoDB connection
mongo_url = os.environ['MONGO_URL']
client = AsyncIOMotorClient(mongo_url)
db = client[os.environ['DB_NAME']]

# JWT Configuration
JWT_SECRET = os.environ.get('JWT_SECRET', 'multisistemas-secret-key-2024')
JWT_ALGORITHM = "HS256"
JWT_EXPIRATION_HOURS = 24

# Create the main app
app = FastAPI(title="Multisistemas - Plataforma de Gestión")

# Create a router with the /api prefix
api_router = APIRouter(prefix="/api")

security = HTTPBearer()

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# ==================== MODELS ====================

class UserBase(BaseModel):
    email: EmailStr
    nombre: str
    rol: str  # superadmin, admin, solicitante, gerente, seguridad, comandante, capitan, instructor, pañolero, maquinista
    empresa_id: Optional[str] = None

class UserCreate(UserBase):
    password: str

class UserLogin(BaseModel):
    email: EmailStr
    password: str

class UserResponse(BaseModel):
    id: str
    email: str
    nombre: str
    rol: str
    empresa_id: Optional[str] = None
    created_at: str

class TokenResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"
    user: UserResponse

# Módulos del sistema
class ModuloBase(BaseModel):
    codigo: str  # guias_despacho, inventario, etc.
    nombre: str
    descripcion: str
    icono: str  # lucide icon name
    ruta_base: str  # /guias, /inventario, etc.
    activo: bool = True

class ModuloResponse(ModuloBase):
    id: str
    created_at: str

class EmpresaBase(BaseModel):
    nombre: str
    rut: str
    subdominio: str  # mlp, amsa, etc.
    logo_url: Optional[str] = None
    primary_color: Optional[str] = "#F97316"
    nombre_area_seguridad: str = "Protección Industrial"
    motivos_rechazo: List[str] = [
        "Sello roto",
        "Carga incompleta",
        "Documentación incorrecta",
        "Vehículo no autorizado",
        "Personal no identificado"
    ]
    modulos_asignados: List[str] = []  # Lista de códigos de módulos

class EmpresaCreate(EmpresaBase):
    pass

class EmpresaResponse(EmpresaBase):
    id: str
    created_at: str

class AsignarModulosRequest(BaseModel):
    empresa_id: str
    modulos: List[str]  # Lista de códigos de módulos

# Master Tables
class VehiculoBase(BaseModel):
    patente: str
    marca: str
    modelo: str
    empresa_id: str

class EntidadBase(BaseModel):
    rut: str
    razon_social: str
    empresa_id: str

class PersonaBase(BaseModel):
    rut: str
    nombre: str
    empresa_vinculada: Optional[str] = None
    empresa_id: str

# Documento / Guía
class DocumentoCreate(BaseModel):
    tipo: str
    patente: str
    rut_destino: str
    descripcion: Optional[str] = None
    items: Optional[List[Dict[str, Any]]] = []
    folio_fisico: Optional[str] = None  # Número de folio de guía física
    documento_adjunto_url: Optional[str] = None  # URL del documento/foto adjunta

class DocumentoResponse(BaseModel):
    id: str
    folio: str
    tipo: str
    patente: str
    vehiculo_info: Optional[Dict[str, str]] = None
    rut_destino: str
    destino_info: Optional[Dict[str, str]] = None
    descripcion: Optional[str] = None
    items: List[Dict[str, Any]] = []
    estado: str  # pendiente, autorizado, rechazado, despachado
    usuario_solicitante_id: str
    usuario_solicitante_nombre: str
    empresa_id: str
    created_at: str
    updated_at: str
    aprobacion: Optional[Dict[str, Any]] = None
    punto_salida: Optional[Dict[str, Any]] = None
    folio_fisico: Optional[str] = None
    documento_adjunto_url: Optional[str] = None

class AprobacionCreate(BaseModel):
    documento_id: str
    estado: str  # autorizado, rechazado
    observacion: Optional[str] = None

class PuntoSalidaCreate(BaseModel):
    documento_id: str
    estado: str  # despachado, rechazado
    motivos_rechazo: Optional[List[str]] = []
    observacion: Optional[str] = None

class NotificacionResponse(BaseModel):
    id: str
    tipo: str
    titulo: str
    mensaje: str
    leida: bool
    usuario_id: str
    documento_id: Optional[str] = None
    created_at: str

class HistorialResponse(BaseModel):
    id: str
    documento_id: str
    folio: str
    accion: str
    usuario_id: str
    usuario_nombre: str
    detalles: Optional[Dict[str, Any]] = None
    created_at: str

class ConfiguracionUpdate(BaseModel):
    nombre_area_seguridad: Optional[str] = None
    motivos_rechazo: Optional[List[str]] = None
    primary_color: Optional[str] = None
    logo_url: Optional[str] = None

# ==================== BOMBEROS MODULE MODELS ====================

# Grados/Rangos de Bomberos
class GradoBombero:
    VOLUNTARIO = "voluntario"
    BOMBERO = "bombero"
    TENIENTE = "teniente"
    CAPITAN = "capitan"
    COMANDANTE = "comandante"

# Niveles ANB (Academia Nacional de Bomberos)
class NivelANB:
    INICIAL = "inicial"
    OPERATIVO = "operativo"
    PROFESIONAL = "profesional"

# Compañía de Bomberos (Estación)
class CompaniaBomberosBase(BaseModel):
    numero: int  # 1ra, 2da, 3ra Compañía
    nombre: str  # "Primera Compañía de Bomberos de Salamanca"
    direccion: str
    telefono: Optional[str] = None
    email: Optional[str] = None
    fecha_fundacion: Optional[str] = None
    activa: bool = True
    empresa_id: str  # Link to cuerpo de bomberos (tenant)

class CompaniaBomberosResponse(CompaniaBomberosBase):
    id: str
    created_at: str
    total_bomberos: Optional[int] = 0
    total_vehiculos: Optional[int] = 0

# Competencia/Especialidad
class CompetenciaBase(BaseModel):
    codigo: str  # hazmat, rescate, forestal, etc.
    nombre: str  # "Materiales Peligrosos (Hazmat)"
    descripcion: Optional[str] = None
    categoria: str  # tecnica, gestion, operativa
    horas_requeridas: int = 0
    vigencia_meses: int = 24  # Tiempo de validez de la certificación
    activa: bool = True
    empresa_id: str

class CompetenciaResponse(CompetenciaBase):
    id: str
    created_at: str

# Bombero (Personal)
class BomberoBase(BaseModel):
    rut: str
    nombres: str
    apellido_paterno: str
    apellido_materno: str
    fecha_nacimiento: Optional[str] = None
    fecha_ingreso: str
    grado: str = "voluntario"  # voluntario, bombero, teniente, capitan, comandante
    cargo: Optional[str] = None  # Director, Secretario, Tesorero, etc.
    compania_id: str
    email: Optional[str] = None
    telefono: Optional[str] = None
    direccion: Optional[str] = None
    grupo_sanguineo: Optional[str] = None
    contacto_emergencia: Optional[str] = None
    telefono_emergencia: Optional[str] = None
    activo: bool = True
    empresa_id: str

class BomberoResponse(BomberoBase):
    id: str
    created_at: str
    nombre_completo: Optional[str] = None
    compania_nombre: Optional[str] = None
    competencias: Optional[List[Dict[str, Any]]] = []
    epp_asignado: Optional[List[Dict[str, Any]]] = []

# Capacitación/Curso
class CapacitacionBase(BaseModel):
    codigo: str  # AUTO-GEN o manual
    nombre: str
    descripcion: Optional[str] = None
    competencia_id: Optional[str] = None  # Competencia que otorga
    nivel_anb: str = "inicial"  # inicial, operativo, profesional
    horas_duracion: int = 8
    fecha_inicio: str
    fecha_fin: str
    instructor: Optional[str] = None
    lugar: Optional[str] = None
    cupo_maximo: Optional[int] = None
    estado: str = "programada"  # programada, en_curso, finalizada, cancelada
    modulo_formacion: Optional[str] = None  # Módulo del plan de capacitación
    tipo_capacitacion: Optional[str] = None  # Tipo específico de capacitación
    objetivos: Optional[str] = None  # Objetivos de aprendizaje
    contenidos: Optional[str] = None  # Temario/contenidos
    requisitos_previos: Optional[str] = None  # Prerrequisitos
    materiales_necesarios: Optional[str] = None  # Materiales requeridos
    inscritos: List[str] = []  # Lista de IDs de bomberos inscritos
    empresa_id: Optional[str] = None  # Se asigna del usuario logueado

class CapacitacionResponse(CapacitacionBase):
    id: str
    created_at: str
    competencia_nombre: Optional[str] = None
    total_inscritos: Optional[int] = 0
    total_aprobados: Optional[int] = 0

# Asistencia a Capacitación
class AsistenciaCapacitacionBase(BaseModel):
    capacitacion_id: str
    bombero_id: str
    fecha: str
    presente: bool = False
    hora_llegada: Optional[str] = None
    hora_salida: Optional[str] = None
    observacion: Optional[str] = None
    documento_respaldo_url: Optional[str] = None  # URL del documento de respaldo

class AsistenciaCapacitacionResponse(AsistenciaCapacitacionBase):
    id: str
    bombero_nombre: Optional[str] = None

# Evaluación de Capacitación
class EvaluacionCapacitacionBase(BaseModel):
    capacitacion_id: str
    bombero_id: str
    fecha_evaluacion: str
    resultado: str  # aprobado, reprobado, pendiente
    nota: Optional[float] = None
    observacion: Optional[str] = None
    evaluador_id: Optional[str] = None

class EvaluacionCapacitacionResponse(EvaluacionCapacitacionBase):
    id: str
    bombero_nombre: Optional[str] = None
    evaluador_nombre: Optional[str] = None

# Material Mayor (Vehículos de Emergencia)
class MaterialMayorBase(BaseModel):
    codigo: str  # B-1, Z-2, etc.
    tipo: str  # carro_bomba, aljibe, escalera, rescate, hazmat
    marca: str
    modelo: str
    año: int
    patente: str
    numero_chasis: Optional[str] = None
    compania_id: str
    capacidad_agua: Optional[int] = None  # Litros
    capacidad_espuma: Optional[int] = None  # Litros
    estado_operativo: str = "operativo"  # operativo, mantenimiento, fuera_servicio
    fecha_revision_tecnica: Optional[str] = None
    fecha_permiso_circulacion: Optional[str] = None
    fecha_seguro: Optional[str] = None
    kilometraje: Optional[int] = None
    activo: bool = True
    empresa_id: str

class MaterialMayorResponse(MaterialMayorBase):
    id: str
    created_at: str
    compania_nombre: Optional[str] = None
    dias_para_revision: Optional[int] = None
    alertas: Optional[List[str]] = []

# Checklist de Material Mayor
class ChecklistMaterialMayorBase(BaseModel):
    material_mayor_id: str
    fecha: str
    responsable_id: str
    tipo: str = "diario"  # diario, semanal, mensual
    items: List[Dict[str, Any]]  # [{nombre, estado, observacion}]
    observacion_general: Optional[str] = None
    estado_general: str = "ok"  # ok, con_observaciones, fuera_servicio

class ChecklistMaterialMayorResponse(ChecklistMaterialMayorBase):
    id: str
    responsable_nombre: Optional[str] = None
    material_codigo: Optional[str] = None

# Material Menor / EPP
class TipoEPP:
    CASCO = "casco"
    CHAQUETON = "chaqueton"
    PANTALON = "pantalon"
    BOTAS = "botas"
    GUANTES = "guantes"
    CAPUCHA = "capucha"
    ERA = "equipo_respiracion"  # Equipo de Respiración Autónomo
    LINTERNA = "linterna"
    RADIO = "radio"

class MaterialMenorBase(BaseModel):
    codigo: str  # Código de inventario
    tipo: str  # casco, chaqueton, pantalon, botas, guantes, era, etc.
    marca: Optional[str] = None
    modelo: Optional[str] = None
    talla: Optional[str] = None
    numero_serie: Optional[str] = None
    fecha_adquisicion: Optional[str] = None
    fecha_vencimiento: Optional[str] = None  # Para EPP con vida útil
    estado: str = "disponible"  # disponible, asignado, mantenimiento, baja
    compania_id: str
    bombero_asignado_id: Optional[str] = None
    fecha_asignacion: Optional[str] = None
    observacion: Optional[str] = None
    activo: bool = True
    empresa_id: str

class MaterialMenorResponse(MaterialMenorBase):
    id: str
    created_at: str
    bombero_nombre: Optional[str] = None

# Solicitud de Baja de EPP
class SolicitudBajaEPPBase(BaseModel):
    material_menor_id: str  # ID del EPP a dar de baja
    motivo: str  # Motivo de la baja
    documento_evidencia_url: str  # URL del acta de baja escaneada
    observaciones: Optional[str] = None

class SolicitudBajaEPPCreate(SolicitudBajaEPPBase):
    pass

class SolicitudBajaEPPResponse(SolicitudBajaEPPBase):
    id: str
    estado: str  # pendiente, aprobada, rechazada
    solicitante_id: str
    solicitante_nombre: str
    material_codigo: Optional[str] = None
    material_tipo: Optional[str] = None
    empresa_id: str
    created_at: str
    validador_id: Optional[str] = None
    validador_nombre: Optional[str] = None
    fecha_validacion: Optional[str] = None
    motivo_rechazo: Optional[str] = None
    compania_nombre: Optional[str] = None
    dias_para_vencimiento: Optional[int] = None

# Asignación de EPP a Bombero
class AsignacionEPPBase(BaseModel):
    material_menor_id: str
    bombero_id: str
    fecha_entrega: str
    fecha_devolucion: Optional[str] = None
    estado_entrega: str = "bueno"  # bueno, regular, malo
    estado_devolucion: Optional[str] = None
    observacion_entrega: Optional[str] = None
    observacion_devolucion: Optional[str] = None
    responsable_id: str

class AsignacionEPPResponse(AsignacionEPPBase):
    id: str
    material_codigo: Optional[str] = None
    material_tipo: Optional[str] = None
    bombero_nombre: Optional[str] = None

# Acta de Registro y Evaluación (Formulario de Actividad)
class ActaActividadBase(BaseModel):
    tipo: str  # entrenamiento, academia, guardia, emergencia
    titulo: str
    descripcion: Optional[str] = None
    fecha: str
    hora_inicio: str
    hora_fin: str
    lugar: str
    compania_id: str
    responsable_id: str
    capacitacion_id: Optional[str] = None  # Si es parte de una capacitación
    asistentes: List[Dict[str, Any]] = []  # [{bombero_id, presente, evaluacion, observacion}]
    firma_responsable: bool = False
    observacion_general: Optional[str] = None
    empresa_id: str

class ActaActividadResponse(ActaActividadBase):
    id: str
    created_at: str
    responsable_nombre: Optional[str] = None
    compania_nombre: Optional[str] = None
    total_asistentes: Optional[int] = 0

# Alerta del Sistema
class AlertaBomberosBase(BaseModel):
    tipo: str  # capacitacion_vencida, epp_vencido, documento_vencido, brecha_competencia
    prioridad: str = "media"  # baja, media, alta, critica
    titulo: str
    mensaje: str
    entidad_tipo: str  # bombero, material_mayor, material_menor, capacitacion
    entidad_id: str
    bombero_id: Optional[str] = None
    compania_id: Optional[str] = None
    leida: bool = False
    resuelta: bool = False
    fecha_resolucion: Optional[str] = None
    usuario_resolucion_id: Optional[str] = None
    empresa_id: str

class AlertaBomberosResponse(AlertaBomberosBase):
    id: str
    created_at: str
    bombero_nombre: Optional[str] = None
    compania_nombre: Optional[str] = None

# KPIs del Sistema
class KPIBomberosResponse(BaseModel):
    periodo: str  # "2026-Q1", "2026-01", etc.
    compania_id: Optional[str] = None
    compania_nombre: Optional[str] = None
    # Académico
    cursos_programados: int = 0
    cursos_realizados: int = 0
    porcentaje_academico: float = 0.0
    # Operatividad
    material_mayor_total: int = 0
    material_mayor_operativo: int = 0
    porcentaje_operatividad_mayor: float = 0.0
    material_menor_total: int = 0
    material_menor_disponible: int = 0
    porcentaje_operatividad_menor: float = 0.0
    # Asistencia
    actividades_totales: int = 0
    promedio_asistencia: float = 0.0
    # Personal
    total_bomberos: int = 0
    bomberos_activos: int = 0
    bomberos_con_brechas: int = 0

# ==================== ROLES Y PERMISOS BOMBEROS ====================

# Definición de todos los permisos disponibles del módulo de Bomberos
PERMISOS_BOMBEROS = {
    # Dashboard
    "ver_dashboard": "Ver panel de control",
    "ver_kpis": "Ver KPIs institucionales",
    
    # Personal
    "ver_personal": "Ver listado de personal",
    "crear_personal": "Crear nuevo personal",
    "editar_personal": "Editar personal existente",
    "eliminar_personal": "Eliminar personal",
    
    # Material Mayor (Vehículos)
    "ver_material_mayor": "Ver material mayor",
    "crear_material_mayor": "Crear vehículos",
    "editar_material_mayor": "Editar vehículos",
    "eliminar_material_mayor": "Eliminar vehículos",
    "ver_checklists": "Ver checklists de vehículos",
    "crear_checklists": "Crear checklists",
    
    # EPP / Material Menor
    "ver_epp": "Ver equipamiento personal",
    "crear_epp": "Crear EPP",
    "editar_epp": "Editar EPP",
    "eliminar_epp": "Eliminar EPP",
    "asignar_epp": "Asignar EPP a bomberos",
    
    # Capacitaciones
    "ver_capacitaciones": "Ver capacitaciones",
    "crear_capacitaciones": "Crear capacitaciones",
    "editar_capacitaciones": "Editar capacitaciones",
    "eliminar_capacitaciones": "Eliminar capacitaciones",
    "registrar_asistencia": "Registrar asistencia",
    "registrar_evaluaciones": "Registrar evaluaciones",
    
    # Alertas
    "ver_alertas": "Ver alertas del sistema",
    "resolver_alertas": "Resolver alertas",
    "generar_alertas": "Generar alertas automáticas",
    
    # Reportes
    "ver_reportes": "Ver reportes",
    "exportar_reportes": "Exportar reportes a PDF",
    
    # Compañías
    "ver_companias": "Ver compañías",
    "crear_companias": "Crear compañías",
    "editar_companias": "Editar compañías",
    
    # Configuración
    "gestionar_roles": "Gestionar roles y permisos",
    "gestionar_usuarios": "Gestionar usuarios del módulo",
    
    # Validación de Documentos
    "validar_documentos": "Validar solicitudes de baja de EPP",
}

# Roles predefinidos con sus permisos por defecto
ROLES_BOMBEROS_DEFAULT = {
    "admin_bomberos": {
        "nombre": "Administrador",
        "descripcion": "Acceso completo al módulo de bomberos",
        "permisos": list(PERMISOS_BOMBEROS.keys()),  # Todos los permisos
    },
    "director": {
        "nombre": "Director",
        "descripcion": "Dirección general con permisos de gestión",
        "permisos": [
            "ver_dashboard", "ver_kpis",
            "ver_personal", "crear_personal", "editar_personal",
            "ver_material_mayor", "crear_material_mayor", "editar_material_mayor", "ver_checklists", "crear_checklists",
            "ver_epp", "crear_epp", "editar_epp", "asignar_epp",
            "ver_capacitaciones", "crear_capacitaciones", "editar_capacitaciones", "registrar_asistencia", "registrar_evaluaciones",
            "ver_alertas", "resolver_alertas", "generar_alertas",
            "ver_reportes", "exportar_reportes",
            "ver_companias", "editar_companias",
            "gestionar_usuarios",
            "validar_documentos",
        ],
    },
    "comandante": {
        "nombre": "Comandante",
        "descripcion": "Comandante de compañía con permisos operativos",
        "permisos": [
            "ver_dashboard", "ver_kpis",
            "ver_personal", "editar_personal",
            "ver_material_mayor", "editar_material_mayor", "ver_checklists", "crear_checklists",
            "ver_epp", "editar_epp", "asignar_epp",
            "ver_capacitaciones", "editar_capacitaciones", "registrar_asistencia", "registrar_evaluaciones",
            "ver_alertas", "resolver_alertas",
            "ver_reportes", "exportar_reportes",
            "ver_companias",
        ],
    },
    "ayudante": {
        "nombre": "Ayudante",
        "descripcion": "Ayudante con permisos de consulta y registro",
        "permisos": [
            "ver_dashboard", "ver_kpis",
            "ver_personal",
            "ver_material_mayor", "ver_checklists", "crear_checklists",
            "ver_epp",
            "ver_capacitaciones", "registrar_asistencia",
            "ver_alertas",
            "ver_reportes",
            "ver_companias",
        ],
    },
}

class RolBomberosBase(BaseModel):
    codigo: str  # admin_bomberos, director, comandante, ayudante
    nombre: str
    descripcion: Optional[str] = None
    permisos: List[str] = []  # Lista de códigos de permisos
    activo: bool = True
    empresa_id: str

class RolBomberosResponse(RolBomberosBase):
    id: str
    created_at: str

class UsuarioBomberosBase(BaseModel):
    usuario_id: str  # ID del usuario en la colección usuarios
    rol_bomberos_id: str  # ID del rol de bomberos asignado
    empresa_id: Optional[str] = None  # Se toma del usuario autenticado
    activo: bool = True

class UsuarioBomberosResponse(UsuarioBomberosBase):
    id: str
    created_at: str
    usuario_email: Optional[str] = None
    usuario_nombre: Optional[str] = None
    rol_nombre: Optional[str] = None
    permisos: List[str] = []

def hash_password(password: str) -> str:
    return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')

def verify_password(password: str, hashed: str) -> bool:
    return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8'))

def create_token(user_id: str, email: str, rol: str, empresa_id: str = None) -> str:
    payload = {
        "sub": user_id,
        "email": email,
        "rol": rol,
        "empresa_id": empresa_id,
        "exp": datetime.now(timezone.utc) + timedelta(hours=JWT_EXPIRATION_HOURS)
    }
    return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)

async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
    try:
        payload = jwt.decode(credentials.credentials, JWT_SECRET, algorithms=[JWT_ALGORITHM])
        user = await db.usuarios.find_one({"id": payload["sub"]}, {"_id": 0})
        if not user:
            raise HTTPException(status_code=401, detail="Usuario no encontrado")
        return user
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token expirado")
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Token inválido")

def require_roles(*roles):
    async def role_checker(user: dict = Depends(get_current_user)):
        # Superadmin siempre tiene acceso
        if user["rol"] == "superadmin":
            return user
        if user["rol"] not in roles:
            raise HTTPException(status_code=403, detail="No tiene permisos para esta acción")
        return user
    return role_checker

def require_superadmin():
    async def superadmin_checker(user: dict = Depends(get_current_user)):
        if user["rol"] != "superadmin":
            raise HTTPException(status_code=403, detail="Requiere permisos de Super Administrador")
        return user
    return superadmin_checker

# ==================== PERMISOS BOMBEROS HELPER ====================

async def get_user_bomberos_permisos(user_id: str, empresa_id: str) -> List[str]:
    """Obtener los permisos del módulo bomberos para un usuario"""
    usuario_bomberos = await db.bomberos_usuarios.find_one(
        {"usuario_id": user_id, "empresa_id": empresa_id, "activo": True},
        {"_id": 0}
    )
    if not usuario_bomberos:
        return []
    
    rol = await db.bomberos_roles.find_one(
        {"id": usuario_bomberos["rol_bomberos_id"], "activo": True},
        {"_id": 0}
    )
    if not rol:
        return []
    
    return rol.get("permisos", [])

def require_bomberos_permiso(*permisos_requeridos):
    """Dependency para verificar permisos específicos del módulo bomberos"""
    async def permiso_checker(user: dict = Depends(get_current_user)):
        # Superadmin siempre tiene acceso
        if user["rol"] == "superadmin":
            return user
        
        # Admin global también tiene acceso completo
        if user["rol"] == "admin":
            return user
        
        empresa_id = user.get("empresa_id")
        if not empresa_id:
            raise HTTPException(status_code=403, detail="Usuario sin empresa asignada")
        
        permisos_usuario = await get_user_bomberos_permisos(user["id"], empresa_id)
        
        # Verificar si tiene al menos uno de los permisos requeridos
        if not any(p in permisos_usuario for p in permisos_requeridos):
            raise HTTPException(
                status_code=403, 
                detail=f"No tiene permisos para esta acción. Requiere: {', '.join(permisos_requeridos)}"
            )
        
        return user
    return permiso_checker

# ==================== HELPER FUNCTIONS ====================

async def registrar_historial(documento_id: str, folio: str, accion: str, usuario_id: str, usuario_nombre: str, detalles: dict = None):
    historial = {
        "id": str(uuid.uuid4()),
        "documento_id": documento_id,
        "folio": folio,
        "accion": accion,
        "usuario_id": usuario_id,
        "usuario_nombre": usuario_nombre,
        "detalles": detalles,
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.historial.insert_one(historial)

async def crear_notificacion(usuario_id: str, tipo: str, titulo: str, mensaje: str, documento_id: str = None):
    notificacion = {
        "id": str(uuid.uuid4()),
        "tipo": tipo,
        "titulo": titulo,
        "mensaje": mensaje,
        "leida": False,
        "usuario_id": usuario_id,
        "documento_id": documento_id,
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.notificaciones.insert_one(notificacion)

async def generar_folio(empresa_id: str) -> str:
    count = await db.documentos.count_documents({"empresa_id": empresa_id})
    year = datetime.now().year
    return f"GD-{year}-{str(count + 1).zfill(6)}"

# ==================== AUTH ROUTES ====================

@api_router.post("/auth/register", response_model=TokenResponse)
async def register(user_data: UserCreate):
    existing = await db.usuarios.find_one({"email": user_data.email})
    if existing:
        raise HTTPException(status_code=400, detail="El email ya está registrado")
    
    user_id = str(uuid.uuid4())
    user = {
        "id": user_id,
        "email": user_data.email,
        "nombre": user_data.nombre,
        "rol": user_data.rol,
        "empresa_id": user_data.empresa_id,
        "password_hash": hash_password(user_data.password),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.usuarios.insert_one(user)
    
    token = create_token(user_id, user_data.email, user_data.rol, user_data.empresa_id)
    return TokenResponse(
        access_token=token,
        user=UserResponse(
            id=user_id,
            email=user_data.email,
            nombre=user_data.nombre,
            rol=user_data.rol,
            empresa_id=user_data.empresa_id,
            created_at=user["created_at"]
        )
    )

@api_router.post("/auth/login", response_model=TokenResponse)
async def login(credentials: UserLogin):
    user = await db.usuarios.find_one({"email": credentials.email}, {"_id": 0})
    if not user or not verify_password(credentials.password, user["password_hash"]):
        raise HTTPException(status_code=401, detail="Credenciales inválidas")
    
    token = create_token(user["id"], user["email"], user["rol"], user.get("empresa_id"))
    return TokenResponse(
        access_token=token,
        user=UserResponse(
            id=user["id"],
            email=user["email"],
            nombre=user["nombre"],
            rol=user["rol"],
            empresa_id=user.get("empresa_id"),
            created_at=user["created_at"]
        )
    )

@api_router.get("/auth/me", response_model=UserResponse)
async def get_me(user: dict = Depends(get_current_user)):
    return UserResponse(
        id=user["id"],
        email=user["email"],
        nombre=user["nombre"],
        rol=user["rol"],
        empresa_id=user.get("empresa_id"),
        created_at=user["created_at"]
    )

# Modelo para cambio de contraseña
class ChangePasswordRequest(BaseModel):
    user_id: str
    new_password: str

class ChangeOwnPasswordRequest(BaseModel):
    current_password: str
    new_password: str

@api_router.put("/auth/change-password")
async def change_user_password(data: ChangePasswordRequest, user: dict = Depends(require_roles("admin", "superadmin"))):
    """Cambiar contraseña de un usuario (solo admin/superadmin)"""
    # Find target user
    target_user = await db.usuarios.find_one({"id": data.user_id}, {"_id": 0})
    if not target_user:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    
    # Superadmin can change anyone, admin can only change users in their company
    if user["rol"] == "admin":
        if target_user.get("empresa_id") != user.get("empresa_id"):
            raise HTTPException(status_code=403, detail="No puede cambiar contraseña de usuarios de otra empresa")
        if target_user["rol"] == "superadmin":
            raise HTTPException(status_code=403, detail="No puede cambiar contraseña de superadmin")
    
    # Update password
    new_hash = hash_password(data.new_password)
    await db.usuarios.update_one(
        {"id": data.user_id},
        {"$set": {"password_hash": new_hash}}
    )
    
    return {"message": "Contraseña actualizada correctamente"}

@api_router.put("/auth/change-own-password")
async def change_own_password(data: ChangeOwnPasswordRequest, user: dict = Depends(get_current_user)):
    """Cambiar la propia contraseña"""
    # Verify current password
    db_user = await db.usuarios.find_one({"id": user["id"]}, {"_id": 0})
    if not verify_password(data.current_password, db_user["password_hash"]):
        raise HTTPException(status_code=400, detail="Contraseña actual incorrecta")
    
    # Update password
    new_hash = hash_password(data.new_password)
    await db.usuarios.update_one(
        {"id": user["id"]},
        {"$set": {"password_hash": new_hash}}
    )
    
    return {"message": "Contraseña actualizada correctamente"}

@api_router.get("/usuarios", response_model=List[UserResponse])
async def get_usuarios(user: dict = Depends(require_roles("admin", "superadmin"))):
    """Obtener lista de usuarios (admin ve su empresa, superadmin ve todos)"""
    query = {}
    if user["rol"] == "admin":
        query["empresa_id"] = user.get("empresa_id")
    
    usuarios = await db.usuarios.find(query, {"_id": 0, "password_hash": 0}).to_list(500)
    return [UserResponse(**u) for u in usuarios]

@api_router.get("/modulos", response_model=List[ModuloResponse])
async def get_modulos(user: dict = Depends(get_current_user)):
    """Obtener todos los módulos disponibles"""
    modulos = await db.modulos.find({"activo": True}, {"_id": 0}).to_list(100)
    return modulos

@api_router.get("/modulos/empresa", response_model=List[ModuloResponse])
async def get_modulos_empresa(user: dict = Depends(get_current_user)):
    """Obtener módulos asignados a la empresa del usuario"""
    if user["rol"] == "superadmin":
        # Superadmin ve todos los módulos
        modulos = await db.modulos.find({"activo": True}, {"_id": 0}).to_list(100)
        return modulos
    
    if not user.get("empresa_id"):
        return []
    
    empresa = await db.empresas.find_one({"id": user["empresa_id"]}, {"_id": 0})
    if not empresa:
        return []
    
    modulos_asignados = empresa.get("modulos_asignados", [])
    if not modulos_asignados:
        return []
    
    modulos = await db.modulos.find(
        {"codigo": {"$in": modulos_asignados}, "activo": True}, 
        {"_id": 0}
    ).to_list(100)
    return modulos

@api_router.post("/modulos")
async def create_modulo(modulo: ModuloBase, user: dict = Depends(require_superadmin())):
    """Crear un nuevo módulo (solo superadmin)"""
    existing = await db.modulos.find_one({"codigo": modulo.codigo})
    if existing:
        raise HTTPException(status_code=400, detail="El código de módulo ya existe")
    
    modulo_id = str(uuid.uuid4())
    modulo_data = {
        "id": modulo_id,
        **modulo.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.modulos.insert_one(modulo_data)
    return {"id": modulo_id, "message": "Módulo creado"}

@api_router.post("/empresas/{empresa_id}/modulos")
async def asignar_modulos(empresa_id: str, request: AsignarModulosRequest, user: dict = Depends(require_superadmin())):
    """Asignar módulos a una empresa (solo superadmin)"""
    empresa = await db.empresas.find_one({"id": empresa_id})
    if not empresa:
        raise HTTPException(status_code=404, detail="Empresa no encontrada")
    
    # Verificar que los módulos existen
    modulos_existentes = await db.modulos.find(
        {"codigo": {"$in": request.modulos}}, 
        {"_id": 0}
    ).to_list(100)
    codigos_existentes = [m["codigo"] for m in modulos_existentes]
    
    for codigo in request.modulos:
        if codigo not in codigos_existentes:
            raise HTTPException(status_code=400, detail=f"Módulo '{codigo}' no existe")
    
    await db.empresas.update_one(
        {"id": empresa_id},
        {"$set": {"modulos_asignados": request.modulos}}
    )
    
    return {"message": "Módulos asignados correctamente"}

# ==================== SUPERADMIN ROUTES ====================

@api_router.get("/superadmin/empresas")
async def get_all_empresas_superadmin(user: dict = Depends(require_superadmin())):
    """Obtener todas las empresas (solo superadmin)"""
    empresas = await db.empresas.find({}, {"_id": 0}).to_list(500)
    return empresas

@api_router.post("/superadmin/empresas", response_model=EmpresaResponse)
async def create_empresa_superadmin(empresa_data: EmpresaCreate, user: dict = Depends(require_superadmin())):
    """Crear empresa (solo superadmin)"""
    existing = await db.empresas.find_one({"subdominio": empresa_data.subdominio})
    if existing:
        raise HTTPException(status_code=400, detail="El subdominio ya existe")
    
    empresa_id = str(uuid.uuid4())
    empresa = {
        "id": empresa_id,
        **empresa_data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.empresas.insert_one(empresa)
    return EmpresaResponse(id=empresa_id, **empresa_data.model_dump(), created_at=empresa["created_at"])

@api_router.get("/superadmin/usuarios")
async def get_all_usuarios_superadmin(user: dict = Depends(require_superadmin())):
    """Obtener todos los usuarios de todas las empresas (solo superadmin)"""
    usuarios = await db.usuarios.find({}, {"_id": 0, "password_hash": 0}).to_list(1000)
    return usuarios

@api_router.post("/superadmin/usuarios")
async def create_usuario_superadmin(user_data: UserCreate, user: dict = Depends(require_superadmin())):
    """Crear usuario en cualquier empresa (solo superadmin)"""
    existing = await db.usuarios.find_one({"email": user_data.email})
    if existing:
        raise HTTPException(status_code=400, detail="El email ya está registrado")
    
    user_id = str(uuid.uuid4())
    new_user = {
        "id": user_id,
        "email": user_data.email,
        "nombre": user_data.nombre,
        "rol": user_data.rol,
        "empresa_id": user_data.empresa_id,
        "password_hash": hash_password(user_data.password),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.usuarios.insert_one(new_user)
    return {"id": user_id, "message": "Usuario creado"}

# ==================== EMPRESA ROUTES ====================

@api_router.post("/empresas", response_model=EmpresaResponse)
async def create_empresa(empresa_data: EmpresaCreate, user: dict = Depends(require_roles("admin"))):
    existing = await db.empresas.find_one({"subdominio": empresa_data.subdominio})
    if existing:
        raise HTTPException(status_code=400, detail="El subdominio ya existe")
    
    empresa_id = str(uuid.uuid4())
    empresa = {
        "id": empresa_id,
        **empresa_data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.empresas.insert_one(empresa)
    return EmpresaResponse(id=empresa_id, **empresa_data.model_dump(), created_at=empresa["created_at"])

@api_router.get("/empresas", response_model=List[EmpresaResponse])
async def get_empresas(user: dict = Depends(get_current_user)):
    empresas = await db.empresas.find({}, {"_id": 0}).to_list(100)
    return empresas

@api_router.get("/empresas/{empresa_id}", response_model=EmpresaResponse)
async def get_empresa(empresa_id: str, user: dict = Depends(get_current_user)):
    empresa = await db.empresas.find_one({"id": empresa_id}, {"_id": 0})
    if not empresa:
        raise HTTPException(status_code=404, detail="Empresa no encontrada")
    return empresa

@api_router.get("/empresas/subdominio/{subdominio}", response_model=EmpresaResponse)
async def get_empresa_by_subdominio(subdominio: str):
    empresa = await db.empresas.find_one({"subdominio": subdominio}, {"_id": 0})
    if not empresa:
        raise HTTPException(status_code=404, detail="Empresa no encontrada")
    return empresa

@api_router.put("/empresas/{empresa_id}/configuracion")
async def update_configuracion(empresa_id: str, config: ConfiguracionUpdate, user: dict = Depends(require_roles("admin"))):
    update_data = {k: v for k, v in config.model_dump().items() if v is not None}
    if not update_data:
        raise HTTPException(status_code=400, detail="No hay datos para actualizar")
    
    result = await db.empresas.update_one({"id": empresa_id}, {"$set": update_data})
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Empresa no encontrada")
    
    return {"message": "Configuración actualizada"}

# ==================== MASTER TABLES ROUTES ====================

@api_router.post("/vehiculos")
async def create_vehiculo(vehiculo: VehiculoBase, user: dict = Depends(require_roles("admin", "solicitante"))):
    vehiculo_data = {
        "id": str(uuid.uuid4()),
        **vehiculo.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.vehiculos.insert_one(vehiculo_data)
    return {"id": vehiculo_data["id"]}

@api_router.get("/vehiculos")
async def get_vehiculos(empresa_id: str = Query(None), user: dict = Depends(get_current_user)):
    query = {}
    if empresa_id:
        query["empresa_id"] = empresa_id
    elif user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    vehiculos = await db.vehiculos.find(query, {"_id": 0}).to_list(1000)
    return vehiculos

@api_router.get("/vehiculos/buscar/{patente}")
async def buscar_vehiculo(patente: str, user: dict = Depends(get_current_user)):
    query = {"patente": {"$regex": f"^{patente}", "$options": "i"}}
    if user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    vehiculo = await db.vehiculos.find_one(query, {"_id": 0})
    return vehiculo

@api_router.post("/entidades")
async def create_entidad(entidad: EntidadBase, user: dict = Depends(require_roles("admin", "solicitante"))):
    entidad_data = {
        "id": str(uuid.uuid4()),
        **entidad.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.entidades.insert_one(entidad_data)
    return {"id": entidad_data["id"]}

@api_router.get("/entidades")
async def get_entidades(empresa_id: str = Query(None), user: dict = Depends(get_current_user)):
    query = {}
    if empresa_id:
        query["empresa_id"] = empresa_id
    elif user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    entidades = await db.entidades.find(query, {"_id": 0}).to_list(1000)
    return entidades

@api_router.get("/entidades/buscar/{rut}")
async def buscar_entidad(rut: str, user: dict = Depends(get_current_user)):
    query = {"rut": {"$regex": f"^{rut}", "$options": "i"}}
    if user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    entidad = await db.entidades.find_one(query, {"_id": 0})
    return entidad

@api_router.post("/personas")
async def create_persona(persona: PersonaBase, user: dict = Depends(require_roles("admin", "solicitante"))):
    persona_data = {
        "id": str(uuid.uuid4()),
        **persona.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.personas.insert_one(persona_data)
    return {"id": persona_data["id"]}

@api_router.get("/personas")
async def get_personas(empresa_id: str = Query(None), user: dict = Depends(get_current_user)):
    query = {}
    if empresa_id:
        query["empresa_id"] = empresa_id
    elif user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    personas = await db.personas.find(query, {"_id": 0}).to_list(1000)
    return personas

# ==================== BULK UPLOAD ====================

@api_router.post("/upload/vehiculos")
async def upload_vehiculos(file: UploadFile = File(...), user: dict = Depends(require_roles("admin"))):
    if not user.get("empresa_id"):
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    content = await file.read()
    decoded = content.decode('utf-8')
    reader = csv.DictReader(io.StringIO(decoded))
    
    count = 0
    for row in reader:
        vehiculo = {
            "id": str(uuid.uuid4()),
            "patente": row.get("patente", "").strip().upper(),
            "marca": row.get("marca", "").strip(),
            "modelo": row.get("modelo", "").strip(),
            "empresa_id": user["empresa_id"],
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        if vehiculo["patente"]:
            await db.vehiculos.update_one(
                {"patente": vehiculo["patente"], "empresa_id": user["empresa_id"]},
                {"$set": vehiculo},
                upsert=True
            )
            count += 1
    
    return {"message": f"{count} vehículos importados"}

@api_router.post("/upload/entidades")
async def upload_entidades(file: UploadFile = File(...), user: dict = Depends(require_roles("admin"))):
    if not user.get("empresa_id"):
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    content = await file.read()
    decoded = content.decode('utf-8')
    reader = csv.DictReader(io.StringIO(decoded))
    
    count = 0
    for row in reader:
        entidad = {
            "id": str(uuid.uuid4()),
            "rut": row.get("rut", "").strip(),
            "razon_social": row.get("razon_social", "").strip(),
            "empresa_id": user["empresa_id"],
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        if entidad["rut"]:
            await db.entidades.update_one(
                {"rut": entidad["rut"], "empresa_id": user["empresa_id"]},
                {"$set": entidad},
                upsert=True
            )
            count += 1
    
    return {"message": f"{count} entidades importadas"}

@api_router.post("/upload/personas")
async def upload_personas(file: UploadFile = File(...), user: dict = Depends(require_roles("admin"))):
    if not user.get("empresa_id"):
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    content = await file.read()
    decoded = content.decode('utf-8')
    reader = csv.DictReader(io.StringIO(decoded))
    
    count = 0
    for row in reader:
        persona = {
            "id": str(uuid.uuid4()),
            "rut": row.get("rut", "").strip(),
            "nombre": row.get("nombre", "").strip(),
            "empresa_vinculada": row.get("empresa_vinculada", "").strip(),
            "empresa_id": user["empresa_id"],
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        if persona["rut"]:
            await db.personas.update_one(
                {"rut": persona["rut"], "empresa_id": user["empresa_id"]},
                {"$set": persona},
                upsert=True
            )
            count += 1
    
    return {"message": f"{count} personas importadas"}

# ==================== DOCUMENTO / GUÍA ROUTES ====================

@api_router.post("/documentos", response_model=DocumentoResponse)
async def create_documento(doc_data: DocumentoCreate, user: dict = Depends(require_roles("solicitante", "admin"))):
    if not user.get("empresa_id"):
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Auto-fill vehicle info
    vehiculo = await db.vehiculos.find_one(
        {"patente": doc_data.patente.upper(), "empresa_id": user["empresa_id"]},
        {"_id": 0}
    )
    vehiculo_info = None
    if vehiculo:
        vehiculo_info = {"marca": vehiculo.get("marca"), "modelo": vehiculo.get("modelo")}
    
    # Auto-fill destination info
    entidad = await db.entidades.find_one(
        {"rut": doc_data.rut_destino, "empresa_id": user["empresa_id"]},
        {"_id": 0}
    )
    destino_info = None
    if entidad:
        destino_info = {"razon_social": entidad.get("razon_social")}
    
    doc_id = str(uuid.uuid4())
    folio = await generar_folio(user["empresa_id"])
    now = datetime.now(timezone.utc).isoformat()
    
    documento = {
        "id": doc_id,
        "folio": folio,
        "tipo": doc_data.tipo,
        "patente": doc_data.patente.upper(),
        "vehiculo_info": vehiculo_info,
        "rut_destino": doc_data.rut_destino,
        "destino_info": destino_info,
        "descripcion": doc_data.descripcion,
        "items": doc_data.items or [],
        "estado": "pendiente",
        "usuario_solicitante_id": user["id"],
        "usuario_solicitante_nombre": user["nombre"],
        "empresa_id": user["empresa_id"],
        "created_at": now,
        "updated_at": now,
        "aprobacion": None,
        "punto_salida": None,
        "folio_fisico": doc_data.folio_fisico,
        "documento_adjunto_url": doc_data.documento_adjunto_url
    }
    
    await db.documentos.insert_one(documento)
    
    # Register history
    await registrar_historial(doc_id, folio, "CREACIÓN", user["id"], user["nombre"], {"estado": "pendiente"})
    
    # Notify managers
    gerentes = await db.usuarios.find({"rol": "gerente", "empresa_id": user["empresa_id"]}, {"_id": 0}).to_list(100)
    for gerente in gerentes:
        await crear_notificacion(
            gerente["id"],
            "nueva_guia",
            "Nueva Guía de Despacho",
            f"Se ha creado la guía {folio} y requiere su aprobación.",
            doc_id
        )
    
    return documento

@api_router.post("/documentos/upload-adjunto")
async def upload_documento_adjunto(
    file: UploadFile = File(...),
    user: dict = Depends(require_roles("solicitante", "admin"))
):
    """Subir documento/foto adjunta de la guía física"""
    import os
    
    # Validar tipo de archivo
    allowed_types = ["image/jpeg", "image/png", "image/webp", "application/pdf"]
    if file.content_type not in allowed_types:
        raise HTTPException(status_code=400, detail="Tipo de archivo no permitido. Use JPG, PNG, WebP o PDF")
    
    # Crear directorio si no existe
    upload_dir = "/app/backend/uploads/guias"
    os.makedirs(upload_dir, exist_ok=True)
    
    # Generar nombre único
    extension = file.filename.split(".")[-1] if "." in file.filename else "pdf"
    filename = f"guia_{uuid.uuid4().hex[:12]}.{extension}"
    filepath = os.path.join(upload_dir, filename)
    
    # Guardar archivo
    content = await file.read()
    with open(filepath, "wb") as f:
        f.write(content)
    
    # URL relativa para acceder al archivo
    url = f"/api/documentos/adjunto/{filename}"
    
    return {"url": url, "filename": filename, "message": "Documento subido correctamente"}

@api_router.get("/documentos/adjunto/{filename}")
async def get_documento_adjunto(filename: str):
    """Obtener documento adjunto de guía"""
    from fastapi.responses import FileResponse
    import os
    
    filepath = f"/app/backend/uploads/guias/{filename}"
    if not os.path.exists(filepath):
        raise HTTPException(status_code=404, detail="Archivo no encontrado")
    
    # Determinar content type
    extension = filename.split(".")[-1].lower()
    content_types = {
        "jpg": "image/jpeg",
        "jpeg": "image/jpeg",
        "png": "image/png",
        "webp": "image/webp",
        "pdf": "application/pdf"
    }
    content_type = content_types.get(extension, "application/octet-stream")
    
    return FileResponse(filepath, media_type=content_type, filename=filename)

@api_router.get("/documentos", response_model=List[DocumentoResponse])
async def get_documentos(
    estado: str = Query(None),
    user: dict = Depends(get_current_user)
):
    query = {}
    if user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    
    # Filter by role
    if user["rol"] == "solicitante":
        query["usuario_solicitante_id"] = user["id"]
    elif user["rol"] == "gerente":
        if estado:
            query["estado"] = estado
        else:
            query["estado"] = {"$in": ["pendiente", "autorizado", "rechazado", "despachado"]}
    elif user["rol"] == "seguridad":
        query["estado"] = {"$in": ["autorizado"]}
    
    if estado and user["rol"] != "gerente":
        query["estado"] = estado
    
    documentos = await db.documentos.find(query, {"_id": 0}).sort("created_at", -1).to_list(500)
    return documentos

@api_router.get("/documentos/todos", response_model=List[DocumentoResponse])
async def get_all_documentos(user: dict = Depends(require_roles("admin", "gerente"))):
    query = {}
    if user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    
    documentos = await db.documentos.find(query, {"_id": 0}).sort("created_at", -1).to_list(500)
    return documentos

@api_router.get("/documentos/{doc_id}", response_model=DocumentoResponse)
async def get_documento(doc_id: str, user: dict = Depends(get_current_user)):
    documento = await db.documentos.find_one({"id": doc_id}, {"_id": 0})
    if not documento:
        raise HTTPException(status_code=404, detail="Documento no encontrado")
    return documento

# ==================== APROBACIÓN (GERENCIA) ====================

@api_router.post("/documentos/{doc_id}/aprobar")
async def aprobar_documento(doc_id: str, aprobacion: AprobacionCreate, user: dict = Depends(require_roles("gerente"))):
    documento = await db.documentos.find_one({"id": doc_id}, {"_id": 0})
    if not documento:
        raise HTTPException(status_code=404, detail="Documento no encontrado")
    
    if documento["estado"] != "pendiente":
        raise HTTPException(status_code=400, detail="Solo se pueden aprobar documentos pendientes")
    
    now = datetime.now(timezone.utc).isoformat()
    nuevo_estado = aprobacion.estado  # autorizado o rechazado
    
    aprobacion_data = {
        "aprobador_id": user["id"],
        "aprobador_nombre": user["nombre"],
        "fecha": now,
        "estado": nuevo_estado,
        "observacion": aprobacion.observacion
    }
    
    await db.documentos.update_one(
        {"id": doc_id},
        {
            "$set": {
                "estado": nuevo_estado,
                "aprobacion": aprobacion_data,
                "updated_at": now
            }
        }
    )
    
    # Register history
    await registrar_historial(
        doc_id, documento["folio"], 
        f"APROBACIÓN: {nuevo_estado.upper()}", 
        user["id"], user["nombre"],
        {"observacion": aprobacion.observacion}
    )
    
    # Notify requester
    await crear_notificacion(
        documento["usuario_solicitante_id"],
        "aprobacion",
        f"Guía {documento['folio']} - {nuevo_estado.upper()}",
        f"Su guía ha sido {nuevo_estado} por {user['nombre']}. {aprobacion.observacion or ''}",
        doc_id
    )
    
    # If approved, notify security
    if nuevo_estado == "autorizado":
        seguridad_users = await db.usuarios.find(
            {"rol": "seguridad", "empresa_id": user.get("empresa_id")},
            {"_id": 0}
        ).to_list(100)
        for seg in seguridad_users:
            await crear_notificacion(
                seg["id"],
                "guia_autorizada",
                f"Guía {documento['folio']} autorizada",
                f"La guía está lista para verificación y despacho.",
                doc_id
            )
    
    return {"message": f"Documento {nuevo_estado}"}

# ==================== PUNTO DE SALIDA (SEGURIDAD) ====================

@api_router.post("/documentos/{doc_id}/despachar")
async def despachar_documento(doc_id: str, punto_salida: PuntoSalidaCreate, user: dict = Depends(require_roles("seguridad"))):
    documento = await db.documentos.find_one({"id": doc_id}, {"_id": 0})
    if not documento:
        raise HTTPException(status_code=404, detail="Documento no encontrado")
    
    if documento["estado"] != "autorizado":
        raise HTTPException(status_code=400, detail="Solo se pueden despachar documentos autorizados")
    
    now = datetime.now(timezone.utc).isoformat()
    nuevo_estado = punto_salida.estado  # despachado o rechazado
    
    # Validate rejection requires reasons and observation
    if nuevo_estado == "rechazado":
        if not punto_salida.motivos_rechazo or len(punto_salida.motivos_rechazo) == 0:
            raise HTTPException(status_code=400, detail="Debe seleccionar al menos un motivo de rechazo")
        if not punto_salida.observacion or punto_salida.observacion.strip() == "":
            raise HTTPException(status_code=400, detail="Debe ingresar una observación")
    
    punto_salida_data = {
        "responsable_id": user["id"],
        "responsable_nombre": user["nombre"],
        "fecha_verificacion": now,
        "estado": nuevo_estado,
        "motivos_rechazo": punto_salida.motivos_rechazo or [],
        "observacion": punto_salida.observacion
    }
    
    await db.documentos.update_one(
        {"id": doc_id},
        {
            "$set": {
                "estado": nuevo_estado,
                "punto_salida": punto_salida_data,
                "updated_at": now
            }
        }
    )
    
    # Register history
    await registrar_historial(
        doc_id, documento["folio"],
        f"PUNTO DE SALIDA: {nuevo_estado.upper()}",
        user["id"], user["nombre"],
        {
            "motivos_rechazo": punto_salida.motivos_rechazo,
            "observacion": punto_salida.observacion
        }
    )
    
    # If rejected at gate, notify manager and requester (CRITICAL ALERT)
    if nuevo_estado == "rechazado":
        # Notify requester
        await crear_notificacion(
            documento["usuario_solicitante_id"],
            "rechazo_critico",
            f"⚠️ ALERTA: Guía {documento['folio']} rechazada en punto de salida",
            f"Motivos: {', '.join(punto_salida.motivos_rechazo)}. Observación: {punto_salida.observacion}",
            doc_id
        )
        
        # Notify manager who approved
        if documento.get("aprobacion") and documento["aprobacion"].get("aprobador_id"):
            await crear_notificacion(
                documento["aprobacion"]["aprobador_id"],
                "rechazo_critico",
                f"⚠️ ALERTA: Guía {documento['folio']} rechazada en punto de salida",
                f"Motivos: {', '.join(punto_salida.motivos_rechazo)}. Observación: {punto_salida.observacion}",
                doc_id
            )
        
        # Log simulated email
        logger.info(f"[EMAIL SIMULADO] Alerta crítica - Guía {documento['folio']} rechazada. Motivos: {punto_salida.motivos_rechazo}")
    
    return {"message": f"Documento {nuevo_estado}"}

# ==================== NOTIFICATIONS ====================

@api_router.get("/notificaciones", response_model=List[NotificacionResponse])
async def get_notificaciones(user: dict = Depends(get_current_user)):
    notificaciones = await db.notificaciones.find(
        {"usuario_id": user["id"]},
        {"_id": 0}
    ).sort("created_at", -1).to_list(100)
    return notificaciones

@api_router.put("/notificaciones/{notif_id}/leer")
async def marcar_leida(notif_id: str, user: dict = Depends(get_current_user)):
    await db.notificaciones.update_one(
        {"id": notif_id, "usuario_id": user["id"]},
        {"$set": {"leida": True}}
    )
    return {"message": "Notificación marcada como leída"}

@api_router.put("/notificaciones/leer-todas")
async def marcar_todas_leidas(user: dict = Depends(get_current_user)):
    await db.notificaciones.update_many(
        {"usuario_id": user["id"]},
        {"$set": {"leida": True}}
    )
    return {"message": "Todas las notificaciones marcadas como leídas"}

# ==================== HISTORIAL ====================

@api_router.get("/historial", response_model=List[HistorialResponse])
async def get_historial(documento_id: str = Query(None), user: dict = Depends(get_current_user)):
    query = {}
    if documento_id:
        query["documento_id"] = documento_id
    
    historial = await db.historial.find(query, {"_id": 0}).sort("created_at", -1).to_list(500)
    return historial

# ==================== USERS MANAGEMENT ====================

@api_router.get("/usuarios", response_model=List[UserResponse])
async def get_usuarios(user: dict = Depends(require_roles("admin"))):
    query = {}
    if user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    
    usuarios = await db.usuarios.find(query, {"_id": 0, "password_hash": 0}).to_list(100)
    return usuarios

@api_router.put("/usuarios/{user_id}")
async def update_usuario(user_id: str, update_data: dict, user: dict = Depends(require_roles("admin"))):
    # Remove sensitive fields
    update_data.pop("password_hash", None)
    update_data.pop("id", None)
    
    result = await db.usuarios.update_one({"id": user_id}, {"$set": update_data})
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    
    return {"message": "Usuario actualizado"}

@api_router.delete("/usuarios/{user_id}")
async def delete_usuario(user_id: str, user: dict = Depends(require_roles("admin"))):
    result = await db.usuarios.delete_one({"id": user_id})
    if result.deleted_count == 0:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    
    return {"message": "Usuario eliminado"}

# ==================== STATS / DASHBOARD ====================

@api_router.get("/stats")
async def get_stats(user: dict = Depends(get_current_user)):
    query = {}
    if user.get("empresa_id"):
        query["empresa_id"] = user["empresa_id"]
    
    total = await db.documentos.count_documents(query)
    pendientes = await db.documentos.count_documents({**query, "estado": "pendiente"})
    autorizados = await db.documentos.count_documents({**query, "estado": "autorizado"})
    despachados = await db.documentos.count_documents({**query, "estado": "despachado"})
    rechazados = await db.documentos.count_documents({**query, "estado": "rechazado"})
    
    return {
        "total": total,
        "pendientes": pendientes,
        "autorizados": autorizados,
        "despachados": despachados,
        "rechazados": rechazados
    }

# ==================== SEED DATA ====================

@api_router.post("/seed")
async def seed_data():
    """Create demo data for testing"""
    
    # Check if superadmin exists
    existing_superadmin = await db.usuarios.find_one({"rol": "superadmin"})
    
    # Create superadmin if not exists
    if not existing_superadmin:
        superadmin_id = str(uuid.uuid4())
        superadmin = {
            "id": superadmin_id,
            "email": "superadmin@multisistemas.cl",
            "nombre": "Super Administrador",
            "rol": "superadmin",
            "empresa_id": None,
            "password_hash": hash_password("superadmin123"),
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.usuarios.insert_one(superadmin)
    
    # Create modules if not exist
    existing_modulos = await db.modulos.count_documents({})
    if existing_modulos == 0:
        modulos = [
            {
                "id": str(uuid.uuid4()),
                "codigo": "guias_despacho",
                "nombre": "Guías de Despacho",
                "descripcion": "Gestión de guías de salida de materiales con validaciones jerárquicas",
                "icono": "FileText",
                "ruta_base": "/guias",
                "activo": True,
                "created_at": datetime.now(timezone.utc).isoformat()
            },
            {
                "id": str(uuid.uuid4()),
                "codigo": "bomberos",
                "nombre": "Gestión de Bomberos",
                "descripcion": "Sistema de gestión para Cuerpos de Bomberos: personal, capacitación, material mayor/menor y KPIs",
                "icono": "Flame",
                "ruta_base": "/bomberos",
                "activo": True,
                "created_at": datetime.now(timezone.utc).isoformat()
            },
            {
                "id": str(uuid.uuid4()),
                "codigo": "inventario",
                "nombre": "Inventario",
                "descripcion": "Control de inventario y stock de materiales",
                "icono": "Package",
                "ruta_base": "/inventario",
                "activo": True,
                "created_at": datetime.now(timezone.utc).isoformat()
            },
            {
                "id": str(uuid.uuid4()),
                "codigo": "reportes",
                "nombre": "Reportes",
                "descripcion": "Generación de reportes y análisis de datos",
                "icono": "BarChart3",
                "ruta_base": "/reportes",
                "activo": True,
                "created_at": datetime.now(timezone.utc).isoformat()
            },
            {
                "id": str(uuid.uuid4()),
                "codigo": "personal",
                "nombre": "Personal",
                "descripcion": "Gestión de personal y control de acceso",
                "icono": "Users",
                "ruta_base": "/personal",
                "activo": True,
                "created_at": datetime.now(timezone.utc).isoformat()
            },
        ]
        for m in modulos:
            await db.modulos.insert_one(m)
    
    # Check if demo empresa already seeded
    existing_empresa = await db.empresas.find_one({"subdominio": "demo"})
    if existing_empresa:
        return {
            "message": "Datos ya existentes", 
            "empresa_id": existing_empresa["id"],
            "superadmin": {"email": "superadmin@multisistemas.cl", "password": "superadmin123"}
        }
    
    # Create demo empresa with guias_despacho module assigned
    empresa_id = str(uuid.uuid4())
    empresa = {
        "id": empresa_id,
        "nombre": "Empresa Demo S.A.",
        "rut": "76.123.456-7",
        "subdominio": "demo",
        "logo_url": None,
        "primary_color": "#F97316",
        "nombre_area_seguridad": "Protección Industrial",
        "motivos_rechazo": [
            "Sello roto",
            "Carga incompleta",
            "Documentación incorrecta",
            "Vehículo no autorizado",
            "Personal no identificado"
        ],
        "modulos_asignados": ["guias_despacho"],
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.empresas.insert_one(empresa)
    
    # Create demo users
    users = [
        {"email": "admin@demo.com", "nombre": "Administrador Demo", "rol": "admin", "password": "admin123"},
        {"email": "solicitante@demo.com", "nombre": "Juan Solicitante", "rol": "solicitante", "password": "solicitante123"},
        {"email": "gerente@demo.com", "nombre": "María Gerente", "rol": "gerente", "password": "gerente123"},
        {"email": "seguridad@demo.com", "nombre": "Pedro Seguridad", "rol": "seguridad", "password": "seguridad123"},
    ]
    
    for u in users:
        user_id = str(uuid.uuid4())
        user = {
            "id": user_id,
            "email": u["email"],
            "nombre": u["nombre"],
            "rol": u["rol"],
            "empresa_id": empresa_id,
            "password_hash": hash_password(u["password"]),
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.usuarios.insert_one(user)
    
    # Create demo vehicles
    vehiculos = [
        {"patente": "ABCD12", "marca": "Volvo", "modelo": "FH16"},
        {"patente": "WXYZ98", "marca": "Mercedes", "modelo": "Actros"},
        {"patente": "JKLM45", "marca": "Scania", "modelo": "R500"},
    ]
    for v in vehiculos:
        await db.vehiculos.insert_one({
            "id": str(uuid.uuid4()),
            **v,
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        })
    
    # Create demo entities
    entidades = [
        {"rut": "96.000.000-0", "razon_social": "Codelco Chile"},
        {"rut": "91.000.000-6", "razon_social": "ENAP Refinería"},
        {"rut": "76.000.000-1", "razon_social": "Minera Escondida"},
    ]
    for e in entidades:
        await db.entidades.insert_one({
            "id": str(uuid.uuid4()),
            **e,
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        })
    
    return {
        "message": "Datos de demo creados",
        "empresa_id": empresa_id,
        "superadmin": {"email": "superadmin@multisistemas.cl", "password": "superadmin123"},
        "usuarios": [
            {"email": "admin@demo.com", "password": "admin123", "rol": "admin"},
            {"email": "solicitante@demo.com", "password": "solicitante123", "rol": "solicitante"},
            {"email": "gerente@demo.com", "password": "gerente123", "rol": "gerente"},
            {"email": "seguridad@demo.com", "password": "seguridad123", "rol": "seguridad"},
        ]
    }

# ==================== BOMBEROS MODULE ROUTES ====================

# Helper para calcular días hasta vencimiento
def dias_hasta_vencimiento(fecha_str: str) -> int:
    if not fecha_str:
        return -1
    try:
        fecha = datetime.fromisoformat(fecha_str.replace('Z', '+00:00'))
        delta = fecha - datetime.now(timezone.utc)
        return delta.days
    except:
        return -1

# --- COMPAÑÍAS DE BOMBEROS ---

@api_router.post("/bomberos/companias", response_model=CompaniaBomberosResponse)
async def create_compania_bomberos(data: CompaniaBomberosBase, user: dict = Depends(require_roles("admin"))):
    """Crear una compañía de bomberos"""
    compania_id = str(uuid.uuid4())
    compania = {
        "id": compania_id,
        **data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_companias.insert_one(compania)
    return CompaniaBomberosResponse(**compania, total_bomberos=0, total_vehiculos=0)

@api_router.get("/bomberos/companias", response_model=List[CompaniaBomberosResponse])
async def get_companias_bomberos(user: dict = Depends(get_current_user)):
    """Obtener todas las compañías de bomberos"""
    query = {}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    
    companias = await db.bomberos_companias.find(query, {"_id": 0}).to_list(100)
    
    # Enrich with counts
    result = []
    for c in companias:
        total_bomberos = await db.bomberos_personal.count_documents({"compania_id": c["id"], "activo": True})
        total_vehiculos = await db.bomberos_material_mayor.count_documents({"compania_id": c["id"], "activo": True})
        result.append(CompaniaBomberosResponse(**c, total_bomberos=total_bomberos, total_vehiculos=total_vehiculos))
    
    return result

@api_router.get("/bomberos/companias/{compania_id}", response_model=CompaniaBomberosResponse)
async def get_compania_bomberos(compania_id: str, user: dict = Depends(get_current_user)):
    """Obtener una compañía específica"""
    compania = await db.bomberos_companias.find_one({"id": compania_id}, {"_id": 0})
    if not compania:
        raise HTTPException(status_code=404, detail="Compañía no encontrada")
    
    total_bomberos = await db.bomberos_personal.count_documents({"compania_id": compania_id, "activo": True})
    total_vehiculos = await db.bomberos_material_mayor.count_documents({"compania_id": compania_id, "activo": True})
    
    return CompaniaBomberosResponse(**compania, total_bomberos=total_bomberos, total_vehiculos=total_vehiculos)

@api_router.put("/bomberos/companias/{compania_id}")
async def update_compania_bomberos(compania_id: str, data: dict, user: dict = Depends(require_roles("admin"))):
    """Actualizar compañía de bomberos"""
    data.pop("id", None)
    data.pop("created_at", None)
    result = await db.bomberos_companias.update_one({"id": compania_id}, {"$set": data})
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Compañía no encontrada")
    return {"message": "Compañía actualizada"}

@api_router.delete("/bomberos/companias/{compania_id}")
async def delete_compania_bomberos(compania_id: str, user: dict = Depends(require_roles("admin"))):
    """Eliminar/desactivar compañía de bomberos"""
    # Check if compania has associated personnel
    personal_count = await db.bomberos_personal.count_documents({"compania_id": compania_id, "activo": True})
    if personal_count > 0:
        raise HTTPException(
            status_code=400, 
            detail=f"No se puede eliminar. La compañía tiene {personal_count} bombero(s) activo(s)"
        )
    
    result = await db.bomberos_companias.update_one(
        {"id": compania_id}, 
        {"$set": {"activa": False, "deleted_at": datetime.now(timezone.utc).isoformat()}}
    )
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Compañía no encontrada")
    return {"message": "Compañía eliminada"}

# --- COMPETENCIAS ---

@api_router.post("/bomberos/competencias", response_model=CompetenciaResponse)
async def create_competencia(data: CompetenciaBase, user: dict = Depends(require_roles("admin"))):
    """Crear competencia/especialidad"""
    comp_id = str(uuid.uuid4())
    competencia = {
        "id": comp_id,
        **data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_competencias.insert_one(competencia)
    return competencia

@api_router.get("/bomberos/competencias", response_model=List[CompetenciaResponse])
async def get_competencias(user: dict = Depends(get_current_user)):
    """Obtener todas las competencias"""
    query = {"activa": True}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    
    competencias = await db.bomberos_competencias.find(query, {"_id": 0}).to_list(100)
    return competencias

# --- BOMBEROS (PERSONAL) ---

@api_router.post("/bomberos/personal", response_model=BomberoResponse)
async def create_bombero(data: BomberoBase, user: dict = Depends(require_roles("admin"))):
    """Crear un bombero"""
    bombero_id = str(uuid.uuid4())
    bombero = {
        "id": bombero_id,
        **data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_personal.insert_one(bombero)
    
    # Get compania name
    compania = await db.bomberos_companias.find_one({"id": data.compania_id}, {"_id": 0})
    nombre_completo = f"{data.nombres} {data.apellido_paterno} {data.apellido_materno}"
    
    return BomberoResponse(
        **bombero,
        nombre_completo=nombre_completo,
        compania_nombre=compania["nombre"] if compania else None,
        competencias=[],
        epp_asignado=[]
    )

# --- IMPORTACION MASIVA DE DATOS ---

class ImportacionBomberoData(BaseModel):
    """Modelo flexible para importación masiva de bomberos"""
    rut: str
    nombre_completo: Optional[str] = None  # Can be parsed to nombres/apellidos
    nombres: Optional[str] = None
    apellido_paterno: Optional[str] = None
    apellido_materno: Optional[str] = None
    fecha_nacimiento: Optional[str] = None
    fecha_ingreso: Optional[str] = None
    grado: Optional[str] = "voluntario"
    cargo: Optional[str] = None
    compania_id: str
    email: Optional[str] = None
    telefono: Optional[str] = None
    direccion: Optional[str] = None
    grupo_sanguineo: Optional[str] = None
    activo: bool = True

class ImportacionEPPData(BaseModel):
    """Modelo flexible para importación masiva de EPP"""
    codigo: Optional[str] = None
    tipo: str
    marca: str
    modelo: Optional[str] = None
    numero_serie: Optional[str] = None
    talla: Optional[str] = None
    fecha_adquisicion: Optional[str] = None
    fecha_vencimiento: Optional[str] = None
    estado: str = "disponible"
    compania_id: str
    activo: bool = True

class ImportacionRequest(BaseModel):
    tipo: str  # "personal" or "epp"
    registros: List[Dict[str, Any]]
    compania_id: str

class ImportacionResponse(BaseModel):
    success: int
    failed: int
    errors: List[str]
    ids_creados: List[str]

@api_router.post("/bomberos/importacion", response_model=ImportacionResponse)
async def importar_datos_masivos(data: ImportacionRequest, user: dict = Depends(require_roles("admin"))):
    """Importar datos masivamente para el módulo de bomberos"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Verify compania exists
    compania = await db.bomberos_companias.find_one({"id": data.compania_id, "empresa_id": empresa_id}, {"_id": 0})
    if not compania:
        raise HTTPException(status_code=404, detail="Compañía no encontrada")
    
    success = 0
    failed = 0
    errors = []
    ids_creados = []
    
    for idx, registro in enumerate(data.registros):
        try:
            if data.tipo == "personal":
                # Parse nombre_completo if provided
                if registro.get("nombre_completo") and not registro.get("nombres"):
                    partes = registro["nombre_completo"].strip().split()
                    if len(partes) >= 3:
                        registro["nombres"] = " ".join(partes[:-2])
                        registro["apellido_paterno"] = partes[-2]
                        registro["apellido_materno"] = partes[-1]
                    elif len(partes) == 2:
                        registro["nombres"] = partes[0]
                        registro["apellido_paterno"] = partes[1]
                        registro["apellido_materno"] = ""
                    else:
                        registro["nombres"] = registro["nombre_completo"]
                        registro["apellido_paterno"] = ""
                        registro["apellido_materno"] = ""
                
                # Validate required fields
                if not registro.get("rut"):
                    errors.append(f"Fila {idx+1}: RUT es requerido")
                    failed += 1
                    continue
                if not registro.get("nombres"):
                    errors.append(f"Fila {idx+1}: Nombre es requerido")
                    failed += 1
                    continue
                
                # Check for duplicate RUT
                existing = await db.bomberos_personal.find_one({
                    "rut": registro["rut"],
                    "empresa_id": empresa_id
                })
                if existing:
                    errors.append(f"Fila {idx+1}: RUT {registro['rut']} ya existe")
                    failed += 1
                    continue
                
                # Create bombero
                bombero_id = str(uuid.uuid4())
                bombero = {
                    "id": bombero_id,
                    "rut": registro["rut"],
                    "nombres": registro.get("nombres", ""),
                    "apellido_paterno": registro.get("apellido_paterno", ""),
                    "apellido_materno": registro.get("apellido_materno", ""),
                    "fecha_nacimiento": registro.get("fecha_nacimiento"),
                    "fecha_ingreso": registro.get("fecha_ingreso", datetime.now().strftime("%Y-%m-%d")),
                    "grado": registro.get("grado", "voluntario"),
                    "cargo": registro.get("cargo"),
                    "compania_id": data.compania_id,
                    "email": registro.get("email"),
                    "telefono": registro.get("telefono"),
                    "direccion": registro.get("direccion"),
                    "grupo_sanguineo": registro.get("grupo_sanguineo"),
                    "activo": registro.get("activo", True),
                    "empresa_id": empresa_id,
                    "created_at": datetime.now(timezone.utc).isoformat()
                }
                await db.bomberos_personal.insert_one(bombero)
                ids_creados.append(bombero_id)
                success += 1
                
            elif data.tipo == "epp":
                # Validate required fields
                if not registro.get("tipo"):
                    errors.append(f"Fila {idx+1}: Tipo de EPP es requerido")
                    failed += 1
                    continue
                if not registro.get("marca"):
                    errors.append(f"Fila {idx+1}: Marca es requerida")
                    failed += 1
                    continue
                
                # Generate codigo if not provided
                codigo = registro.get("codigo")
                if not codigo:
                    # Count existing EPP to generate next code
                    count = await db.bomberos_material_menor.count_documents({"empresa_id": empresa_id})
                    codigo = f"EPP-{str(count + 1).zfill(4)}"
                
                # Create EPP
                epp_id = str(uuid.uuid4())
                epp = {
                    "id": epp_id,
                    "codigo": codigo,
                    "tipo": registro["tipo"],
                    "marca": registro["marca"],
                    "modelo": registro.get("modelo"),
                    "numero_serie": registro.get("numero_serie"),
                    "talla": registro.get("talla"),
                    "fecha_adquisicion": registro.get("fecha_adquisicion"),
                    "fecha_vencimiento": registro.get("fecha_vencimiento"),
                    "estado": registro.get("estado", "disponible"),
                    "compania_id": data.compania_id,
                    "activo": registro.get("activo", True),
                    "empresa_id": empresa_id,
                    "created_at": datetime.now(timezone.utc).isoformat()
                }
                await db.bomberos_material_menor.insert_one(epp)
                ids_creados.append(epp_id)
                success += 1
            else:
                raise HTTPException(status_code=400, detail=f"Tipo de importación no válido: {data.tipo}")
                
        except Exception as e:
            errors.append(f"Fila {idx+1}: {str(e)}")
            failed += 1
    
    return ImportacionResponse(
        success=success,
        failed=failed,
        errors=errors[:20],  # Limit errors to 20
        ids_creados=ids_creados
    )

@api_router.get("/bomberos/personal", response_model=List[BomberoResponse])
async def get_bomberos(
    compania_id: str = Query(None),
    activo: bool = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener listado de bomberos"""
    query = {}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    if compania_id:
        query["compania_id"] = compania_id
    if activo is not None:
        query["activo"] = activo
    
    bomberos = await db.bomberos_personal.find(query, {"_id": 0}).to_list(1000)
    
    # Get companias for names
    compania_ids = list(set(b.get("compania_id") for b in bomberos if b.get("compania_id")))
    companias = await db.bomberos_companias.find({"id": {"$in": compania_ids}}, {"_id": 0}).to_list(100)
    compania_map = {c["id"]: c["nombre"] for c in companias}
    
    result = []
    for b in bomberos:
        nombre_completo = f"{b['nombres']} {b['apellido_paterno']} {b.get('apellido_materno', '')}"
        result.append(BomberoResponse(
            **b,
            nombre_completo=nombre_completo.strip(),
            compania_nombre=compania_map.get(b.get("compania_id")),
            competencias=[],
            epp_asignado=[]
        ))
    
    return result

@api_router.get("/bomberos/personal/{bombero_id}", response_model=BomberoResponse)
async def get_bombero(bombero_id: str, user: dict = Depends(get_current_user)):
    """Obtener un bombero con todos sus datos"""
    bombero = await db.bomberos_personal.find_one({"id": bombero_id}, {"_id": 0})
    if not bombero:
        raise HTTPException(status_code=404, detail="Bombero no encontrado")
    
    # Get compania
    compania = await db.bomberos_companias.find_one({"id": bombero.get("compania_id")}, {"_id": 0})
    
    # Get competencias del bombero
    competencias = await db.bomberos_bombero_competencias.find(
        {"bombero_id": bombero_id}, {"_id": 0}
    ).to_list(100)
    
    # Get EPP asignado
    epp = await db.bomberos_material_menor.find(
        {"bombero_asignado_id": bombero_id, "estado": "asignado"}, {"_id": 0}
    ).to_list(100)
    
    nombre_completo = f"{bombero['nombres']} {bombero['apellido_paterno']} {bombero.get('apellido_materno', '')}"
    
    return BomberoResponse(
        **bombero,
        nombre_completo=nombre_completo.strip(),
        compania_nombre=compania["nombre"] if compania else None,
        competencias=competencias,
        epp_asignado=epp
    )

@api_router.put("/bomberos/personal/{bombero_id}")
async def update_bombero(bombero_id: str, data: dict, user: dict = Depends(require_roles("admin"))):
    """Actualizar datos de un bombero"""
    existing = await db.bomberos_personal.find_one({"id": bombero_id})
    if not existing:
        raise HTTPException(status_code=404, detail="Bombero no encontrado")
    
    data.pop("id", None)
    data.pop("created_at", None)
    await db.bomberos_personal.update_one({"id": bombero_id}, {"$set": data})
    return {"message": "Bombero actualizado"}

@api_router.delete("/bomberos/personal/{bombero_id}")
async def delete_bombero(bombero_id: str, user: dict = Depends(require_roles("admin"))):
    """Eliminar un bombero (soft delete)"""
    result = await db.bomberos_personal.update_one(
        {"id": bombero_id}, 
        {"$set": {"activo": False, "deleted_at": datetime.now(timezone.utc).isoformat()}}
    )
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Bombero no encontrado")
    return {"message": "Bombero eliminado"}

# --- CAPACITACIONES ---

@api_router.post("/bomberos/capacitaciones", response_model=CapacitacionResponse)
async def create_capacitacion(data: CapacitacionBase, user: dict = Depends(require_roles("admin"))):
    """Crear una capacitación"""
    cap_id = str(uuid.uuid4())
    
    # Asignar empresa_id del usuario si no viene en la data
    empresa_id = data.empresa_id or user.get("empresa_id")
    
    capacitacion = {
        "id": cap_id,
        **data.model_dump(),
        "empresa_id": empresa_id,
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_capacitaciones.insert_one(capacitacion)
    
    # Get competencia name if exists
    competencia_nombre = None
    if data.competencia_id:
        comp = await db.bomberos_competencias.find_one({"id": data.competencia_id}, {"_id": 0})
        competencia_nombre = comp["nombre"] if comp else None
    
    return CapacitacionResponse(**capacitacion, competencia_nombre=competencia_nombre, total_inscritos=0, total_aprobados=0)

@api_router.get("/bomberos/capacitaciones", response_model=List[CapacitacionResponse])
async def get_capacitaciones(
    estado: str = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener listado de capacitaciones"""
    query = {}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    if estado:
        query["estado"] = estado
    
    capacitaciones = await db.bomberos_capacitaciones.find(query, {"_id": 0}).sort("fecha_inicio", -1).to_list(500)
    
    result = []
    for cap in capacitaciones:
        # Get counts - usar lista de inscritos del documento
        inscritos = cap.get("inscritos", [])
        total_inscritos = len(inscritos)
        total_aprobados = await db.bomberos_evaluaciones.count_documents({"capacitacion_id": cap["id"], "resultado": "aprobado"})
        
        # Get competencia name
        competencia_nombre = None
        if cap.get("competencia_id"):
            comp = await db.bomberos_competencias.find_one({"id": cap["competencia_id"]}, {"_id": 0})
            competencia_nombre = comp["nombre"] if comp else None
        
        result.append(CapacitacionResponse(
            **cap,
            competencia_nombre=competencia_nombre,
            total_inscritos=total_inscritos,
            total_aprobados=total_aprobados
        ))
    
    return result

@api_router.get("/bomberos/capacitaciones/{cap_id}", response_model=CapacitacionResponse)
async def get_capacitacion(cap_id: str, user: dict = Depends(get_current_user)):
    """Obtener una capacitación"""
    cap = await db.bomberos_capacitaciones.find_one({"id": cap_id}, {"_id": 0})
    if not cap:
        raise HTTPException(status_code=404, detail="Capacitación no encontrada")
    
    total_inscritos = await db.bomberos_asistencias.count_documents({"capacitacion_id": cap_id})
    total_aprobados = await db.bomberos_evaluaciones.count_documents({"capacitacion_id": cap_id, "resultado": "aprobado"})
    
    competencia_nombre = None
    if cap.get("competencia_id"):
        comp = await db.bomberos_competencias.find_one({"id": cap["competencia_id"]}, {"_id": 0})
        competencia_nombre = comp["nombre"] if comp else None
    
    return CapacitacionResponse(**cap, competencia_nombre=competencia_nombre, total_inscritos=total_inscritos, total_aprobados=total_aprobados)

@api_router.put("/bomberos/capacitaciones/{cap_id}")
async def update_capacitacion(cap_id: str, data: dict, user: dict = Depends(require_roles("admin"))):
    """Actualizar capacitación"""
    # Verificar que existe primero
    existing = await db.bomberos_capacitaciones.find_one({"id": cap_id})
    if not existing:
        raise HTTPException(status_code=404, detail="Capacitación no encontrada")
    
    data.pop("id", None)
    data.pop("created_at", None)
    await db.bomberos_capacitaciones.update_one({"id": cap_id}, {"$set": data})
    return {"message": "Capacitación actualizada"}

@api_router.delete("/bomberos/capacitaciones/{cap_id}")
async def delete_capacitacion(cap_id: str, user: dict = Depends(require_roles("admin"))):
    """Eliminar una capacitación"""
    result = await db.bomberos_capacitaciones.update_one(
        {"id": cap_id}, 
        {"$set": {"estado": "cancelada", "deleted_at": datetime.now(timezone.utc).isoformat()}}
    )
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Capacitación no encontrada")
    return {"message": "Capacitación eliminada"}

# --- ASISTENCIA A CAPACITACIONES ---

@api_router.post("/bomberos/asistencias")
async def registrar_asistencia(data: AsistenciaCapacitacionBase, user: dict = Depends(require_roles("admin"))):
    """Registrar asistencia a una capacitación"""
    asist_id = str(uuid.uuid4())
    asistencia = {
        "id": asist_id,
        **data.model_dump(),
        "registrado_por": user["id"],
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_asistencias.insert_one(asistencia)
    return {"id": asist_id, "message": "Asistencia registrada"}

@api_router.get("/bomberos/asistencias/{capacitacion_id}")
async def get_asistencias_capacitacion(capacitacion_id: str, user: dict = Depends(get_current_user)):
    """Obtener asistencias de una capacitación"""
    asistencias = await db.bomberos_asistencias.find(
        {"capacitacion_id": capacitacion_id}, {"_id": 0}
    ).to_list(500)
    
    # Enrich with bombero names
    bombero_ids = list(set(a["bombero_id"] for a in asistencias))
    bomberos = await db.bomberos_personal.find({"id": {"$in": bombero_ids}}, {"_id": 0}).to_list(500)
    bombero_map = {b["id"]: f"{b['nombres']} {b['apellido_paterno']}" for b in bomberos}
    
    for a in asistencias:
        a["bombero_nombre"] = bombero_map.get(a["bombero_id"], "Desconocido")
    
    return asistencias

@api_router.post("/bomberos/asistencias/upload-documento")
async def upload_documento_asistencia(
    file: UploadFile = File(...),
    capacitacion_id: str = Query(...),
    fecha: str = Query(...),
    user: dict = Depends(require_roles("admin"))
):
    """Subir documento de respaldo de asistencia (imagen o PDF)"""
    import os
    
    # Validar tipo de archivo
    allowed_types = ["image/jpeg", "image/png", "image/webp", "application/pdf"]
    if file.content_type not in allowed_types:
        raise HTTPException(status_code=400, detail="Tipo de archivo no permitido. Use JPG, PNG, WebP o PDF")
    
    # Crear directorio si no existe
    upload_dir = "/app/backend/uploads/asistencias"
    os.makedirs(upload_dir, exist_ok=True)
    
    # Generar nombre único
    extension = file.filename.split(".")[-1] if "." in file.filename else "pdf"
    filename = f"asist_{capacitacion_id}_{fecha}_{uuid.uuid4().hex[:8]}.{extension}"
    filepath = os.path.join(upload_dir, filename)
    
    # Guardar archivo
    content = await file.read()
    with open(filepath, "wb") as f:
        f.write(content)
    
    # Guardar referencia en la base de datos
    doc_id = str(uuid.uuid4())
    documento = {
        "id": doc_id,
        "capacitacion_id": capacitacion_id,
        "fecha": fecha,
        "filename": filename,
        "original_name": file.filename,
        "content_type": file.content_type,
        "size": len(content),
        "uploaded_by": user["id"],
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_asistencias_documentos.insert_one(documento)
    
    # URL relativa para acceder al archivo
    url = f"/api/bomberos/asistencias/documento/{doc_id}"
    
    return {"id": doc_id, "url": url, "filename": filename, "message": "Documento subido correctamente"}

@api_router.get("/bomberos/asistencias/documento/{doc_id}")
async def get_documento_asistencia(doc_id: str):
    """Obtener documento de respaldo de asistencia"""
    from fastapi.responses import FileResponse
    import os
    
    doc = await db.bomberos_asistencias_documentos.find_one({"id": doc_id}, {"_id": 0})
    if not doc:
        raise HTTPException(status_code=404, detail="Documento no encontrado")
    
    filepath = f"/app/backend/uploads/asistencias/{doc['filename']}"
    if not os.path.exists(filepath):
        raise HTTPException(status_code=404, detail="Archivo no encontrado")
    
    return FileResponse(filepath, media_type=doc["content_type"], filename=doc["original_name"])

@api_router.get("/bomberos/asistencias/documentos/{capacitacion_id}/{fecha}")
async def get_documentos_por_fecha(capacitacion_id: str, fecha: str, user: dict = Depends(get_current_user)):
    """Obtener documentos de respaldo para una fecha específica"""
    documentos = await db.bomberos_asistencias_documentos.find(
        {"capacitacion_id": capacitacion_id, "fecha": fecha}, {"_id": 0}
    ).to_list(50)
    return documentos

# --- EVALUACIONES ---

@api_router.post("/bomberos/evaluaciones")
async def registrar_evaluacion(data: EvaluacionCapacitacionBase, user: dict = Depends(require_roles("admin"))):
    """Registrar evaluación de capacitación"""
    eval_id = str(uuid.uuid4())
    evaluacion = {
        "id": eval_id,
        **data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_evaluaciones.insert_one(evaluacion)
    
    # Si aprobó, actualizar competencia del bombero si corresponde
    if data.resultado == "aprobado":
        cap = await db.bomberos_capacitaciones.find_one({"id": data.capacitacion_id}, {"_id": 0})
        if cap and cap.get("competencia_id"):
            # Registrar competencia al bombero
            await db.bomberos_bombero_competencias.update_one(
                {"bombero_id": data.bombero_id, "competencia_id": cap["competencia_id"]},
                {"$set": {
                    "fecha_obtencion": data.fecha_evaluacion,
                    "capacitacion_id": data.capacitacion_id,
                    "vigente": True,
                    "updated_at": datetime.now(timezone.utc).isoformat()
                }},
                upsert=True
            )
    
    return {"id": eval_id, "message": "Evaluación registrada"}

@api_router.get("/bomberos/evaluaciones/{capacitacion_id}")
async def get_evaluaciones_capacitacion(capacitacion_id: str, user: dict = Depends(get_current_user)):
    """Obtener evaluaciones de una capacitación"""
    evaluaciones = await db.bomberos_evaluaciones.find(
        {"capacitacion_id": capacitacion_id}, {"_id": 0}
    ).to_list(500)
    
    # Enrich with names
    bombero_ids = list(set(e["bombero_id"] for e in evaluaciones))
    bomberos = await db.bomberos_personal.find({"id": {"$in": bombero_ids}}, {"_id": 0}).to_list(500)
    bombero_map = {b["id"]: f"{b['nombres']} {b['apellido_paterno']}" for b in bomberos}
    
    for e in evaluaciones:
        e["bombero_nombre"] = bombero_map.get(e["bombero_id"], "Desconocido")
    
    return evaluaciones

# --- CERTIFICADOS PDF ---

from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import Paragraph
from io import BytesIO
from fastapi.responses import StreamingResponse

@api_router.get("/bomberos/certificado/{capacitacion_id}/{bombero_id}")
async def generar_certificado(capacitacion_id: str, bombero_id: str, user: dict = Depends(get_current_user)):
    """Generar certificado PDF para un bombero aprobado"""
    
    # Verificar que el bombero aprobó la capacitación
    evaluacion = await db.bomberos_evaluaciones.find_one({
        "capacitacion_id": capacitacion_id,
        "bombero_id": bombero_id,
        "resultado": "aprobado"
    }, {"_id": 0})
    
    if not evaluacion:
        raise HTTPException(status_code=404, detail="El bombero no tiene evaluación aprobada en esta capacitación")
    
    # Obtener datos
    bombero = await db.bomberos_personal.find_one({"id": bombero_id}, {"_id": 0})
    capacitacion = await db.bomberos_capacitaciones.find_one({"id": capacitacion_id}, {"_id": 0})
    
    if not bombero or not capacitacion:
        raise HTTPException(status_code=404, detail="Datos no encontrados")
    
    # Crear PDF
    buffer = BytesIO()
    c = canvas.Canvas(buffer, pagesize=landscape(A4))
    width, height = landscape(A4)
    
    # Colores
    color_rojo = colors.Color(0.8, 0.1, 0.1)
    color_dorado = colors.Color(0.85, 0.65, 0.1)
    
    # Borde decorativo
    c.setStrokeColor(color_dorado)
    c.setLineWidth(3)
    c.rect(20, 20, width - 40, height - 40)
    c.setLineWidth(1)
    c.rect(30, 30, width - 60, height - 60)
    
    # Título
    c.setFont("Helvetica-Bold", 40)
    c.setFillColor(color_rojo)
    c.drawCentredString(width/2, height - 100, "CERTIFICADO")
    
    # Subtítulo
    c.setFont("Helvetica", 18)
    c.setFillColor(colors.black)
    c.drawCentredString(width/2, height - 140, "Cuerpo de Bomberos de Chile")
    
    # Texto principal
    c.setFont("Helvetica", 14)
    c.drawCentredString(width/2, height - 200, "Se certifica que")
    
    # Nombre del bombero
    c.setFont("Helvetica-Bold", 28)
    c.setFillColor(color_rojo)
    nombre_completo = bombero.get("nombre_completo", "")
    c.drawCentredString(width/2, height - 250, nombre_completo.upper())
    
    # RUT
    c.setFont("Helvetica", 12)
    c.setFillColor(colors.gray)
    c.drawCentredString(width/2, height - 275, f"RUT: {bombero.get('rut', 'N/A')}")
    
    # Texto de aprobación
    c.setFont("Helvetica", 14)
    c.setFillColor(colors.black)
    c.drawCentredString(width/2, height - 320, "ha completado satisfactoriamente el curso de")
    
    # Nombre del curso
    c.setFont("Helvetica-Bold", 22)
    c.setFillColor(colors.darkblue)
    c.drawCentredString(width/2, height - 360, capacitacion.get("nombre", ""))
    
    # Detalles del curso
    c.setFont("Helvetica", 12)
    c.setFillColor(colors.black)
    nivel = capacitacion.get("nivel_anb", "").upper()
    horas = capacitacion.get("horas_duracion", 0)
    c.drawCentredString(width/2, height - 395, f"Nivel: {nivel} | Duración: {horas} horas")
    
    # Fecha
    fecha_eval = evaluacion.get("fecha_evaluacion", "")
    c.drawCentredString(width/2, height - 430, f"Fecha de certificación: {fecha_eval}")
    
    # Nota si existe
    if evaluacion.get("nota"):
        c.setFont("Helvetica-Bold", 14)
        c.drawCentredString(width/2, height - 460, f"Calificación: {evaluacion.get('nota')}")
    
    # Línea de firma
    c.setStrokeColor(colors.black)
    c.line(width/2 - 120, 100, width/2 + 120, 100)
    c.setFont("Helvetica", 10)
    c.drawCentredString(width/2, 85, "Firma y Timbre del Director")
    
    # Código de certificado
    cert_code = f"CERT-{capacitacion_id[:8]}-{bombero_id[:8]}".upper()
    c.setFont("Helvetica", 8)
    c.setFillColor(colors.gray)
    c.drawString(40, 40, f"Código: {cert_code}")
    c.drawRightString(width - 40, 40, f"Generado: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M')}")
    
    c.save()
    buffer.seek(0)
    
    filename = f"certificado_{bombero.get('rut', 'NA')}_{capacitacion_id[:8]}.pdf"
    
    return StreamingResponse(
        buffer,
        media_type="application/pdf",
        headers={"Content-Disposition": f"attachment; filename={filename}"}
    )

@api_router.get("/bomberos/certificados-disponibles/{capacitacion_id}")
async def get_certificados_disponibles(capacitacion_id: str, user: dict = Depends(get_current_user)):
    """Obtener lista de bomberos que pueden recibir certificado (aprobados)"""
    
    evaluaciones = await db.bomberos_evaluaciones.find({
        "capacitacion_id": capacitacion_id,
        "resultado": "aprobado"
    }, {"_id": 0}).to_list(500)
    
    bombero_ids = [e["bombero_id"] for e in evaluaciones]
    bomberos = await db.bomberos_personal.find({"id": {"$in": bombero_ids}}, {"_id": 0}).to_list(500)
    
    bombero_map = {b["id"]: b for b in bomberos}
    
    result = []
    for e in evaluaciones:
        bombero = bombero_map.get(e["bombero_id"], {})
        result.append({
            "bombero_id": e["bombero_id"],
            "nombre": bombero.get("nombre_completo", "Desconocido"),
            "rut": bombero.get("rut", ""),
            "fecha_evaluacion": e.get("fecha_evaluacion", ""),
            "nota": e.get("nota"),
        })
    
    return result

# --- MATERIAL MAYOR ---

@api_router.post("/bomberos/material-mayor", response_model=MaterialMayorResponse)
async def create_material_mayor(data: MaterialMayorBase, user: dict = Depends(require_roles("admin"))):
    """Crear vehículo/material mayor"""
    mat_id = str(uuid.uuid4())
    material = {
        "id": mat_id,
        **data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_material_mayor.insert_one(material)
    
    compania = await db.bomberos_companias.find_one({"id": data.compania_id}, {"_id": 0})
    dias_revision = dias_hasta_vencimiento(data.fecha_revision_tecnica) if data.fecha_revision_tecnica else None
    
    alertas = []
    if dias_revision is not None and dias_revision < 30:
        alertas.append(f"Revisión técnica vence en {dias_revision} días")
    
    return MaterialMayorResponse(
        **material,
        compania_nombre=compania["nombre"] if compania else None,
        dias_para_revision=dias_revision,
        alertas=alertas
    )

@api_router.get("/bomberos/material-mayor", response_model=List[MaterialMayorResponse])
async def get_material_mayor(
    compania_id: str = Query(None),
    estado_operativo: str = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener listado de material mayor"""
    query = {"activo": True}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    if compania_id:
        query["compania_id"] = compania_id
    if estado_operativo:
        query["estado_operativo"] = estado_operativo
    
    materiales = await db.bomberos_material_mayor.find(query, {"_id": 0}).to_list(500)
    
    # Get compania names
    compania_ids = list(set(m.get("compania_id") for m in materiales if m.get("compania_id")))
    companias = await db.bomberos_companias.find({"id": {"$in": compania_ids}}, {"_id": 0}).to_list(100)
    compania_map = {c["id"]: c["nombre"] for c in companias}
    
    result = []
    for m in materiales:
        dias_revision = dias_hasta_vencimiento(m.get("fecha_revision_tecnica"))
        alertas = []
        if dias_revision >= 0 and dias_revision < 30:
            alertas.append(f"Revisión técnica vence en {dias_revision} días")
        if m.get("estado_operativo") == "mantenimiento":
            alertas.append("En mantenimiento")
        
        result.append(MaterialMayorResponse(
            **m,
            compania_nombre=compania_map.get(m.get("compania_id")),
            dias_para_revision=dias_revision if dias_revision >= 0 else None,
            alertas=alertas
        ))
    
    return result

@api_router.get("/bomberos/material-mayor/{material_id}", response_model=MaterialMayorResponse)
async def get_material_mayor_detalle(material_id: str, user: dict = Depends(get_current_user)):
    """Obtener detalle de material mayor"""
    material = await db.bomberos_material_mayor.find_one({"id": material_id}, {"_id": 0})
    if not material:
        raise HTTPException(status_code=404, detail="Material no encontrado")
    
    compania = await db.bomberos_companias.find_one({"id": material.get("compania_id")}, {"_id": 0})
    dias_revision = dias_hasta_vencimiento(material.get("fecha_revision_tecnica"))
    
    alertas = []
    if dias_revision >= 0 and dias_revision < 30:
        alertas.append(f"Revisión técnica vence en {dias_revision} días")
    
    return MaterialMayorResponse(
        **material,
        compania_nombre=compania["nombre"] if compania else None,
        dias_para_revision=dias_revision if dias_revision >= 0 else None,
        alertas=alertas
    )

@api_router.put("/bomberos/material-mayor/{material_id}")
async def update_material_mayor(material_id: str, data: dict, user: dict = Depends(require_roles("admin"))):
    """Actualizar material mayor"""
    existing = await db.bomberos_material_mayor.find_one({"id": material_id})
    if not existing:
        raise HTTPException(status_code=404, detail="Material no encontrado")
    
    data.pop("id", None)
    data.pop("created_at", None)
    await db.bomberos_material_mayor.update_one({"id": material_id}, {"$set": data})
    return {"message": "Material actualizado"}

@api_router.delete("/bomberos/material-mayor/{material_id}")
async def delete_material_mayor(material_id: str, user: dict = Depends(require_roles("admin"))):
    """Eliminar material mayor (soft delete)"""
    result = await db.bomberos_material_mayor.update_one(
        {"id": material_id}, 
        {"$set": {"activo": False, "deleted_at": datetime.now(timezone.utc).isoformat()}}
    )
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Material no encontrado")
    return {"message": "Material eliminado"}

# --- CHECKLIST MATERIAL MAYOR ---

@api_router.post("/bomberos/checklists")
async def create_checklist(data: ChecklistMaterialMayorBase, user: dict = Depends(require_roles("admin", "seguridad"))):
    """Crear checklist de material mayor"""
    check_id = str(uuid.uuid4())
    checklist = {
        "id": check_id,
        **data.model_dump(),
        "responsable_id": user["id"],
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_checklists.insert_one(checklist)
    return {"id": check_id, "message": "Checklist registrado"}

@api_router.get("/bomberos/checklists/{material_id}")
async def get_checklists_material(material_id: str, user: dict = Depends(get_current_user)):
    """Obtener checklists de un material mayor"""
    checklists = await db.bomberos_checklists.find(
        {"material_mayor_id": material_id}, {"_id": 0}
    ).sort("fecha", -1).to_list(100)
    return checklists

# --- MATERIAL MENOR / EPP ---

@api_router.post("/bomberos/material-menor", response_model=MaterialMenorResponse)
async def create_material_menor(data: MaterialMenorBase, user: dict = Depends(require_roles("admin"))):
    """Crear material menor/EPP"""
    mat_id = str(uuid.uuid4())
    material = {
        "id": mat_id,
        **data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_material_menor.insert_one(material)
    
    return MaterialMenorResponse(**material, bombero_nombre=None, compania_nombre=None, dias_para_vencimiento=None)

@api_router.get("/bomberos/material-menor", response_model=List[MaterialMenorResponse])
async def get_material_menor(
    compania_id: str = Query(None),
    tipo: str = Query(None),
    estado: str = Query(None),
    bombero_id: str = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener listado de material menor/EPP"""
    query = {"activo": True}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    if compania_id:
        query["compania_id"] = compania_id
    if tipo:
        query["tipo"] = tipo
    if estado:
        query["estado"] = estado
    if bombero_id:
        query["bombero_asignado_id"] = bombero_id
    
    materiales = await db.bomberos_material_menor.find(query, {"_id": 0}).to_list(2000)
    
    # Get compania and bombero names
    compania_ids = list(set(m.get("compania_id") for m in materiales if m.get("compania_id")))
    bombero_ids = list(set(m.get("bombero_asignado_id") for m in materiales if m.get("bombero_asignado_id")))
    
    companias = await db.bomberos_companias.find({"id": {"$in": compania_ids}}, {"_id": 0}).to_list(100)
    bomberos = await db.bomberos_personal.find({"id": {"$in": bombero_ids}}, {"_id": 0}).to_list(500)
    
    compania_map = {c["id"]: c["nombre"] for c in companias}
    bombero_map = {b["id"]: f"{b['nombres']} {b['apellido_paterno']}" for b in bomberos}
    
    result = []
    for m in materiales:
        dias_venc = dias_hasta_vencimiento(m.get("fecha_vencimiento"))
        result.append(MaterialMenorResponse(
            **m,
            compania_nombre=compania_map.get(m.get("compania_id")),
            bombero_nombre=bombero_map.get(m.get("bombero_asignado_id")),
            dias_para_vencimiento=dias_venc if dias_venc >= 0 else None
        ))
    
    return result

@api_router.put("/bomberos/material-menor/{material_id}")
async def update_material_menor(material_id: str, data: dict, user: dict = Depends(require_roles("admin"))):
    """Actualizar material menor/EPP"""
    existing = await db.bomberos_material_menor.find_one({"id": material_id})
    if not existing:
        raise HTTPException(status_code=404, detail="Material no encontrado")
    
    data.pop("id", None)
    data.pop("created_at", None)
    await db.bomberos_material_menor.update_one({"id": material_id}, {"$set": data})
    return {"message": "Material actualizado"}

@api_router.delete("/bomberos/material-menor/{material_id}")
async def delete_material_menor(material_id: str, user: dict = Depends(require_roles("admin"))):
    """Eliminar material menor/EPP (soft delete) - Solo para bajas ya aprobadas"""
    # Verificar si el material existe
    material = await db.bomberos_material_menor.find_one({"id": material_id}, {"_id": 0})
    if not material:
        raise HTTPException(status_code=404, detail="Material no encontrado")
    
    # Si ya está en baja, permitir
    if material.get("estado") == "baja":
        return {"message": "Material ya está dado de baja"}
    
    # Verificar si hay una solicitud de baja aprobada
    solicitud_aprobada = await db.bomberos_solicitudes_baja_epp.find_one({
        "material_menor_id": material_id,
        "estado": "aprobada"
    }, {"_id": 0})
    
    if not solicitud_aprobada:
        raise HTTPException(
            status_code=400, 
            detail="Debe solicitar la baja del EPP y esperar su validación antes de eliminarlo"
        )
    
    # Proceder con la baja
    await db.bomberos_material_menor.update_one(
        {"id": material_id}, 
        {"$set": {"activo": False, "estado": "baja", "deleted_at": datetime.now(timezone.utc).isoformat()}}
    )
    return {"message": "Material dado de baja correctamente"}

# --- SOLICITUDES DE BAJA DE EPP ---

@api_router.post("/bomberos/solicitudes-baja-epp/upload-evidencia")
async def upload_evidencia_baja(
    file: UploadFile = File(...),
    user: dict = Depends(require_roles("admin"))
):
    """Subir documento de evidencia para baja de EPP (acta de baja)"""
    import os
    
    # Validar tipo de archivo
    allowed_types = ["image/jpeg", "image/png", "image/webp", "application/pdf"]
    if file.content_type not in allowed_types:
        raise HTTPException(status_code=400, detail="Tipo de archivo no permitido. Use JPG, PNG, WebP o PDF")
    
    # Crear directorio si no existe
    upload_dir = "/app/backend/uploads/bajas_epp"
    os.makedirs(upload_dir, exist_ok=True)
    
    # Generar nombre único
    extension = file.filename.split(".")[-1] if "." in file.filename else "pdf"
    filename = f"baja_epp_{uuid.uuid4().hex[:12]}.{extension}"
    filepath = os.path.join(upload_dir, filename)
    
    # Guardar archivo
    content = await file.read()
    with open(filepath, "wb") as f:
        f.write(content)
    
    # URL relativa para acceder al archivo
    url = f"/api/bomberos/solicitudes-baja-epp/evidencia/{filename}"
    
    return {"url": url, "filename": filename, "message": "Documento subido correctamente"}

@api_router.get("/bomberos/solicitudes-baja-epp/evidencia/{filename}")
async def get_evidencia_baja(filename: str):
    """Obtener documento de evidencia de baja"""
    from fastapi.responses import FileResponse
    import os
    
    filepath = f"/app/backend/uploads/bajas_epp/{filename}"
    if not os.path.exists(filepath):
        raise HTTPException(status_code=404, detail="Archivo no encontrado")
    
    extension = filename.split(".")[-1].lower()
    content_types = {"jpg": "image/jpeg", "jpeg": "image/jpeg", "png": "image/png", "webp": "image/webp", "pdf": "application/pdf"}
    content_type = content_types.get(extension, "application/octet-stream")
    
    return FileResponse(filepath, media_type=content_type, filename=filename)

@api_router.post("/bomberos/solicitudes-baja-epp", response_model=SolicitudBajaEPPResponse)
async def crear_solicitud_baja_epp(data: SolicitudBajaEPPCreate, user: dict = Depends(require_roles("admin"))):
    """Crear solicitud de baja de EPP"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Verificar que el material existe
    material = await db.bomberos_material_menor.find_one({"id": data.material_menor_id}, {"_id": 0})
    if not material:
        raise HTTPException(status_code=404, detail="Material no encontrado")
    
    # Verificar que no haya una solicitud pendiente
    solicitud_existente = await db.bomberos_solicitudes_baja_epp.find_one({
        "material_menor_id": data.material_menor_id,
        "estado": "pendiente"
    })
    if solicitud_existente:
        raise HTTPException(status_code=400, detail="Ya existe una solicitud de baja pendiente para este EPP")
    
    solicitud_id = str(uuid.uuid4())
    solicitud = {
        "id": solicitud_id,
        "material_menor_id": data.material_menor_id,
        "motivo": data.motivo,
        "documento_evidencia_url": data.documento_evidencia_url,
        "observaciones": data.observaciones,
        "estado": "pendiente",
        "solicitante_id": user["id"],
        "solicitante_nombre": user["nombre"],
        "material_codigo": material.get("codigo"),
        "material_tipo": material.get("tipo"),
        "empresa_id": empresa_id,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "validador_id": None,
        "validador_nombre": None,
        "fecha_validacion": None,
        "motivo_rechazo": None
    }
    
    await db.bomberos_solicitudes_baja_epp.insert_one(solicitud)
    
    # Actualizar estado del material a "pendiente_baja"
    await db.bomberos_material_menor.update_one(
        {"id": data.material_menor_id},
        {"$set": {"estado": "pendiente_baja"}}
    )
    
    return solicitud

@api_router.get("/bomberos/solicitudes-baja-epp")
async def get_solicitudes_baja_epp(
    estado: str = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener solicitudes de baja de EPP"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    query = {"empresa_id": empresa_id}
    if estado:
        query["estado"] = estado
    
    solicitudes = await db.bomberos_solicitudes_baja_epp.find(query, {"_id": 0}).sort("created_at", -1).to_list(500)
    return solicitudes

@api_router.post("/bomberos/solicitudes-baja-epp/{solicitud_id}/validar")
async def validar_solicitud_baja_epp(
    solicitud_id: str,
    data: dict,
    user: dict = Depends(get_current_user)
):
    """Aprobar o rechazar solicitud de baja de EPP - Requiere permiso validar_documentos"""
    # Verificar permiso
    permisos = await get_user_permissions(user["id"], user.get("empresa_id"))
    if "validar_documentos" not in permisos and user["rol"] not in ["admin", "superadmin"]:
        raise HTTPException(status_code=403, detail="No tiene permiso para validar documentos")
    
    solicitud = await db.bomberos_solicitudes_baja_epp.find_one({"id": solicitud_id}, {"_id": 0})
    if not solicitud:
        raise HTTPException(status_code=404, detail="Solicitud no encontrada")
    
    if solicitud["estado"] != "pendiente":
        raise HTTPException(status_code=400, detail="Esta solicitud ya fue procesada")
    
    accion = data.get("accion")  # "aprobar" o "rechazar"
    if accion not in ["aprobar", "rechazar"]:
        raise HTTPException(status_code=400, detail="Acción no válida. Use 'aprobar' o 'rechazar'")
    
    nuevo_estado = "aprobada" if accion == "aprobar" else "rechazada"
    update_data = {
        "estado": nuevo_estado,
        "validador_id": user["id"],
        "validador_nombre": user["nombre"],
        "fecha_validacion": datetime.now(timezone.utc).isoformat()
    }
    
    if accion == "rechazar":
        motivo_rechazo = data.get("motivo_rechazo", "")
        if not motivo_rechazo:
            raise HTTPException(status_code=400, detail="Debe indicar el motivo del rechazo")
        update_data["motivo_rechazo"] = motivo_rechazo
        # Revertir estado del material
        await db.bomberos_material_menor.update_one(
            {"id": solicitud["material_menor_id"]},
            {"$set": {"estado": "disponible"}}
        )
    else:
        # Aprobar: dar de baja el material
        await db.bomberos_material_menor.update_one(
            {"id": solicitud["material_menor_id"]},
            {"$set": {
                "activo": False, 
                "estado": "baja", 
                "deleted_at": datetime.now(timezone.utc).isoformat(),
                "motivo_baja": solicitud["motivo"]
            }}
        )
    
    await db.bomberos_solicitudes_baja_epp.update_one({"id": solicitud_id}, {"$set": update_data})
    
    return {"message": f"Solicitud {nuevo_estado} correctamente"}

# Helper function to get user permissions
async def get_user_permissions(user_id: str, empresa_id: str) -> List[str]:
    """Obtener permisos de un usuario"""
    user_role = await db.bomberos_usuarios_roles.find_one(
        {"usuario_id": user_id, "empresa_id": empresa_id, "activo": True}, 
        {"_id": 0}
    )
    if not user_role:
        return []
    
    rol = await db.bomberos_roles.find_one({"id": user_role["rol_bomberos_id"]}, {"_id": 0})
    if not rol:
        return []
    
    permisos = rol.get("permisos", {})
    return [k for k, v in permisos.items() if v]

# --- ASIGNACIÓN DE EPP ---

@api_router.post("/bomberos/asignacion-epp")
async def asignar_epp(data: AsignacionEPPBase, user: dict = Depends(require_roles("admin"))):
    """Asignar EPP a un bombero"""
    asig_id = str(uuid.uuid4())
    asignacion = {
        "id": asig_id,
        **data.model_dump(),
        "responsable_id": user["id"],
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_asignaciones_epp.insert_one(asignacion)
    
    # Update material menor status
    await db.bomberos_material_menor.update_one(
        {"id": data.material_menor_id},
        {"$set": {
            "estado": "asignado",
            "bombero_asignado_id": data.bombero_id,
            "fecha_asignacion": data.fecha_entrega
        }}
    )
    
    return {"id": asig_id, "message": "EPP asignado"}

@api_router.post("/bomberos/devolucion-epp/{material_id}")
async def devolver_epp(material_id: str, data: dict, user: dict = Depends(require_roles("admin"))):
    """Registrar devolución de EPP"""
    # Update material menor status
    await db.bomberos_material_menor.update_one(
        {"id": material_id},
        {"$set": {
            "estado": "disponible",
            "bombero_asignado_id": None,
            "fecha_asignacion": None
        }}
    )
    
    # Update last assignment record
    await db.bomberos_asignaciones_epp.update_one(
        {"material_menor_id": material_id, "fecha_devolucion": None},
        {"$set": {
            "fecha_devolucion": data.get("fecha_devolucion", datetime.now(timezone.utc).isoformat()),
            "estado_devolucion": data.get("estado_devolucion", "bueno"),
            "observacion_devolucion": data.get("observacion_devolucion")
        }}
    )
    
    return {"message": "Devolución registrada"}

# --- ACTAS DE ACTIVIDAD ---

@api_router.post("/bomberos/actas", response_model=ActaActividadResponse)
async def create_acta(data: ActaActividadBase, user: dict = Depends(require_roles("admin"))):
    """Crear acta de actividad/evaluación"""
    acta_id = str(uuid.uuid4())
    acta = {
        "id": acta_id,
        **data.model_dump(),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_actas.insert_one(acta)
    
    compania = await db.bomberos_companias.find_one({"id": data.compania_id}, {"_id": 0})
    
    return ActaActividadResponse(
        **acta,
        responsable_nombre=user["nombre"],
        compania_nombre=compania["nombre"] if compania else None,
        total_asistentes=len(data.asistentes)
    )

@api_router.get("/bomberos/actas", response_model=List[ActaActividadResponse])
async def get_actas(
    compania_id: str = Query(None),
    tipo: str = Query(None),
    fecha_desde: str = Query(None),
    fecha_hasta: str = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener listado de actas"""
    query = {}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    if compania_id:
        query["compania_id"] = compania_id
    if tipo:
        query["tipo"] = tipo
    if fecha_desde:
        query["fecha"] = {"$gte": fecha_desde}
    if fecha_hasta:
        if "fecha" in query:
            query["fecha"]["$lte"] = fecha_hasta
        else:
            query["fecha"] = {"$lte": fecha_hasta}
    
    actas = await db.bomberos_actas.find(query, {"_id": 0}).sort("fecha", -1).to_list(500)
    
    # Get names
    compania_ids = list(set(a.get("compania_id") for a in actas if a.get("compania_id")))
    responsable_ids = list(set(a.get("responsable_id") for a in actas if a.get("responsable_id")))
    
    companias = await db.bomberos_companias.find({"id": {"$in": compania_ids}}, {"_id": 0}).to_list(100)
    usuarios = await db.usuarios.find({"id": {"$in": responsable_ids}}, {"_id": 0, "password_hash": 0}).to_list(100)
    
    compania_map = {c["id"]: c["nombre"] for c in companias}
    usuario_map = {u["id"]: u["nombre"] for u in usuarios}
    
    result = []
    for a in actas:
        result.append(ActaActividadResponse(
            **a,
            responsable_nombre=usuario_map.get(a.get("responsable_id")),
            compania_nombre=compania_map.get(a.get("compania_id")),
            total_asistentes=len(a.get("asistentes", []))
        ))
    
    return result

@api_router.get("/bomberos/actas/{acta_id}", response_model=ActaActividadResponse)
async def get_acta(acta_id: str, user: dict = Depends(get_current_user)):
    """Obtener detalle de un acta"""
    acta = await db.bomberos_actas.find_one({"id": acta_id}, {"_id": 0})
    if not acta:
        raise HTTPException(status_code=404, detail="Acta no encontrada")
    
    compania = await db.bomberos_companias.find_one({"id": acta.get("compania_id")}, {"_id": 0})
    responsable = await db.usuarios.find_one({"id": acta.get("responsable_id")}, {"_id": 0, "password_hash": 0})
    
    return ActaActividadResponse(
        **acta,
        responsable_nombre=responsable["nombre"] if responsable else None,
        compania_nombre=compania["nombre"] if compania else None,
        total_asistentes=len(acta.get("asistentes", []))
    )

# --- KPIs ---

@api_router.get("/bomberos/kpis", response_model=KPIBomberosResponse)
async def get_kpis_bomberos(
    compania_id: str = Query(None),
    periodo: str = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener KPIs del módulo de bomberos"""
    empresa_id = user.get("empresa_id")
    if not empresa_id and user["rol"] != "superadmin":
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Base queries
    query_base = {}
    if empresa_id:
        query_base["empresa_id"] = empresa_id
    if compania_id:
        query_base["compania_id"] = compania_id
    
    # Calculate KPIs
    
    # Académico
    cursos_programados = await db.bomberos_capacitaciones.count_documents({**query_base, "estado": {"$in": ["programada", "en_curso", "finalizada"]}})
    cursos_realizados = await db.bomberos_capacitaciones.count_documents({**query_base, "estado": "finalizada"})
    porcentaje_academico = (cursos_realizados / cursos_programados * 100) if cursos_programados > 0 else 0
    
    # Operatividad Material Mayor
    material_mayor_total = await db.bomberos_material_mayor.count_documents({**query_base, "activo": True})
    material_mayor_operativo = await db.bomberos_material_mayor.count_documents({**query_base, "activo": True, "estado_operativo": "operativo"})
    porcentaje_operatividad_mayor = (material_mayor_operativo / material_mayor_total * 100) if material_mayor_total > 0 else 0
    
    # Operatividad Material Menor
    material_menor_total = await db.bomberos_material_menor.count_documents({**query_base, "activo": True})
    material_menor_disponible = await db.bomberos_material_menor.count_documents({**query_base, "activo": True, "estado": {"$in": ["disponible", "asignado"]}})
    porcentaje_operatividad_menor = (material_menor_disponible / material_menor_total * 100) if material_menor_total > 0 else 0
    
    # Asistencia promedio (de actas)
    pipeline = [
        {"$match": query_base},
        {"$project": {
            "total_asistentes": {"$size": "$asistentes"},
            "presentes": {
                "$size": {
                    "$filter": {
                        "input": "$asistentes",
                        "cond": {"$eq": ["$$this.presente", True]}
                    }
                }
            }
        }},
        {"$group": {
            "_id": None,
            "total_actividades": {"$sum": 1},
            "total_asistentes": {"$sum": "$total_asistentes"},
            "total_presentes": {"$sum": "$presentes"}
        }}
    ]
    asistencia_result = await db.bomberos_actas.aggregate(pipeline).to_list(1)
    
    actividades_totales = asistencia_result[0]["total_actividades"] if asistencia_result else 0
    promedio_asistencia = 0
    if asistencia_result and asistencia_result[0]["total_asistentes"] > 0:
        promedio_asistencia = (asistencia_result[0]["total_presentes"] / asistencia_result[0]["total_asistentes"]) * 100
    
    # Personal
    total_bomberos = await db.bomberos_personal.count_documents({**query_base})
    bomberos_activos = await db.bomberos_personal.count_documents({**query_base, "activo": True})
    
    # Bomberos con brechas (sin competencias básicas)
    bomberos_con_brechas = 0  # TODO: Implementar lógica de brechas según competencias requeridas
    
    # Get compania name if filtered
    compania_nombre = None
    if compania_id:
        compania = await db.bomberos_companias.find_one({"id": compania_id}, {"_id": 0})
        compania_nombre = compania["nombre"] if compania else None
    
    return KPIBomberosResponse(
        periodo=periodo or datetime.now().strftime("%Y"),
        compania_id=compania_id,
        compania_nombre=compania_nombre,
        cursos_programados=cursos_programados,
        cursos_realizados=cursos_realizados,
        porcentaje_academico=round(porcentaje_academico, 1),
        material_mayor_total=material_mayor_total,
        material_mayor_operativo=material_mayor_operativo,
        porcentaje_operatividad_mayor=round(porcentaje_operatividad_mayor, 1),
        material_menor_total=material_menor_total,
        material_menor_disponible=material_menor_disponible,
        porcentaje_operatividad_menor=round(porcentaje_operatividad_menor, 1),
        actividades_totales=actividades_totales,
        promedio_asistencia=round(promedio_asistencia, 1),
        total_bomberos=total_bomberos,
        bomberos_activos=bomberos_activos,
        bomberos_con_brechas=bomberos_con_brechas
    )

# --- ESTADÍSTICAS COMPARATIVAS ---

class EstadisticaCompaniaResponse(BaseModel):
    """Estadísticas por compañía para gráficos comparativos"""
    id: str
    nombre: str
    short: str
    total_bomberos: int = 0
    activos: int = 0
    capacitaciones: int = 0
    cap_finalizadas: int = 0
    cap_programadas: int = 0
    actas: int = 0
    porcentaje_asistencia: float = 0.0
    porcentaje_academico: float = 0.0
    porcentaje_operatividad_mayor: float = 0.0
    porcentaje_operatividad_menor: float = 0.0
    material_mayor_total: int = 0
    material_mayor_operativo: int = 0
    material_menor_total: int = 0
    material_menor_disponible: int = 0

class TendenciaResponse(BaseModel):
    """Datos de tendencia histórica"""
    mes: str
    asistencia: float = 0.0
    academico: float = 0.0
    operatividad: float = 0.0

@api_router.get("/bomberos/estadisticas/comparativas")
async def get_estadisticas_comparativas(
    periodo: str = Query("anual"),
    user: dict = Depends(get_current_user)
):
    """Obtener estadísticas comparativas de todas las compañías"""
    empresa_id = user.get("empresa_id")
    if not empresa_id and user["rol"] != "superadmin":
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Get all companias
    companias = await db.bomberos_companias.find(
        {"empresa_id": empresa_id, "activa": True}, {"_id": 0}
    ).to_list(100)
    
    # Get all data at once for efficiency
    all_bomberos = await db.bomberos_personal.find(
        {"empresa_id": empresa_id}, {"_id": 0}
    ).to_list(5000)
    
    all_capacitaciones = await db.bomberos_capacitaciones.find(
        {"empresa_id": empresa_id}, {"_id": 0}
    ).to_list(1000)
    
    all_actas = await db.bomberos_actas.find(
        {"empresa_id": empresa_id}, {"_id": 0}
    ).to_list(2000)
    
    all_material_mayor = await db.bomberos_material_mayor.find(
        {"empresa_id": empresa_id, "activo": True}, {"_id": 0}
    ).to_list(500)
    
    all_material_menor = await db.bomberos_material_menor.find(
        {"empresa_id": empresa_id, "activo": True}, {"_id": 0}
    ).to_list(2000)
    
    result = []
    
    for comp in companias:
        comp_id = comp["id"]
        
        # Filter data for this compania
        bomberos_comp = [b for b in all_bomberos if b.get("compania_id") == comp_id]
        bombero_ids = {b["id"] for b in bomberos_comp}
        
        # Capacitaciones where bomberos from this compania are enrolled
        caps_comp = []
        for cap in all_capacitaciones:
            inscritos = cap.get("inscritos", [])
            if any(inscrito in bombero_ids for inscrito in inscritos):
                caps_comp.append(cap)
        
        actas_comp = [a for a in all_actas if a.get("compania_id") == comp_id]
        material_mayor_comp = [m for m in all_material_mayor if m.get("compania_id") == comp_id]
        material_menor_comp = [m for m in all_material_menor if m.get("compania_id") == comp_id]
        
        # Calculate statistics
        total_bomberos = len(bomberos_comp)
        activos = len([b for b in bomberos_comp if b.get("activo", True)])
        
        # Capacitaciones
        cap_finalizadas = len([c for c in caps_comp if c.get("estado") == "finalizada"])
        cap_programadas = len([c for c in caps_comp if c.get("estado") == "programada"])
        total_caps = len(caps_comp)
        porcentaje_academico = (cap_finalizadas / total_caps * 100) if total_caps > 0 else 0
        
        # Asistencia from actas
        total_asistencias = 0
        total_posibles = 0
        for acta in actas_comp:
            asistentes = acta.get("asistentes", [])
            total_posibles += len(asistentes)
            total_asistencias += len([a for a in asistentes if a.get("presente", False)])
        porcentaje_asistencia = (total_asistencias / total_posibles * 100) if total_posibles > 0 else 0
        
        # Material Mayor operatividad
        material_mayor_total = len(material_mayor_comp)
        material_mayor_operativo = len([m for m in material_mayor_comp if m.get("estado_operativo") == "operativo"])
        porcentaje_operatividad_mayor = (material_mayor_operativo / material_mayor_total * 100) if material_mayor_total > 0 else 0
        
        # Material Menor operatividad
        material_menor_total = len(material_menor_comp)
        material_menor_disponible = len([m for m in material_menor_comp if m.get("estado") in ["disponible", "asignado"]])
        porcentaje_operatividad_menor = (material_menor_disponible / material_menor_total * 100) if material_menor_total > 0 else 0
        
        # Create short name
        short = comp["nombre"].replace("Compañía", "Cía").replace("Bomba ", "")[:20]
        
        result.append({
            "id": comp_id,
            "nombre": comp["nombre"],
            "short": short,
            "total_bomberos": total_bomberos,
            "activos": activos,
            "capacitaciones": total_caps,
            "cap_finalizadas": cap_finalizadas,
            "cap_programadas": cap_programadas,
            "actas": len(actas_comp),
            "porcentaje_asistencia": round(porcentaje_asistencia, 1),
            "porcentaje_academico": round(porcentaje_academico, 1),
            "porcentaje_operatividad_mayor": round(porcentaje_operatividad_mayor, 1),
            "porcentaje_operatividad_menor": round(porcentaje_operatividad_menor, 1),
            "material_mayor_total": material_mayor_total,
            "material_mayor_operativo": material_mayor_operativo,
            "material_menor_total": material_menor_total,
            "material_menor_disponible": material_menor_disponible,
        })
    
    return result

@api_router.get("/bomberos/estadisticas/tendencias")
async def get_estadisticas_tendencias(
    meses: int = Query(6, ge=1, le=12),
    user: dict = Depends(get_current_user)
):
    """Obtener tendencias históricas de KPIs por mes"""
    empresa_id = user.get("empresa_id")
    if not empresa_id and user["rol"] != "superadmin":
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    now = datetime.now(timezone.utc)
    result = []
    
    for i in range(meses - 1, -1, -1):
        # Calculate month boundaries
        fecha_ref = now - timedelta(days=i * 30)
        mes_inicio = fecha_ref.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        if fecha_ref.month == 12:
            mes_fin = fecha_ref.replace(year=fecha_ref.year + 1, month=1, day=1) - timedelta(seconds=1)
        else:
            mes_fin = fecha_ref.replace(month=fecha_ref.month + 1, day=1) - timedelta(seconds=1)
        
        # Calculate asistencia from actas in this period
        actas_mes = await db.bomberos_actas.find({
            "empresa_id": empresa_id,
            "fecha": {
                "$gte": mes_inicio.strftime("%Y-%m-%d"),
                "$lte": mes_fin.strftime("%Y-%m-%d")
            }
        }, {"_id": 0}).to_list(500)
        
        total_asistencias = 0
        total_posibles = 0
        for acta in actas_mes:
            asistentes = acta.get("asistentes", [])
            total_posibles += len(asistentes)
            total_asistencias += len([a for a in asistentes if a.get("presente", False)])
        asistencia = (total_asistencias / total_posibles * 100) if total_posibles > 0 else 0
        
        # Calculate academico from capacitaciones finalizadas in this period
        caps_finalizadas = await db.bomberos_capacitaciones.count_documents({
            "empresa_id": empresa_id,
            "estado": "finalizada",
            "fecha_fin": {
                "$gte": mes_inicio.strftime("%Y-%m-%d"),
                "$lte": mes_fin.strftime("%Y-%m-%d")
            }
        })
        caps_total = await db.bomberos_capacitaciones.count_documents({
            "empresa_id": empresa_id,
            "fecha_fin": {
                "$gte": mes_inicio.strftime("%Y-%m-%d"),
                "$lte": mes_fin.strftime("%Y-%m-%d")
            }
        })
        academico = (caps_finalizadas / caps_total * 100) if caps_total > 0 else 0
        
        # Calculate operatividad (material operativo vs total) - snapshot at end of month
        material_total = await db.bomberos_material_mayor.count_documents({
            "empresa_id": empresa_id,
            "activo": True
        })
        material_operativo = await db.bomberos_material_mayor.count_documents({
            "empresa_id": empresa_id,
            "activo": True,
            "estado_operativo": "operativo"
        })
        operatividad = (material_operativo / material_total * 100) if material_total > 0 else 0
        
        # Translate month names to Spanish
        meses_es = {
            "January": "Enero", "February": "Febrero", "March": "Marzo",
            "April": "Abril", "May": "Mayo", "June": "Junio",
            "July": "Julio", "August": "Agosto", "September": "Septiembre",
            "October": "Octubre", "November": "Noviembre", "December": "Diciembre"
        }
        mes_nombre_es = fecha_ref.strftime("%B")
        for en, es in meses_es.items():
            mes_nombre_es = mes_nombre_es.replace(en, es)
        
        result.append({
            "mes": mes_nombre_es,
            "asistencia": round(asistencia, 1),
            "academico": round(academico, 1),
            "operatividad": round(operatividad, 1),
        })
    
    return result

@api_router.get("/bomberos/estadisticas/resumen")
async def get_estadisticas_resumen(
    user: dict = Depends(get_current_user)
):
    """Obtener resumen general de estadísticas"""
    empresa_id = user.get("empresa_id")
    if not empresa_id and user["rol"] != "superadmin":
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Count totals
    total_companias = await db.bomberos_companias.count_documents({"empresa_id": empresa_id, "activa": True})
    total_bomberos = await db.bomberos_personal.count_documents({"empresa_id": empresa_id, "activo": True})
    total_capacitaciones = await db.bomberos_capacitaciones.count_documents({"empresa_id": empresa_id})
    total_actas = await db.bomberos_actas.count_documents({"empresa_id": empresa_id})
    
    # Calculate averages
    # Asistencia from all actas
    pipeline = [
        {"$match": {"empresa_id": empresa_id}},
        {"$project": {
            "total": {"$size": {"$ifNull": ["$asistentes", []]}},
            "presentes": {
                "$size": {
                    "$filter": {
                        "input": {"$ifNull": ["$asistentes", []]},
                        "cond": {"$eq": ["$$this.presente", True]}
                    }
                }
            }
        }},
        {"$group": {
            "_id": None,
            "total": {"$sum": "$total"},
            "presentes": {"$sum": "$presentes"}
        }}
    ]
    asistencia_result = await db.bomberos_actas.aggregate(pipeline).to_list(1)
    promedio_asistencia = 0
    if asistencia_result and asistencia_result[0]["total"] > 0:
        promedio_asistencia = round((asistencia_result[0]["presentes"] / asistencia_result[0]["total"]) * 100, 1)
    
    # Academico
    caps_finalizadas = await db.bomberos_capacitaciones.count_documents({"empresa_id": empresa_id, "estado": "finalizada"})
    promedio_academico = round((caps_finalizadas / total_capacitaciones * 100), 1) if total_capacitaciones > 0 else 0
    
    return {
        "total_companias": total_companias,
        "total_bomberos": total_bomberos,
        "total_capacitaciones": total_capacitaciones,
        "total_actas": total_actas,
        "promedio_asistencia": promedio_asistencia,
        "promedio_academico": promedio_academico
    }

# --- ALERTAS ---

@api_router.get("/bomberos/alertas")
async def get_alertas_bomberos(
    compania_id: str = Query(None),
    tipo: str = Query(None),
    resuelta: bool = Query(None),
    user: dict = Depends(get_current_user)
):
    """Obtener alertas del sistema"""
    query = {}
    if user.get("empresa_id") and user["rol"] != "superadmin":
        query["empresa_id"] = user["empresa_id"]
    if compania_id:
        query["compania_id"] = compania_id
    if tipo:
        query["tipo"] = tipo
    if resuelta is not None:
        query["resuelta"] = resuelta
    
    alertas = await db.bomberos_alertas.find(query, {"_id": 0}).sort("created_at", -1).to_list(200)
    return alertas

@api_router.put("/bomberos/alertas/{alerta_id}/resolver")
async def resolver_alerta(alerta_id: str, user: dict = Depends(require_roles("admin"))):
    """Marcar alerta como resuelta"""
    await db.bomberos_alertas.update_one(
        {"id": alerta_id},
        {"$set": {
            "resuelta": True,
            "fecha_resolucion": datetime.now(timezone.utc).isoformat(),
            "usuario_resolucion_id": user["id"]
        }}
    )
    return {"message": "Alerta resuelta"}

@api_router.post("/bomberos/alertas/generar")
async def generar_alertas_automaticas(user: dict = Depends(require_roles("admin"))):
    """Generar alertas automáticas basadas en vencimientos y brechas"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    alertas_generadas = 0
    now = datetime.now(timezone.utc)
    
    # 1. Alertas de Material Mayor - Documentación por vencer
    vehiculos = await db.bomberos_material_mayor.find(
        {"empresa_id": empresa_id, "activo": True}, {"_id": 0}
    ).to_list(500)
    
    for v in vehiculos:
        # Revisión técnica
        if v.get("fecha_revision_tecnica"):
            try:
                fecha = datetime.fromisoformat(v["fecha_revision_tecnica"].replace('Z', '+00:00'))
                dias = (fecha - now).days
                if 0 <= dias <= 30:
                    # Check if alert already exists
                    existing = await db.bomberos_alertas.find_one({
                        "entidad_id": v["id"],
                        "tipo": "documento_vencido",
                        "resuelta": False,
                        "titulo": {"$regex": "Revisión técnica"}
                    })
                    if not existing:
                        alerta_id = str(uuid.uuid4())
                        await db.bomberos_alertas.insert_one({
                            "id": alerta_id,
                            "tipo": "documento_vencido",
                            "prioridad": "alta" if dias <= 7 else "media",
                            "titulo": f"Revisión técnica por vencer - {v['codigo']}",
                            "mensaje": f"La revisión técnica del vehículo {v['codigo']} ({v['patente']}) vence en {dias} días",
                            "entidad_tipo": "material_mayor",
                            "entidad_id": v["id"],
                            "compania_id": v.get("compania_id"),
                            "leida": False,
                            "resuelta": False,
                            "empresa_id": empresa_id,
                            "created_at": now.isoformat()
                        })
                        alertas_generadas += 1
            except:
                pass
        
        # Permiso de circulación
        if v.get("fecha_permiso_circulacion"):
            try:
                fecha = datetime.fromisoformat(v["fecha_permiso_circulacion"].replace('Z', '+00:00'))
                dias = (fecha - now).days
                if 0 <= dias <= 30:
                    existing = await db.bomberos_alertas.find_one({
                        "entidad_id": v["id"],
                        "tipo": "documento_vencido",
                        "resuelta": False,
                        "titulo": {"$regex": "Permiso circulación"}
                    })
                    if not existing:
                        alerta_id = str(uuid.uuid4())
                        await db.bomberos_alertas.insert_one({
                            "id": alerta_id,
                            "tipo": "documento_vencido",
                            "prioridad": "alta" if dias <= 7 else "media",
                            "titulo": f"Permiso circulación por vencer - {v['codigo']}",
                            "mensaje": f"El permiso de circulación del vehículo {v['codigo']} vence en {dias} días",
                            "entidad_tipo": "material_mayor",
                            "entidad_id": v["id"],
                            "compania_id": v.get("compania_id"),
                            "leida": False,
                            "resuelta": False,
                            "empresa_id": empresa_id,
                            "created_at": now.isoformat()
                        })
                        alertas_generadas += 1
            except:
                pass
    
    # 2. Alertas de EPP - Por vencer
    epp_items = await db.bomberos_material_menor.find(
        {"empresa_id": empresa_id, "activo": True, "fecha_vencimiento": {"$ne": None}}, {"_id": 0}
    ).to_list(1000)
    
    for epp in epp_items:
        if epp.get("fecha_vencimiento"):
            try:
                fecha = datetime.fromisoformat(epp["fecha_vencimiento"].replace('Z', '+00:00'))
                dias = (fecha - now).days
                if 0 <= dias <= 30:
                    existing = await db.bomberos_alertas.find_one({
                        "entidad_id": epp["id"],
                        "tipo": "epp_vencido",
                        "resuelta": False
                    })
                    if not existing:
                        alerta_id = str(uuid.uuid4())
                        await db.bomberos_alertas.insert_one({
                            "id": alerta_id,
                            "tipo": "epp_vencido",
                            "prioridad": "alta" if dias <= 7 else "media",
                            "titulo": f"EPP por vencer - {epp['codigo']}",
                            "mensaje": f"El equipo {epp['tipo']} ({epp['codigo']}) vence en {dias} días",
                            "entidad_tipo": "material_menor",
                            "entidad_id": epp["id"],
                            "bombero_id": epp.get("bombero_asignado_id"),
                            "compania_id": epp.get("compania_id"),
                            "leida": False,
                            "resuelta": False,
                            "empresa_id": empresa_id,
                            "created_at": now.isoformat()
                        })
                        alertas_generadas += 1
            except:
                pass
    
    # 3. Alertas de capacitaciones vencidas (competencias)
    # Get all bomberos with competencias
    bomberos = await db.bomberos_personal.find(
        {"empresa_id": empresa_id, "activo": True}, {"_id": 0}
    ).to_list(1000)
    
    competencias = await db.bomberos_competencias.find(
        {"empresa_id": empresa_id, "activa": True}, {"_id": 0}
    ).to_list(100)
    
    for bombero in bomberos:
        bombero_competencias = await db.bomberos_bombero_competencias.find(
            {"bombero_id": bombero["id"]}, {"_id": 0}
        ).to_list(100)
        
        for comp in bombero_competencias:
            if comp.get("fecha_obtencion"):
                competencia = next((c for c in competencias if c["id"] == comp.get("competencia_id")), None)
                if competencia:
                    try:
                        fecha_obtencion = datetime.fromisoformat(comp["fecha_obtencion"].replace('Z', '+00:00'))
                        vigencia_meses = competencia.get("vigencia_meses", 24)
                        fecha_vencimiento = fecha_obtencion + timedelta(days=vigencia_meses * 30)
                        dias = (fecha_vencimiento - now).days
                        
                        if 0 <= dias <= 60:
                            existing = await db.bomberos_alertas.find_one({
                                "bombero_id": bombero["id"],
                                "tipo": "capacitacion_vencida",
                                "resuelta": False,
                                "titulo": {"$regex": competencia["nombre"]}
                            })
                            if not existing:
                                alerta_id = str(uuid.uuid4())
                                await db.bomberos_alertas.insert_one({
                                    "id": alerta_id,
                                    "tipo": "capacitacion_vencida",
                                    "prioridad": "alta" if dias <= 15 else "media",
                                    "titulo": f"Competencia por vencer - {competencia['nombre']}",
                                    "mensaje": f"La competencia '{competencia['nombre']}' del bombero {bombero['nombres']} {bombero['apellido_paterno']} vence en {dias} días",
                                    "entidad_tipo": "bombero",
                                    "entidad_id": bombero["id"],
                                    "bombero_id": bombero["id"],
                                    "compania_id": bombero.get("compania_id"),
                                    "leida": False,
                                    "resuelta": False,
                                    "empresa_id": empresa_id,
                                    "created_at": now.isoformat()
                                })
                                alertas_generadas += 1
                    except:
                        pass
    
    return {
        "message": f"Se generaron {alertas_generadas} alertas",
        "alertas_generadas": alertas_generadas
    }

# ==================== ROLES Y PERMISOS BOMBEROS ENDPOINTS ====================

@api_router.get("/bomberos/permisos-disponibles")
async def get_permisos_disponibles(user: dict = Depends(get_current_user)):
    """Obtener lista de todos los permisos disponibles"""
    return {
        "permisos": [
            {"codigo": codigo, "descripcion": descripcion}
            for codigo, descripcion in PERMISOS_BOMBEROS.items()
        ]
    }

@api_router.get("/bomberos/roles", response_model=List[RolBomberosResponse])
async def get_roles_bomberos(user: dict = Depends(get_current_user)):
    """Obtener todos los roles del módulo bomberos para la empresa"""
    empresa_id = user.get("empresa_id")
    if not empresa_id and user["rol"] != "superadmin":
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    query = {"activo": True}
    if empresa_id:
        query["empresa_id"] = empresa_id
    
    roles = await db.bomberos_roles.find(query, {"_id": 0}).to_list(100)
    return roles

@api_router.get("/bomberos/roles/{rol_id}", response_model=RolBomberosResponse)
async def get_rol_bomberos(rol_id: str, user: dict = Depends(get_current_user)):
    """Obtener un rol específico"""
    rol = await db.bomberos_roles.find_one({"id": rol_id}, {"_id": 0})
    if not rol:
        raise HTTPException(status_code=404, detail="Rol no encontrado")
    return rol

@api_router.post("/bomberos/roles", response_model=RolBomberosResponse)
async def create_rol_bomberos(data: RolBomberosBase, user: dict = Depends(require_roles("admin"))):
    """Crear un nuevo rol para el módulo bomberos"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Verificar que no exista un rol con el mismo código
    existing = await db.bomberos_roles.find_one({
        "codigo": data.codigo, 
        "empresa_id": empresa_id
    })
    if existing:
        raise HTTPException(status_code=400, detail="Ya existe un rol con este código")
    
    # Validar que los permisos sean válidos
    for permiso in data.permisos:
        if permiso not in PERMISOS_BOMBEROS:
            raise HTTPException(status_code=400, detail=f"Permiso inválido: {permiso}")
    
    rol_id = str(uuid.uuid4())
    rol = {
        "id": rol_id,
        **data.model_dump(),
        "empresa_id": empresa_id,
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_roles.insert_one(rol)
    return rol

@api_router.put("/bomberos/roles/{rol_id}")
async def update_rol_bomberos(rol_id: str, data: dict, user: dict = Depends(require_roles("admin"))):
    """Actualizar un rol"""
    # Validar permisos si se proporcionan
    if "permisos" in data:
        for permiso in data["permisos"]:
            if permiso not in PERMISOS_BOMBEROS:
                raise HTTPException(status_code=400, detail=f"Permiso inválido: {permiso}")
    
    data.pop("id", None)
    data.pop("created_at", None)
    result = await db.bomberos_roles.update_one({"id": rol_id}, {"$set": data})
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Rol no encontrado")
    return {"message": "Rol actualizado"}

@api_router.delete("/bomberos/roles/{rol_id}")
async def delete_rol_bomberos(rol_id: str, user: dict = Depends(require_roles("admin"))):
    """Desactivar un rol (soft delete)"""
    # Verificar si hay usuarios con este rol
    usuarios_con_rol = await db.bomberos_usuarios.count_documents({"rol_bomberos_id": rol_id, "activo": True})
    if usuarios_con_rol > 0:
        raise HTTPException(
            status_code=400, 
            detail=f"No se puede eliminar el rol porque hay {usuarios_con_rol} usuarios asignados"
        )
    
    result = await db.bomberos_roles.update_one({"id": rol_id}, {"$set": {"activo": False}})
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Rol no encontrado")
    return {"message": "Rol eliminado"}

@api_router.post("/bomberos/roles/inicializar")
async def inicializar_roles_default(user: dict = Depends(require_roles("admin"))):
    """Crear los roles predefinidos para la empresa"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    roles_creados = 0
    for codigo, config in ROLES_BOMBEROS_DEFAULT.items():
        existing = await db.bomberos_roles.find_one({
            "codigo": codigo,
            "empresa_id": empresa_id
        })
        if not existing:
            rol_id = str(uuid.uuid4())
            rol = {
                "id": rol_id,
                "codigo": codigo,
                "nombre": config["nombre"],
                "descripcion": config["descripcion"],
                "permisos": config["permisos"],
                "activo": True,
                "empresa_id": empresa_id,
                "created_at": datetime.now(timezone.utc).isoformat()
            }
            await db.bomberos_roles.insert_one(rol)
            roles_creados += 1
    
    return {
        "message": f"Se crearon {roles_creados} roles predefinidos",
        "roles_creados": roles_creados
    }

# --- USUARIOS BOMBEROS (Asignación de roles) ---

@api_router.get("/bomberos/usuarios-roles", response_model=List[UsuarioBomberosResponse])
async def get_usuarios_bomberos(user: dict = Depends(require_roles("admin"))):
    """Obtener usuarios con roles asignados en el módulo bomberos"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    usuarios_bomberos = await db.bomberos_usuarios.find(
        {"empresa_id": empresa_id, "activo": True}, {"_id": 0}
    ).to_list(500)
    
    result = []
    for ub in usuarios_bomberos:
        # Get user details
        usuario = await db.usuarios.find_one({"id": ub["usuario_id"]}, {"_id": 0, "password_hash": 0})
        # Get role details
        rol = await db.bomberos_roles.find_one({"id": ub["rol_bomberos_id"]}, {"_id": 0})
        
        result.append(UsuarioBomberosResponse(
            **ub,
            usuario_email=usuario.get("email") if usuario else None,
            usuario_nombre=usuario.get("nombre") if usuario else None,
            rol_nombre=rol.get("nombre") if rol else None,
            permisos=rol.get("permisos", []) if rol else []
        ))
    
    return result

@api_router.post("/bomberos/usuarios-roles")
async def asignar_rol_usuario(data: UsuarioBomberosBase, user: dict = Depends(require_roles("admin"))):
    """Asignar un rol de bomberos a un usuario"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Verificar que el usuario existe
    target_user = await db.usuarios.find_one({"id": data.usuario_id}, {"_id": 0})
    if not target_user:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    
    # Verificar que el rol existe
    rol = await db.bomberos_roles.find_one({"id": data.rol_bomberos_id, "activo": True}, {"_id": 0})
    if not rol:
        raise HTTPException(status_code=404, detail="Rol no encontrado")
    
    # Verificar si ya tiene un rol asignado
    existing = await db.bomberos_usuarios.find_one({
        "usuario_id": data.usuario_id,
        "empresa_id": empresa_id,
        "activo": True
    })
    
    if existing:
        # Actualizar el rol existente
        await db.bomberos_usuarios.update_one(
            {"id": existing["id"]},
            {"$set": {"rol_bomberos_id": data.rol_bomberos_id}}
        )
        return {"message": "Rol actualizado", "id": existing["id"]}
    
    # Crear nueva asignación
    asignacion_id = str(uuid.uuid4())
    asignacion = {
        "id": asignacion_id,
        "usuario_id": data.usuario_id,
        "rol_bomberos_id": data.rol_bomberos_id,
        "empresa_id": empresa_id,
        "activo": True,
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    await db.bomberos_usuarios.insert_one(asignacion)
    
    return {"message": "Rol asignado correctamente", "id": asignacion_id}

@api_router.delete("/bomberos/usuarios-roles/{usuario_id}")
async def remover_rol_usuario(usuario_id: str, user: dict = Depends(require_roles("admin"))):
    """Remover el rol de bomberos de un usuario"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    result = await db.bomberos_usuarios.update_one(
        {"usuario_id": usuario_id, "empresa_id": empresa_id},
        {"$set": {"activo": False}}
    )
    
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Asignación no encontrada")
    
    return {"message": "Rol removido correctamente"}

@api_router.get("/bomberos/mis-permisos")
async def get_mis_permisos_bomberos(user: dict = Depends(get_current_user)):
    """Obtener los permisos del usuario actual en el módulo bomberos"""
    # Superadmin y admin tienen todos los permisos
    if user["rol"] in ["superadmin", "admin"]:
        return {
            "permisos": list(PERMISOS_BOMBEROS.keys()),
            "rol": user["rol"],
            "es_admin": True
        }
    
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        return {"permisos": [], "rol": None, "es_admin": False}
    
    permisos = await get_user_bomberos_permisos(user["id"], empresa_id)
    
    # Get role info
    usuario_bomberos = await db.bomberos_usuarios.find_one(
        {"usuario_id": user["id"], "empresa_id": empresa_id, "activo": True},
        {"_id": 0}
    )
    rol_nombre = None
    if usuario_bomberos:
        rol = await db.bomberos_roles.find_one(
            {"id": usuario_bomberos["rol_bomberos_id"]},
            {"_id": 0}
        )
        if rol:
            rol_nombre = rol.get("nombre")
    
    return {
        "permisos": permisos,
        "rol": rol_nombre,
        "es_admin": False
    }

# --- SEED DATA BOMBEROS ---

@api_router.post("/bomberos/seed")
async def seed_bomberos(user: dict = Depends(require_roles("admin"))):
    """Crear datos de demostración para el módulo de bomberos"""
    empresa_id = user.get("empresa_id")
    if not empresa_id:
        raise HTTPException(status_code=400, detail="Usuario sin empresa asignada")
    
    # Check if already seeded
    existing = await db.bomberos_companias.find_one({"empresa_id": empresa_id})
    if existing:
        return {"message": "Datos de bomberos ya existen para esta empresa"}
    
    # Create 3 companies
    companias = []
    for i, nombre in enumerate(["Primera Compañía - Bomba Facundo Carvajal", "Segunda Compañía - Bomba O'Higgins", "Tercera Compañía - Bomba Chile"], 1):
        comp_id = str(uuid.uuid4())
        compania = {
            "id": comp_id,
            "numero": i,
            "nombre": nombre,
            "direccion": f"Calle Principal {i}00, Salamanca",
            "telefono": f"+56 9 {i}234 5678",
            "activa": True,
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.bomberos_companias.insert_one(compania)
        companias.append(compania)
    
    # Create competencias
    competencias_data = [
        {"codigo": "fuego_estructural", "nombre": "Incendio Estructural", "categoria": "tecnica", "horas_requeridas": 40},
        {"codigo": "rescate_vehicular", "nombre": "Rescate Vehicular", "categoria": "tecnica", "horas_requeridas": 32},
        {"codigo": "hazmat", "nombre": "Materiales Peligrosos (HAZMAT)", "categoria": "tecnica", "horas_requeridas": 48},
        {"codigo": "rescate_cuerdas", "nombre": "Rescate con Cuerdas", "categoria": "tecnica", "horas_requeridas": 40},
        {"codigo": "incendio_forestal", "nombre": "Incendio Forestal", "categoria": "tecnica", "horas_requeridas": 32},
        {"codigo": "soporte_vital", "nombre": "Soporte Vital Básico", "categoria": "tecnica", "horas_requeridas": 24},
        {"codigo": "era", "nombre": "Equipo de Respiración Autónoma", "categoria": "tecnica", "horas_requeridas": 16},
        {"codigo": "liderazgo", "nombre": "Mando y Liderazgo", "categoria": "gestion", "horas_requeridas": 20},
        {"codigo": "sci", "nombre": "Sistema de Comando de Incidentes", "categoria": "operativa", "horas_requeridas": 16},
    ]
    
    competencias = []
    for c in competencias_data:
        comp_id = str(uuid.uuid4())
        competencia = {
            "id": comp_id,
            **c,
            "descripcion": f"Competencia en {c['nombre']}",
            "vigencia_meses": 24,
            "activa": True,
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.bomberos_competencias.insert_one(competencia)
        competencias.append(competencia)
    
    # Create sample bomberos
    bomberos_data = [
        {"nombres": "Juan Carlos", "apellido_paterno": "Pérez", "apellido_materno": "González", "rut": "12.345.678-9", "grado": "capitan"},
        {"nombres": "María José", "apellido_paterno": "López", "apellido_materno": "Silva", "rut": "13.456.789-0", "grado": "teniente"},
        {"nombres": "Pedro Pablo", "apellido_paterno": "Martínez", "apellido_materno": "Rojas", "rut": "14.567.890-1", "grado": "bombero"},
        {"nombres": "Ana María", "apellido_paterno": "García", "apellido_materno": "Muñoz", "rut": "15.678.901-2", "grado": "bombero"},
        {"nombres": "Carlos Alberto", "apellido_paterno": "Rodríguez", "apellido_materno": "Díaz", "rut": "16.789.012-3", "grado": "voluntario"},
    ]
    
    for i, b in enumerate(bomberos_data):
        bomb_id = str(uuid.uuid4())
        bombero = {
            "id": bomb_id,
            **b,
            "fecha_ingreso": "2020-01-15",
            "compania_id": companias[i % 3]["id"],
            "activo": True,
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.bomberos_personal.insert_one(bombero)
    
    # Create sample vehicles
    vehiculos_data = [
        {"codigo": "B-1", "tipo": "carro_bomba", "marca": "Mercedes-Benz", "modelo": "Atego", "año": 2018, "patente": "KXYZ12", "capacidad_agua": 4000},
        {"codigo": "Z-1", "tipo": "aljibe", "marca": "Volvo", "modelo": "FMX", "año": 2020, "patente": "ABCD34", "capacidad_agua": 10000},
        {"codigo": "R-1", "tipo": "rescate", "marca": "MAN", "modelo": "TGM", "año": 2019, "patente": "WXYZ56", "capacidad_agua": 0},
    ]
    
    for i, v in enumerate(vehiculos_data):
        mat_id = str(uuid.uuid4())
        material = {
            "id": mat_id,
            **v,
            "compania_id": companias[i % 3]["id"],
            "estado_operativo": "operativo",
            "fecha_revision_tecnica": "2026-06-15",
            "fecha_permiso_circulacion": "2026-03-31",
            "activo": True,
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.bomberos_material_mayor.insert_one(material)
    
    # Create sample EPP
    epp_tipos = ["casco", "chaqueton", "pantalon", "botas", "guantes"]
    for i in range(15):
        epp_id = str(uuid.uuid4())
        epp = {
            "id": epp_id,
            "codigo": f"EPP-{str(i+1).zfill(4)}",
            "tipo": epp_tipos[i % len(epp_tipos)],
            "marca": "MSA" if i % 2 == 0 else "Drager",
            "talla": ["S", "M", "L", "XL"][i % 4],
            "estado": "disponible",
            "compania_id": companias[i % 3]["id"],
            "activo": True,
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.bomberos_material_menor.insert_one(epp)
    
    return {
        "message": "Datos de demostración creados",
        "companias": len(companias),
        "competencias": len(competencias),
        "bomberos": len(bomberos_data),
        "vehiculos": len(vehiculos_data),
        "epp": 15
    }

# ==================== MÓDULO ÓRDENES DE SERVICIO ====================

# Permisos del módulo
PERMISOS_ORDENES = {
    # Dashboard
    "ver_dashboard": "Ver dashboard de órdenes",
    "ver_kpis": "Ver indicadores de gestión",
    
    # Órdenes
    "ver_ordenes": "Ver órdenes de servicio",
    "crear_ordenes": "Crear órdenes de servicio",
    "editar_ordenes": "Editar órdenes de servicio",
    "eliminar_ordenes": "Eliminar órdenes de servicio",
    "tomar_ordenes": "Tomar órdenes para trabajar",
    "completar_ordenes": "Marcar órdenes como realizadas",
    "facturar_ordenes": "Facturar órdenes completadas",
    "cancelar_ordenes": "Cancelar órdenes",
    
    # Clientes
    "ver_clientes": "Ver clientes",
    "crear_clientes": "Crear clientes",
    "editar_clientes": "Editar clientes",
    "eliminar_clientes": "Eliminar clientes",
    
    # Vehículos
    "ver_vehiculos": "Ver vehículos",
    "crear_vehiculos": "Crear vehículos",
    "editar_vehiculos": "Editar vehículos",
    "eliminar_vehiculos": "Eliminar vehículos",
    
    # Inventario
    "ver_inventario": "Ver inventario de dispositivos",
    "gestionar_inventario": "Gestionar stock de dispositivos",
    
    # Reportes
    "ver_reportes": "Ver reportes",
    "exportar_reportes": "Exportar reportes",
    
    # Configuración
    "gestionar_roles": "Gestionar roles y permisos",
    "gestionar_usuarios": "Gestionar usuarios del módulo",
    "configurar_campos": "Configurar campos personalizados",
}

# Roles predefinidos
ROLES_ORDENES = {
    "admin_ordenes": {
        "nombre": "Administrador",
        "permisos": list(PERMISOS_ORDENES.keys()),
    },
    "supervisor_ordenes": {
        "nombre": "Supervisor",
        "permisos": [
            "ver_dashboard", "ver_kpis",
            "ver_ordenes", "crear_ordenes", "editar_ordenes", "cancelar_ordenes",
            "ver_clientes", "crear_clientes", "editar_clientes",
            "ver_vehiculos", "crear_vehiculos", "editar_vehiculos",
            "ver_inventario",
            "ver_reportes", "exportar_reportes",
            "gestionar_usuarios",
        ],
    },
    "tecnico_ordenes": {
        "nombre": "Técnico/Instalador",
        "permisos": [
            "ver_dashboard",
            "ver_ordenes", "tomar_ordenes", "completar_ordenes",
            "ver_clientes",
            "ver_vehiculos", "crear_vehiculos", "editar_vehiculos",
            "ver_inventario",
        ],
    },
    "facturador_ordenes": {
        "nombre": "Facturador",
        "permisos": [
            "ver_dashboard", "ver_kpis",
            "ver_ordenes", "facturar_ordenes",
            "ver_clientes",
            "ver_vehiculos",
            "ver_reportes", "exportar_reportes",
        ],
    },
    "consultor_ordenes": {
        "nombre": "Consultor (Solo lectura)",
        "permisos": [
            "ver_dashboard", "ver_kpis",
            "ver_ordenes",
            "ver_clientes",
            "ver_vehiculos",
            "ver_inventario",
            "ver_reportes",
        ],
    },
}

# Tipos de servicio predefinidos
TIPOS_SERVICIO = [
    {"codigo": "instalacion_gps", "nombre": "Instalación de GPS", "requiere_dispositivo": True},
    {"codigo": "instalacion_sensor_fatiga", "nombre": "Instalación de Sensor de Fatiga y Somnolencia", "requiere_dispositivo": True},
    {"codigo": "instalacion_camara", "nombre": "Instalación de Cámara", "requiere_dispositivo": True},
    {"codigo": "instalacion_otro", "nombre": "Instalación de Otro Dispositivo", "requiere_dispositivo": True},
    {"codigo": "asistencia_tecnica", "nombre": "Asistencia Técnica", "requiere_dispositivo": False},
    {"codigo": "mantenimiento", "nombre": "Mantenimiento Preventivo", "requiere_dispositivo": False},
    {"codigo": "desinstalacion", "nombre": "Desinstalación de Dispositivo", "requiere_dispositivo": False},
]

# Tipos de dispositivo
TIPOS_DISPOSITIVO = [
    {"codigo": "gps", "nombre": "GPS"},
    {"codigo": "sensor_fatiga", "nombre": "Sensor de Fatiga y Somnolencia"},
    {"codigo": "camara_frontal", "nombre": "Cámara Frontal"},
    {"codigo": "camara_interior", "nombre": "Cámara Interior"},
    {"codigo": "sensor_combustible", "nombre": "Sensor de Combustible"},
    {"codigo": "sensor_temperatura", "nombre": "Sensor de Temperatura"},
    {"codigo": "boton_panico", "nombre": "Botón de Pánico"},
    {"codigo": "inmovilizador", "nombre": "Inmovilizador"},
]

# --- Modelos Pydantic para Órdenes ---

class ClienteServicioCreate(BaseModel):
    rut: str
    razon_social: str
    nombre_fantasia: Optional[str] = None
    direccion: Optional[str] = None
    comuna: Optional[str] = None
    ciudad: Optional[str] = None
    telefono: Optional[str] = None
    email: Optional[str] = None
    contacto_principal: Optional[str] = None
    giro: Optional[str] = None
    campos_extra: Optional[Dict[str, Any]] = {}

class VehiculoClienteCreate(BaseModel):
    cliente_id: str
    patente: str
    tipo_vehiculo: Optional[str] = None  # auto, camioneta, camion, bus, moto, etc.
    marca: Optional[str] = None
    modelo: Optional[str] = None
    anio: Optional[int] = None
    color: Optional[str] = None
    vin: Optional[str] = None
    campos_extra: Optional[Dict[str, Any]] = {}

class DispositivoInstaladoCreate(BaseModel):
    vehiculo_id: str
    tipo_dispositivo: str
    serial: Optional[str] = None
    marca: Optional[str] = None
    modelo: Optional[str] = None
    fecha_instalacion: Optional[str] = None
    orden_id: Optional[str] = None
    observaciones: Optional[str] = None

class OrdenServicioCreate(BaseModel):
    cliente_id: str
    vehiculo_id: Optional[str] = None
    tipo_servicio: str
    descripcion: Optional[str] = None
    fecha_programada: Optional[str] = None
    prioridad: str = "media"  # alta, media, baja
    observaciones: Optional[str] = None
    campos_extra: Optional[Dict[str, Any]] = {}
    # Datos del vehículo si es nuevo
    vehiculo_patente: Optional[str] = None
    vehiculo_tipo: Optional[str] = None
    vehiculo_marca: Optional[str] = None
    vehiculo_modelo: Optional[str] = None
    vehiculo_anio: Optional[int] = None
    vehiculo_color: Optional[str] = None
    vehiculo_vin: Optional[str] = None

class OrdenServicioUpdate(BaseModel):
    cliente_id: Optional[str] = None
    vehiculo_id: Optional[str] = None
    tipo_servicio: Optional[str] = None
    descripcion: Optional[str] = None
    fecha_programada: Optional[str] = None
    prioridad: Optional[str] = None
    observaciones: Optional[str] = None
    campos_extra: Optional[Dict[str, Any]] = None

class TomarOrdenRequest(BaseModel):
    observaciones: Optional[str] = None

class CompletarOrdenRequest(BaseModel):
    trabajo_realizado: str
    dispositivos_instalados: Optional[List[Dict[str, Any]]] = []
    firma_cliente: Optional[str] = None  # Base64 de la firma
    observaciones: Optional[str] = None

class FacturarOrdenRequest(BaseModel):
    numero_factura: str
    monto: Optional[float] = None
    fecha_factura: Optional[str] = None
    documento_factura_url: Optional[str] = None
    observaciones: Optional[str] = None

class InventarioDispositivoCreate(BaseModel):
    tipo_dispositivo: str
    serial: str
    marca: Optional[str] = None
    modelo: Optional[str] = None
    estado: str = "disponible"  # disponible, instalado, en_reparacion, dado_de_baja
    observaciones: Optional[str] = None

class CampoConfigurableCreate(BaseModel):
    entidad: str  # cliente, vehiculo, orden
    nombre_campo: str
    etiqueta: str
    tipo: str  # text, number, date, select, checkbox
    requerido: bool = False
    opciones: Optional[List[str]] = None  # Para select
    orden: int = 0

class RolOrdenesCreate(BaseModel):
    codigo: str
    nombre: str
    descripcion: Optional[str] = None
    permisos: Dict[str, bool]

# --- Endpoints de Órdenes de Servicio ---

# Helper para verificar permisos de órdenes
async def verificar_permiso_ordenes(user: dict, permiso: str) -> bool:
    if user.get("rol") in ["superadmin", "admin"]:
        return True
    
    # Buscar rol asignado en el módulo
    rol_usuario = await db.ordenes_usuarios_roles.find_one({
        "usuario_id": user["id"],
        "empresa_id": user.get("empresa_id")
    })
    
    if not rol_usuario:
        return False
    
    # Buscar permisos del rol
    rol = await db.ordenes_roles.find_one({"codigo": rol_usuario["rol_codigo"]})
    if not rol:
        # Verificar roles predefinidos
        if rol_usuario["rol_codigo"] in ROLES_ORDENES:
            return permiso in ROLES_ORDENES[rol_usuario["rol_codigo"]]["permisos"]
        return False
    
    return rol.get("permisos", {}).get(permiso, False)

# === CLIENTES ===

@api_router.get("/ordenes/clientes")
async def get_clientes_servicio(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    search: Optional[str] = None
):
    """Obtener lista de clientes"""
    user = await get_current_user(credentials)
    
    query = {"empresa_id": user.get("empresa_id"), "activo": True}
    if search:
        query["$or"] = [
            {"razon_social": {"$regex": search, "$options": "i"}},
            {"rut": {"$regex": search, "$options": "i"}},
            {"nombre_fantasia": {"$regex": search, "$options": "i"}}
        ]
    
    clientes = await db.ordenes_clientes.find(query, {"_id": 0}).sort("razon_social", 1).to_list(1000)
    return clientes

@api_router.get("/ordenes/clientes/{cliente_id}")
async def get_cliente_detalle(
    cliente_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener detalle de un cliente con sus vehículos y dispositivos"""
    user = await get_current_user(credentials)
    
    cliente = await db.ordenes_clientes.find_one(
        {"id": cliente_id, "empresa_id": user.get("empresa_id")},
        {"_id": 0}
    )
    if not cliente:
        raise HTTPException(status_code=404, detail="Cliente no encontrado")
    
    # Obtener vehículos del cliente
    vehiculos = await db.ordenes_vehiculos.find(
        {"cliente_id": cliente_id, "activo": True},
        {"_id": 0}
    ).to_list(1000)
    
    # Obtener dispositivos de cada vehículo
    dispositivos_totales = {}
    for vehiculo in vehiculos:
        dispositivos = await db.ordenes_dispositivos_instalados.find(
            {"vehiculo_id": vehiculo["id"], "activo": True},
            {"_id": 0}
        ).to_list(100)
        vehiculo["dispositivos"] = dispositivos
        
        # Contar dispositivos por tipo
        for disp in dispositivos:
            tipo = disp.get("tipo_dispositivo", "otro")
            if tipo not in dispositivos_totales:
                dispositivos_totales[tipo] = {"cantidad": 0, "patentes": []}
            dispositivos_totales[tipo]["cantidad"] += 1
            dispositivos_totales[tipo]["patentes"].append(vehiculo["patente"])
    
    # Obtener historial de órdenes
    ordenes = await db.ordenes_servicio.find(
        {"cliente_id": cliente_id},
        {"_id": 0}
    ).sort("created_at", -1).to_list(100)
    
    cliente["vehiculos"] = vehiculos
    cliente["resumen_dispositivos"] = dispositivos_totales
    cliente["ordenes_historial"] = ordenes
    cliente["total_vehiculos"] = len(vehiculos)
    cliente["total_dispositivos"] = sum(d["cantidad"] for d in dispositivos_totales.values())
    
    return cliente

@api_router.post("/ordenes/clientes")
async def create_cliente_servicio(
    cliente: ClienteServicioCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Crear nuevo cliente"""
    user = await get_current_user(credentials)
    
    # Verificar RUT único
    existing = await db.ordenes_clientes.find_one({
        "rut": cliente.rut,
        "empresa_id": user.get("empresa_id")
    })
    if existing:
        raise HTTPException(status_code=400, detail="Ya existe un cliente con este RUT")
    
    cliente_data = {
        "id": str(uuid.uuid4()),
        **cliente.dict(),
        "empresa_id": user.get("empresa_id"),
        "activo": True,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "created_by": user["id"]
    }
    
    await db.ordenes_clientes.insert_one(cliente_data)
    if "_id" in cliente_data:
        del cliente_data["_id"]
    return cliente_data

@api_router.put("/ordenes/clientes/{cliente_id}")
async def update_cliente_servicio(
    cliente_id: str,
    cliente: ClienteServicioCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Actualizar cliente"""
    user = await get_current_user(credentials)
    
    existing = await db.ordenes_clientes.find_one({
        "id": cliente_id,
        "empresa_id": user.get("empresa_id")
    })
    if not existing:
        raise HTTPException(status_code=404, detail="Cliente no encontrado")
    
    update_data = {
        **cliente.dict(),
        "updated_at": datetime.now(timezone.utc).isoformat(),
        "updated_by": user["id"]
    }
    
    await db.ordenes_clientes.update_one({"id": cliente_id}, {"$set": update_data})
    return {"message": "Cliente actualizado", "id": cliente_id}

@api_router.delete("/ordenes/clientes/{cliente_id}")
async def delete_cliente_servicio(
    cliente_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Eliminar cliente (soft delete)"""
    user = await get_current_user(credentials)
    
    result = await db.ordenes_clientes.update_one(
        {"id": cliente_id, "empresa_id": user.get("empresa_id")},
        {"$set": {"activo": False, "deleted_at": datetime.now(timezone.utc).isoformat()}}
    )
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Cliente no encontrado")
    
    return {"message": "Cliente eliminado"}

# === VEHÍCULOS ===

@api_router.get("/ordenes/vehiculos")
async def get_vehiculos_clientes(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    cliente_id: Optional[str] = None,
    search: Optional[str] = None
):
    """Obtener lista de vehículos"""
    user = await get_current_user(credentials)
    
    query = {"empresa_id": user.get("empresa_id"), "activo": True}
    if cliente_id:
        query["cliente_id"] = cliente_id
    if search:
        query["$or"] = [
            {"patente": {"$regex": search, "$options": "i"}},
            {"marca": {"$regex": search, "$options": "i"}},
            {"modelo": {"$regex": search, "$options": "i"}}
        ]
    
    vehiculos = await db.ordenes_vehiculos.find(query, {"_id": 0}).sort("patente", 1).to_list(1000)
    
    # Agregar info del cliente y dispositivos a cada vehículo
    for vehiculo in vehiculos:
        cliente = await db.ordenes_clientes.find_one(
            {"id": vehiculo["cliente_id"]},
            {"_id": 0, "razon_social": 1, "rut": 1}
        )
        vehiculo["cliente"] = cliente
        
        dispositivos = await db.ordenes_dispositivos_instalados.find(
            {"vehiculo_id": vehiculo["id"], "activo": True},
            {"_id": 0}
        ).to_list(50)
        vehiculo["dispositivos"] = dispositivos
    
    return vehiculos

@api_router.get("/ordenes/vehiculos/{vehiculo_id}")
async def get_vehiculo_detalle(
    vehiculo_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener detalle de un vehículo con historial de servicios"""
    user = await get_current_user(credentials)
    
    vehiculo = await db.ordenes_vehiculos.find_one(
        {"id": vehiculo_id, "empresa_id": user.get("empresa_id")},
        {"_id": 0}
    )
    if not vehiculo:
        raise HTTPException(status_code=404, detail="Vehículo no encontrado")
    
    # Info del cliente
    cliente = await db.ordenes_clientes.find_one(
        {"id": vehiculo["cliente_id"]},
        {"_id": 0}
    )
    vehiculo["cliente"] = cliente
    
    # Dispositivos instalados
    dispositivos = await db.ordenes_dispositivos_instalados.find(
        {"vehiculo_id": vehiculo_id, "activo": True},
        {"_id": 0}
    ).to_list(50)
    vehiculo["dispositivos"] = dispositivos
    
    # Historial de servicios
    ordenes = await db.ordenes_servicio.find(
        {"vehiculo_id": vehiculo_id},
        {"_id": 0}
    ).sort("created_at", -1).to_list(100)
    vehiculo["historial_servicios"] = ordenes
    
    return vehiculo

@api_router.post("/ordenes/vehiculos")
async def create_vehiculo_cliente(
    vehiculo: VehiculoClienteCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Crear nuevo vehículo"""
    user = await get_current_user(credentials)
    
    # Verificar que el cliente existe
    cliente = await db.ordenes_clientes.find_one({"id": vehiculo.cliente_id})
    if not cliente:
        raise HTTPException(status_code=404, detail="Cliente no encontrado")
    
    # Verificar patente única en la empresa
    existing = await db.ordenes_vehiculos.find_one({
        "patente": vehiculo.patente.upper(),
        "empresa_id": user.get("empresa_id"),
        "activo": True
    })
    if existing:
        raise HTTPException(status_code=400, detail="Ya existe un vehículo con esta patente")
    
    vehiculo_data = {
        "id": str(uuid.uuid4()),
        **vehiculo.dict(),
        "patente": vehiculo.patente.upper(),
        "empresa_id": user.get("empresa_id"),
        "activo": True,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "created_by": user["id"]
    }
    
    await db.ordenes_vehiculos.insert_one(vehiculo_data)
    if "_id" in vehiculo_data:
        del vehiculo_data["_id"]
    return vehiculo_data

@api_router.put("/ordenes/vehiculos/{vehiculo_id}")
async def update_vehiculo_cliente(
    vehiculo_id: str,
    vehiculo: VehiculoClienteCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Actualizar vehículo"""
    user = await get_current_user(credentials)
    
    existing = await db.ordenes_vehiculos.find_one({
        "id": vehiculo_id,
        "empresa_id": user.get("empresa_id")
    })
    if not existing:
        raise HTTPException(status_code=404, detail="Vehículo no encontrado")
    
    update_data = {
        **vehiculo.dict(),
        "patente": vehiculo.patente.upper(),
        "updated_at": datetime.now(timezone.utc).isoformat(),
        "updated_by": user["id"]
    }
    
    await db.ordenes_vehiculos.update_one({"id": vehiculo_id}, {"$set": update_data})
    return {"message": "Vehículo actualizado", "id": vehiculo_id}

@api_router.delete("/ordenes/vehiculos/{vehiculo_id}")
async def delete_vehiculo_cliente(
    vehiculo_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Eliminar vehículo (soft delete)"""
    user = await get_current_user(credentials)
    
    result = await db.ordenes_vehiculos.update_one(
        {"id": vehiculo_id, "empresa_id": user.get("empresa_id")},
        {"$set": {"activo": False, "deleted_at": datetime.now(timezone.utc).isoformat()}}
    )
    if result.modified_count == 0:
        raise HTTPException(status_code=404, detail="Vehículo no encontrado")
    
    return {"message": "Vehículo eliminado"}

# === ÓRDENES DE SERVICIO ===

@api_router.get("/ordenes/ordenes")
async def get_ordenes_servicio(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    estado: Optional[str] = None,
    cliente_id: Optional[str] = None,
    tecnico_id: Optional[str] = None,
    tipo_servicio: Optional[str] = None,
    fecha_desde: Optional[str] = None,
    fecha_hasta: Optional[str] = None
):
    """Obtener lista de órdenes de servicio"""
    user = await get_current_user(credentials)
    
    query = {"empresa_id": user.get("empresa_id")}
    if estado:
        query["estado"] = estado
    if cliente_id:
        query["cliente_id"] = cliente_id
    if tecnico_id:
        query["tecnico_id"] = tecnico_id
    if tipo_servicio:
        query["tipo_servicio"] = tipo_servicio
    if fecha_desde:
        query["created_at"] = {"$gte": fecha_desde}
    if fecha_hasta:
        if "created_at" in query:
            query["created_at"]["$lte"] = fecha_hasta
        else:
            query["created_at"] = {"$lte": fecha_hasta}
    
    ordenes = await db.ordenes_servicio.find(query, {"_id": 0}).sort("created_at", -1).to_list(1000)
    
    # Agregar info del cliente y vehículo
    for orden in ordenes:
        cliente = await db.ordenes_clientes.find_one(
            {"id": orden.get("cliente_id")},
            {"_id": 0, "razon_social": 1, "rut": 1}
        )
        orden["cliente"] = cliente
        
        if orden.get("vehiculo_id"):
            vehiculo = await db.ordenes_vehiculos.find_one(
                {"id": orden["vehiculo_id"]},
                {"_id": 0, "patente": 1, "marca": 1, "modelo": 1}
            )
            orden["vehiculo"] = vehiculo
        
        if orden.get("tecnico_id"):
            tecnico = await db.users.find_one(
                {"id": orden["tecnico_id"]},
                {"_id": 0, "nombre": 1, "email": 1}
            )
            orden["tecnico"] = tecnico
    
    return ordenes

@api_router.get("/ordenes/ordenes/{orden_id}")
async def get_orden_detalle(
    orden_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener detalle completo de una orden"""
    user = await get_current_user(credentials)
    
    orden = await db.ordenes_servicio.find_one(
        {"id": orden_id, "empresa_id": user.get("empresa_id")},
        {"_id": 0}
    )
    if not orden:
        raise HTTPException(status_code=404, detail="Orden no encontrada")
    
    # Info completa del cliente
    if orden.get("cliente_id"):
        cliente = await db.ordenes_clientes.find_one(
            {"id": orden["cliente_id"]},
            {"_id": 0}
        )
        orden["cliente"] = cliente
    
    # Info completa del vehículo
    if orden.get("vehiculo_id"):
        vehiculo = await db.ordenes_vehiculos.find_one(
            {"id": orden["vehiculo_id"]},
            {"_id": 0}
        )
        orden["vehiculo"] = vehiculo
    
    # Info del técnico
    if orden.get("tecnico_id"):
        tecnico = await db.users.find_one(
            {"id": orden["tecnico_id"]},
            {"_id": 0, "nombre": 1, "email": 1}
        )
        orden["tecnico"] = tecnico
    
    # Dispositivos instalados en esta orden
    dispositivos = await db.ordenes_dispositivos_instalados.find(
        {"orden_id": orden_id},
        {"_id": 0}
    ).to_list(50)
    orden["dispositivos_instalados"] = dispositivos
    
    return orden

@api_router.post("/ordenes/ordenes")
async def create_orden_servicio(
    orden: OrdenServicioCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Crear nueva orden de servicio"""
    user = await get_current_user(credentials)
    
    # Verificar cliente
    cliente = await db.ordenes_clientes.find_one({"id": orden.cliente_id})
    if not cliente:
        raise HTTPException(status_code=404, detail="Cliente no encontrado")
    
    # Si se proporciona patente pero no vehiculo_id, crear el vehículo
    vehiculo_id = orden.vehiculo_id
    if not vehiculo_id and orden.vehiculo_patente:
        # Buscar si existe el vehículo
        vehiculo_existente = await db.ordenes_vehiculos.find_one({
            "patente": orden.vehiculo_patente.upper(),
            "empresa_id": user.get("empresa_id"),
            "activo": True
        })
        if vehiculo_existente:
            vehiculo_id = vehiculo_existente["id"]
        else:
            # Crear nuevo vehículo
            vehiculo_data = {
                "id": str(uuid.uuid4()),
                "cliente_id": orden.cliente_id,
                "patente": orden.vehiculo_patente.upper(),
                "tipo_vehiculo": orden.vehiculo_tipo,
                "marca": orden.vehiculo_marca,
                "modelo": orden.vehiculo_modelo,
                "anio": orden.vehiculo_anio,
                "color": orden.vehiculo_color,
                "vin": orden.vehiculo_vin,
                "empresa_id": user.get("empresa_id"),
                "activo": True,
                "created_at": datetime.now(timezone.utc).isoformat(),
                "created_by": user["id"]
            }
            await db.ordenes_vehiculos.insert_one(vehiculo_data)
            vehiculo_id = vehiculo_data["id"]
    
    # Generar número de orden
    count = await db.ordenes_servicio.count_documents({"empresa_id": user.get("empresa_id")})
    numero_orden = f"OS-{str(count + 1).zfill(6)}"
    
    orden_data = {
        "id": str(uuid.uuid4()),
        "numero_orden": numero_orden,
        "cliente_id": orden.cliente_id,
        "vehiculo_id": vehiculo_id,
        "tipo_servicio": orden.tipo_servicio,
        "descripcion": orden.descripcion,
        "fecha_programada": orden.fecha_programada,
        "prioridad": orden.prioridad,
        "observaciones": orden.observaciones,
        "campos_extra": orden.campos_extra or {},
        "estado": "pendiente",
        "empresa_id": user.get("empresa_id"),
        "created_at": datetime.now(timezone.utc).isoformat(),
        "created_by": user["id"],
        "historial": [{
            "estado": "pendiente",
            "fecha": datetime.now(timezone.utc).isoformat(),
            "usuario_id": user["id"],
            "usuario_nombre": user["nombre"],
            "comentario": "Orden creada"
        }]
    }
    
    await db.ordenes_servicio.insert_one(orden_data)
    if "_id" in orden_data:
        del orden_data["_id"]
    return orden_data

@api_router.put("/ordenes/ordenes/{orden_id}")
async def update_orden_servicio(
    orden_id: str,
    orden: OrdenServicioUpdate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Actualizar orden de servicio"""
    user = await get_current_user(credentials)
    
    existing = await db.ordenes_servicio.find_one({
        "id": orden_id,
        "empresa_id": user.get("empresa_id")
    })
    if not existing:
        raise HTTPException(status_code=404, detail="Orden no encontrada")
    
    if existing["estado"] in ["facturada", "cancelada"]:
        raise HTTPException(status_code=400, detail="No se puede editar una orden facturada o cancelada")
    
    update_data = {k: v for k, v in orden.dict().items() if v is not None}
    update_data["updated_at"] = datetime.now(timezone.utc).isoformat()
    update_data["updated_by"] = user["id"]
    
    await db.ordenes_servicio.update_one({"id": orden_id}, {"$set": update_data})
    return {"message": "Orden actualizada", "id": orden_id}

@api_router.post("/ordenes/ordenes/{orden_id}/tomar")
async def tomar_orden_servicio(
    orden_id: str,
    request: TomarOrdenRequest,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Técnico toma una orden para trabajar"""
    user = await get_current_user(credentials)
    
    orden = await db.ordenes_servicio.find_one({
        "id": orden_id,
        "empresa_id": user.get("empresa_id")
    })
    if not orden:
        raise HTTPException(status_code=404, detail="Orden no encontrada")
    
    if orden["estado"] not in ["pendiente", "asignada"]:
        raise HTTPException(status_code=400, detail="Esta orden no puede ser tomada")
    
    historial_entry = {
        "estado": "en_proceso",
        "fecha": datetime.now(timezone.utc).isoformat(),
        "usuario_id": user["id"],
        "usuario_nombre": user["nombre"],
        "comentario": f"Orden tomada por {user['nombre']}"
    }
    if request.observaciones:
        historial_entry["comentario"] += f". {request.observaciones}"
    
    await db.ordenes_servicio.update_one(
        {"id": orden_id},
        {
            "$set": {
                "estado": "en_proceso",
                "tecnico_id": user["id"],
                "fecha_inicio_trabajo": datetime.now(timezone.utc).isoformat(),
                "updated_at": datetime.now(timezone.utc).isoformat()
            },
            "$push": {"historial": historial_entry}
        }
    )
    
    return {"message": "Orden tomada exitosamente", "estado": "en_proceso"}

@api_router.post("/ordenes/ordenes/{orden_id}/completar")
async def completar_orden_servicio(
    orden_id: str,
    request: CompletarOrdenRequest,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Marcar orden como realizada"""
    user = await get_current_user(credentials)
    
    orden = await db.ordenes_servicio.find_one({
        "id": orden_id,
        "empresa_id": user.get("empresa_id")
    })
    if not orden:
        raise HTTPException(status_code=404, detail="Orden no encontrada")
    
    if orden["estado"] != "en_proceso":
        raise HTTPException(status_code=400, detail="Esta orden no está en proceso")
    
    # Registrar dispositivos instalados
    for dispositivo in (request.dispositivos_instalados or []):
        dispositivo_data = {
            "id": str(uuid.uuid4()),
            "vehiculo_id": orden.get("vehiculo_id"),
            "orden_id": orden_id,
            "tipo_dispositivo": dispositivo.get("tipo_dispositivo"),
            "serial": dispositivo.get("serial"),
            "marca": dispositivo.get("marca"),
            "modelo": dispositivo.get("modelo"),
            "fecha_instalacion": datetime.now(timezone.utc).isoformat(),
            "instalado_por": user["id"],
            "observaciones": dispositivo.get("observaciones"),
            "activo": True,
            "empresa_id": user.get("empresa_id"),
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.ordenes_dispositivos_instalados.insert_one(dispositivo_data)
        
        # Actualizar estado del dispositivo en inventario si existe
        if dispositivo.get("serial"):
            await db.ordenes_inventario.update_one(
                {"serial": dispositivo["serial"], "empresa_id": user.get("empresa_id")},
                {"$set": {"estado": "instalado", "vehiculo_id": orden.get("vehiculo_id")}}
            )
    
    historial_entry = {
        "estado": "realizada",
        "fecha": datetime.now(timezone.utc).isoformat(),
        "usuario_id": user["id"],
        "usuario_nombre": user["nombre"],
        "comentario": f"Trabajo completado: {request.trabajo_realizado}"
    }
    
    await db.ordenes_servicio.update_one(
        {"id": orden_id},
        {
            "$set": {
                "estado": "realizada",
                "trabajo_realizado": request.trabajo_realizado,
                "firma_cliente": request.firma_cliente,
                "fecha_completado": datetime.now(timezone.utc).isoformat(),
                "observaciones_cierre": request.observaciones,
                "updated_at": datetime.now(timezone.utc).isoformat()
            },
            "$push": {"historial": historial_entry}
        }
    )
    
    return {"message": "Orden completada exitosamente", "estado": "realizada"}

@api_router.post("/ordenes/ordenes/{orden_id}/facturar")
async def facturar_orden_servicio(
    orden_id: str,
    request: FacturarOrdenRequest,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Facturar orden completada"""
    user = await get_current_user(credentials)
    
    orden = await db.ordenes_servicio.find_one({
        "id": orden_id,
        "empresa_id": user.get("empresa_id")
    })
    if not orden:
        raise HTTPException(status_code=404, detail="Orden no encontrada")
    
    if orden["estado"] != "realizada":
        raise HTTPException(status_code=400, detail="Esta orden no está lista para facturar")
    
    historial_entry = {
        "estado": "facturada",
        "fecha": datetime.now(timezone.utc).isoformat(),
        "usuario_id": user["id"],
        "usuario_nombre": user["nombre"],
        "comentario": f"Factura #{request.numero_factura} emitida"
    }
    
    await db.ordenes_servicio.update_one(
        {"id": orden_id},
        {
            "$set": {
                "estado": "facturada",
                "numero_factura": request.numero_factura,
                "monto_factura": request.monto,
                "fecha_factura": request.fecha_factura or datetime.now(timezone.utc).isoformat(),
                "documento_factura_url": request.documento_factura_url,
                "observaciones_factura": request.observaciones,
                "facturado_por": user["id"],
                "updated_at": datetime.now(timezone.utc).isoformat()
            },
            "$push": {"historial": historial_entry}
        }
    )
    
    return {"message": "Orden facturada exitosamente", "estado": "facturada"}

@api_router.post("/ordenes/ordenes/{orden_id}/cancelar")
async def cancelar_orden_servicio(
    orden_id: str,
    motivo: str = Query(..., description="Motivo de cancelación"),
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Cancelar orden de servicio"""
    user = await get_current_user(credentials)
    
    orden = await db.ordenes_servicio.find_one({
        "id": orden_id,
        "empresa_id": user.get("empresa_id")
    })
    if not orden:
        raise HTTPException(status_code=404, detail="Orden no encontrada")
    
    if orden["estado"] == "facturada":
        raise HTTPException(status_code=400, detail="No se puede cancelar una orden facturada")
    
    historial_entry = {
        "estado": "cancelada",
        "fecha": datetime.now(timezone.utc).isoformat(),
        "usuario_id": user["id"],
        "usuario_nombre": user["nombre"],
        "comentario": f"Orden cancelada: {motivo}"
    }
    
    await db.ordenes_servicio.update_one(
        {"id": orden_id},
        {
            "$set": {
                "estado": "cancelada",
                "motivo_cancelacion": motivo,
                "cancelado_por": user["id"],
                "fecha_cancelacion": datetime.now(timezone.utc).isoformat(),
                "updated_at": datetime.now(timezone.utc).isoformat()
            },
            "$push": {"historial": historial_entry}
        }
    )
    
    return {"message": "Orden cancelada", "estado": "cancelada"}

@api_router.delete("/ordenes/ordenes/{orden_id}")
async def delete_orden_servicio(
    orden_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Eliminar orden (solo si está pendiente)"""
    user = await get_current_user(credentials)
    
    orden = await db.ordenes_servicio.find_one({
        "id": orden_id,
        "empresa_id": user.get("empresa_id")
    })
    if not orden:
        raise HTTPException(status_code=404, detail="Orden no encontrada")
    
    if orden["estado"] != "pendiente":
        raise HTTPException(status_code=400, detail="Solo se pueden eliminar órdenes pendientes")
    
    await db.ordenes_servicio.delete_one({"id": orden_id})
    return {"message": "Orden eliminada"}

# === INVENTARIO DE DISPOSITIVOS ===

@api_router.get("/ordenes/inventario")
async def get_inventario_dispositivos(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    tipo: Optional[str] = None,
    estado: Optional[str] = None
):
    """Obtener inventario de dispositivos"""
    user = await get_current_user(credentials)
    
    query = {"empresa_id": user.get("empresa_id")}
    if tipo:
        query["tipo_dispositivo"] = tipo
    if estado:
        query["estado"] = estado
    
    dispositivos = await db.ordenes_inventario.find(query, {"_id": 0}).sort("created_at", -1).to_list(1000)
    return dispositivos

@api_router.post("/ordenes/inventario")
async def create_dispositivo_inventario(
    dispositivo: InventarioDispositivoCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Agregar dispositivo al inventario"""
    user = await get_current_user(credentials)
    
    # Verificar serial único
    existing = await db.ordenes_inventario.find_one({
        "serial": dispositivo.serial,
        "empresa_id": user.get("empresa_id")
    })
    if existing:
        raise HTTPException(status_code=400, detail="Ya existe un dispositivo con este serial")
    
    dispositivo_data = {
        "id": str(uuid.uuid4()),
        **dispositivo.dict(),
        "empresa_id": user.get("empresa_id"),
        "created_at": datetime.now(timezone.utc).isoformat(),
        "created_by": user["id"]
    }
    
    await db.ordenes_inventario.insert_one(dispositivo_data)
    if "_id" in dispositivo_data:
        del dispositivo_data["_id"]
    return dispositivo_data

@api_router.put("/ordenes/inventario/{dispositivo_id}")
async def update_dispositivo_inventario(
    dispositivo_id: str,
    dispositivo: InventarioDispositivoCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Actualizar dispositivo del inventario"""
    user = await get_current_user(credentials)
    
    result = await db.ordenes_inventario.update_one(
        {"id": dispositivo_id, "empresa_id": user.get("empresa_id")},
        {"$set": {**dispositivo.dict(), "updated_at": datetime.now(timezone.utc).isoformat()}}
    )
    if result.matched_count == 0:
        raise HTTPException(status_code=404, detail="Dispositivo no encontrado")
    
    return {"message": "Dispositivo actualizado"}

@api_router.delete("/ordenes/inventario/{dispositivo_id}")
async def delete_dispositivo_inventario(
    dispositivo_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Eliminar dispositivo del inventario"""
    user = await get_current_user(credentials)
    
    result = await db.ordenes_inventario.delete_one({
        "id": dispositivo_id,
        "empresa_id": user.get("empresa_id"),
        "estado": "disponible"
    })
    if result.deleted_count == 0:
        raise HTTPException(status_code=400, detail="Solo se pueden eliminar dispositivos disponibles")
    
    return {"message": "Dispositivo eliminado"}

@api_router.get("/ordenes/inventario/resumen")
async def get_inventario_resumen(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener resumen del inventario"""
    user = await get_current_user(credentials)
    
    pipeline = [
        {"$match": {"empresa_id": user.get("empresa_id")}},
        {"$group": {
            "_id": {"tipo": "$tipo_dispositivo", "estado": "$estado"},
            "cantidad": {"$sum": 1}
        }}
    ]
    
    result = await db.ordenes_inventario.aggregate(pipeline).to_list(100)
    
    resumen = {}
    for item in result:
        tipo = item["_id"]["tipo"]
        estado = item["_id"]["estado"]
        if tipo not in resumen:
            resumen[tipo] = {"total": 0, "disponible": 0, "instalado": 0, "en_reparacion": 0, "dado_de_baja": 0}
        resumen[tipo][estado] = item["cantidad"]
        resumen[tipo]["total"] += item["cantidad"]
    
    return resumen

# === KPIs Y DASHBOARD ===

@api_router.get("/ordenes/kpis")
async def get_ordenes_kpis(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener KPIs del módulo de órdenes"""
    user = await get_current_user(credentials)
    empresa_id = user.get("empresa_id")
    
    # Contar órdenes por estado
    estados = ["pendiente", "asignada", "en_proceso", "realizada", "facturada", "cancelada"]
    ordenes_por_estado = {}
    for estado in estados:
        count = await db.ordenes_servicio.count_documents({
            "empresa_id": empresa_id,
            "estado": estado
        })
        ordenes_por_estado[estado] = count
    
    # Total de órdenes
    total_ordenes = sum(ordenes_por_estado.values())
    
    # Órdenes del mes actual
    inicio_mes = datetime.now(timezone.utc).replace(day=1, hour=0, minute=0, second=0, microsecond=0)
    ordenes_mes = await db.ordenes_servicio.count_documents({
        "empresa_id": empresa_id,
        "created_at": {"$gte": inicio_mes.isoformat()}
    })
    
    # Facturación del mes
    facturacion_mes = 0
    ordenes_facturadas_mes = await db.ordenes_servicio.find({
        "empresa_id": empresa_id,
        "estado": "facturada",
        "fecha_factura": {"$gte": inicio_mes.isoformat()}
    }).to_list(1000)
    for orden in ordenes_facturadas_mes:
        facturacion_mes += orden.get("monto_factura", 0) or 0
    
    # Total clientes
    total_clientes = await db.ordenes_clientes.count_documents({
        "empresa_id": empresa_id,
        "activo": True
    })
    
    # Total vehículos
    total_vehiculos = await db.ordenes_vehiculos.count_documents({
        "empresa_id": empresa_id,
        "activo": True
    })
    
    # Total dispositivos instalados
    total_dispositivos = await db.ordenes_dispositivos_instalados.count_documents({
        "empresa_id": empresa_id,
        "activo": True
    })
    
    # Inventario disponible
    inventario_disponible = await db.ordenes_inventario.count_documents({
        "empresa_id": empresa_id,
        "estado": "disponible"
    })
    
    return {
        "total_ordenes": total_ordenes,
        "ordenes_por_estado": ordenes_por_estado,
        "ordenes_mes": ordenes_mes,
        "facturacion_mes": facturacion_mes,
        "total_clientes": total_clientes,
        "total_vehiculos": total_vehiculos,
        "total_dispositivos": total_dispositivos,
        "inventario_disponible": inventario_disponible,
        "por_facturar": ordenes_por_estado.get("realizada", 0)
    }

@api_router.get("/ordenes/estadisticas/por-tipo-servicio")
async def get_estadisticas_por_tipo(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Estadísticas por tipo de servicio"""
    user = await get_current_user(credentials)
    
    pipeline = [
        {"$match": {"empresa_id": user.get("empresa_id")}},
        {"$group": {
            "_id": "$tipo_servicio",
            "total": {"$sum": 1},
            "facturadas": {"$sum": {"$cond": [{"$eq": ["$estado", "facturada"]}, 1, 0]}},
            "monto_total": {"$sum": {"$ifNull": ["$monto_factura", 0]}}
        }},
        {"$sort": {"total": -1}}
    ]
    
    result = await db.ordenes_servicio.aggregate(pipeline).to_list(20)
    return result

@api_router.get("/ordenes/estadisticas/por-tecnico")
async def get_estadisticas_por_tecnico(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Estadísticas por técnico"""
    user = await get_current_user(credentials)
    
    pipeline = [
        {"$match": {"empresa_id": user.get("empresa_id"), "tecnico_id": {"$exists": True}}},
        {"$group": {
            "_id": "$tecnico_id",
            "total": {"$sum": 1},
            "completadas": {"$sum": {"$cond": [{"$in": ["$estado", ["realizada", "facturada"]]}, 1, 0]}},
            "en_proceso": {"$sum": {"$cond": [{"$eq": ["$estado", "en_proceso"]}, 1, 0]}}
        }},
        {"$sort": {"total": -1}}
    ]
    
    result = await db.ordenes_servicio.aggregate(pipeline).to_list(50)
    
    # Agregar nombre del técnico
    for item in result:
        tecnico = await db.users.find_one({"id": item["_id"]}, {"_id": 0, "nombre": 1})
        item["tecnico_nombre"] = tecnico["nombre"] if tecnico else "Desconocido"
    
    return result

@api_router.get("/ordenes/estadisticas/tendencia-mensual")
async def get_tendencia_mensual(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Tendencia de órdenes por mes (últimos 6 meses)"""
    user = await get_current_user(credentials)
    
    meses = []
    for i in range(5, -1, -1):
        fecha = datetime.now(timezone.utc) - timedelta(days=30 * i)
        inicio_mes = fecha.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        if i > 0:
            fin_mes = (inicio_mes + timedelta(days=32)).replace(day=1) - timedelta(seconds=1)
        else:
            fin_mes = datetime.now(timezone.utc)
        
        # Contar órdenes creadas
        creadas = await db.ordenes_servicio.count_documents({
            "empresa_id": user.get("empresa_id"),
            "created_at": {"$gte": inicio_mes.isoformat(), "$lte": fin_mes.isoformat()}
        })
        
        # Contar órdenes facturadas
        facturadas = await db.ordenes_servicio.count_documents({
            "empresa_id": user.get("empresa_id"),
            "estado": "facturada",
            "fecha_factura": {"$gte": inicio_mes.isoformat(), "$lte": fin_mes.isoformat()}
        })
        
        # Monto facturado
        ordenes_mes = await db.ordenes_servicio.find({
            "empresa_id": user.get("empresa_id"),
            "estado": "facturada",
            "fecha_factura": {"$gte": inicio_mes.isoformat(), "$lte": fin_mes.isoformat()}
        }).to_list(1000)
        monto = sum(o.get("monto_factura", 0) or 0 for o in ordenes_mes)
        
        meses.append({
            "mes": inicio_mes.strftime("%Y-%m"),
            "nombre_mes": inicio_mes.strftime("%b %Y"),
            "creadas": creadas,
            "facturadas": facturadas,
            "monto_facturado": monto
        })
    
    return meses

# === CONFIGURACIÓN: CAMPOS PERSONALIZADOS ===

@api_router.get("/ordenes/configuracion/campos")
async def get_campos_configurables(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    entidad: Optional[str] = None
):
    """Obtener campos configurables"""
    user = await get_current_user(credentials)
    
    query = {"empresa_id": user.get("empresa_id")}
    if entidad:
        query["entidad"] = entidad
    
    campos = await db.ordenes_campos_config.find(query, {"_id": 0}).sort("orden", 1).to_list(100)
    return campos

@api_router.post("/ordenes/configuracion/campos")
async def create_campo_configurable(
    campo: CampoConfigurableCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Crear campo personalizado"""
    user = await get_current_user(credentials)
    
    campo_data = {
        "id": str(uuid.uuid4()),
        **campo.dict(),
        "empresa_id": user.get("empresa_id"),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    
    await db.ordenes_campos_config.insert_one(campo_data)
    if "_id" in campo_data:
        del campo_data["_id"]
    return campo_data

@api_router.delete("/ordenes/configuracion/campos/{campo_id}")
async def delete_campo_configurable(
    campo_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Eliminar campo personalizado"""
    user = await get_current_user(credentials)
    
    result = await db.ordenes_campos_config.delete_one({
        "id": campo_id,
        "empresa_id": user.get("empresa_id")
    })
    if result.deleted_count == 0:
        raise HTTPException(status_code=404, detail="Campo no encontrado")
    
    return {"message": "Campo eliminado"}

# === CONFIGURACIÓN: ROLES Y PERMISOS ===

@api_router.get("/ordenes/permisos-disponibles")
async def get_permisos_ordenes_disponibles(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener lista de permisos disponibles"""
    await get_current_user(credentials)
    
    permisos = [{"codigo": k, "descripcion": v} for k, v in PERMISOS_ORDENES.items()]
    return {"permisos": permisos, "total": len(permisos)}

@api_router.get("/ordenes/roles")
async def get_roles_ordenes(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener roles del módulo"""
    user = await get_current_user(credentials)
    
    # Roles predefinidos
    roles_predefinidos = [
        {
            "codigo": k,
            "nombre": v["nombre"],
            "predefinido": True,
            "permisos": {p: True for p in v["permisos"]}
        }
        for k, v in ROLES_ORDENES.items()
    ]
    
    # Roles personalizados
    roles_custom = await db.ordenes_roles.find(
        {"empresa_id": user.get("empresa_id")},
        {"_id": 0}
    ).to_list(50)
    
    return roles_predefinidos + roles_custom

@api_router.post("/ordenes/roles")
async def create_rol_ordenes(
    rol: RolOrdenesCreate,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Crear rol personalizado"""
    user = await get_current_user(credentials)
    
    # Verificar código único
    if rol.codigo in ROLES_ORDENES:
        raise HTTPException(status_code=400, detail="Este código está reservado")
    
    existing = await db.ordenes_roles.find_one({
        "codigo": rol.codigo,
        "empresa_id": user.get("empresa_id")
    })
    if existing:
        raise HTTPException(status_code=400, detail="Ya existe un rol con este código")
    
    rol_data = {
        "id": str(uuid.uuid4()),
        **rol.dict(),
        "predefinido": False,
        "empresa_id": user.get("empresa_id"),
        "created_at": datetime.now(timezone.utc).isoformat()
    }
    
    await db.ordenes_roles.insert_one(rol_data)
    if "_id" in rol_data:
        del rol_data["_id"]
    return rol_data

@api_router.get("/ordenes/usuarios")
async def get_usuarios_ordenes(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener usuarios con acceso al módulo"""
    user = await get_current_user(credentials)
    
    # Usuarios de la empresa
    usuarios = await db.users.find(
        {"empresa_id": user.get("empresa_id")},
        {"_id": 0, "password": 0}
    ).to_list(500)
    
    # Agregar rol en el módulo
    for u in usuarios:
        rol_asignado = await db.ordenes_usuarios_roles.find_one({
            "usuario_id": u["id"],
            "empresa_id": user.get("empresa_id")
        })
        u["rol_ordenes"] = rol_asignado["rol_codigo"] if rol_asignado else None
    
    return usuarios

@api_router.post("/ordenes/usuarios/{usuario_id}/asignar-rol")
async def asignar_rol_ordenes(
    usuario_id: str,
    rol_codigo: str = Query(...),
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Asignar rol a usuario en el módulo"""
    user = await get_current_user(credentials)
    
    # Verificar que el usuario existe
    usuario = await db.users.find_one({"id": usuario_id})
    if not usuario:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    
    # Verificar que el rol existe
    if rol_codigo not in ROLES_ORDENES:
        rol_custom = await db.ordenes_roles.find_one({"codigo": rol_codigo})
        if not rol_custom:
            raise HTTPException(status_code=404, detail="Rol no encontrado")
    
    # Asignar o actualizar
    await db.ordenes_usuarios_roles.update_one(
        {"usuario_id": usuario_id, "empresa_id": user.get("empresa_id")},
        {"$set": {
            "usuario_id": usuario_id,
            "rol_codigo": rol_codigo,
            "empresa_id": user.get("empresa_id"),
            "asignado_por": user["id"],
            "fecha_asignacion": datetime.now(timezone.utc).isoformat()
        }},
        upsert=True
    )
    
    return {"message": "Rol asignado exitosamente"}

@api_router.delete("/ordenes/usuarios/{usuario_id}/rol")
async def quitar_rol_ordenes(
    usuario_id: str,
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Quitar rol de usuario en el módulo"""
    user = await get_current_user(credentials)
    
    result = await db.ordenes_usuarios_roles.delete_one({
        "usuario_id": usuario_id,
        "empresa_id": user.get("empresa_id")
    })
    if result.deleted_count == 0:
        raise HTTPException(status_code=404, detail="Usuario no tiene rol asignado")
    
    return {"message": "Rol removido"}

# === TIPOS DE SERVICIO Y DISPOSITIVO ===

@api_router.get("/ordenes/tipos-servicio")
async def get_tipos_servicio(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener tipos de servicio"""
    await get_current_user(credentials)
    return TIPOS_SERVICIO

@api_router.get("/ordenes/tipos-dispositivo")
async def get_tipos_dispositivo(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Obtener tipos de dispositivo"""
    await get_current_user(credentials)
    return TIPOS_DISPOSITIVO

# === DATOS DE DEMOSTRACIÓN ===

@api_router.post("/ordenes/seed-demo")
async def seed_ordenes_demo(
    credentials: HTTPAuthorizationCredentials = Depends(security)
):
    """Crear datos de demostración para órdenes de servicio"""
    user = await get_current_user(credentials)
    empresa_id = user.get("empresa_id")
    
    # Crear clientes de demo
    clientes_demo = [
        {"rut": "76.123.456-7", "razon_social": "Transportes del Norte Ltda.", "nombre_fantasia": "TransNorte", "giro": "Transporte de carga", "telefono": "+56912345678", "email": "contacto@transnorte.cl", "ciudad": "Santiago"},
        {"rut": "76.234.567-8", "razon_social": "Logística Express SpA", "nombre_fantasia": "LogiEx", "giro": "Logística y distribución", "telefono": "+56923456789", "email": "info@logiex.cl", "ciudad": "Valparaíso"},
        {"rut": "76.345.678-9", "razon_social": "Buses Interurbanos S.A.", "nombre_fantasia": "BusInter", "giro": "Transporte de pasajeros", "telefono": "+56934567890", "email": "operaciones@businter.cl", "ciudad": "Concepción"},
    ]
    
    clientes_creados = []
    for c in clientes_demo:
        cliente_data = {
            "id": str(uuid.uuid4()),
            **c,
            "empresa_id": empresa_id,
            "activo": True,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.ordenes_clientes.update_one(
            {"rut": c["rut"], "empresa_id": empresa_id},
            {"$setOnInsert": cliente_data},
            upsert=True
        )
        cliente = await db.ordenes_clientes.find_one({"rut": c["rut"], "empresa_id": empresa_id})
        clientes_creados.append(cliente)
    
    # Crear vehículos de demo
    vehiculos_demo = [
        {"patente": "SPSX-17", "tipo_vehiculo": "camion", "marca": "Volvo", "modelo": "FH16", "anio": 2022, "color": "Blanco"},
        {"patente": "SPSX-16", "tipo_vehiculo": "camion", "marca": "Mercedes-Benz", "modelo": "Actros", "anio": 2021, "color": "Azul"},
        {"patente": "RKJH-45", "tipo_vehiculo": "camioneta", "marca": "Toyota", "modelo": "Hilux", "anio": 2023, "color": "Gris"},
        {"patente": "HJKL-89", "tipo_vehiculo": "bus", "marca": "Mercedes-Benz", "modelo": "O500", "anio": 2020, "color": "Verde"},
    ]
    
    vehiculos_creados = []
    for i, v in enumerate(vehiculos_demo):
        vehiculo_data = {
            "id": str(uuid.uuid4()),
            **v,
            "cliente_id": clientes_creados[i % len(clientes_creados)]["id"],
            "empresa_id": empresa_id,
            "activo": True,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.ordenes_vehiculos.update_one(
            {"patente": v["patente"], "empresa_id": empresa_id},
            {"$setOnInsert": vehiculo_data},
            upsert=True
        )
        vehiculo = await db.ordenes_vehiculos.find_one({"patente": v["patente"], "empresa_id": empresa_id})
        vehiculos_creados.append(vehiculo)
    
    # Crear dispositivos instalados de demo
    dispositivos_demo = [
        {"vehiculo_patente": "SPSX-17", "tipo": "gps", "serial": "GPS-001"},
        {"vehiculo_patente": "SPSX-16", "tipo": "gps", "serial": "GPS-002"},
        {"vehiculo_patente": "SPSX-16", "tipo": "sensor_fatiga", "serial": "SF-001"},
        {"vehiculo_patente": "RKJH-45", "tipo": "gps", "serial": "GPS-003"},
    ]
    
    for d in dispositivos_demo:
        vehiculo = next((v for v in vehiculos_creados if v["patente"] == d["vehiculo_patente"]), None)
        if vehiculo:
            disp_data = {
                "id": str(uuid.uuid4()),
                "vehiculo_id": vehiculo["id"],
                "tipo_dispositivo": d["tipo"],
                "serial": d["serial"],
                "fecha_instalacion": datetime.now(timezone.utc).isoformat(),
                "activo": True,
                "empresa_id": empresa_id,
                "created_at": datetime.now(timezone.utc).isoformat()
            }
            await db.ordenes_dispositivos_instalados.update_one(
                {"serial": d["serial"], "empresa_id": empresa_id},
                {"$setOnInsert": disp_data},
                upsert=True
            )
    
    # Crear inventario de demo
    inventario_demo = [
        {"tipo": "gps", "serial": "GPS-STOCK-001", "marca": "Teltonika", "modelo": "FMB920"},
        {"tipo": "gps", "serial": "GPS-STOCK-002", "marca": "Teltonika", "modelo": "FMB920"},
        {"tipo": "sensor_fatiga", "serial": "SF-STOCK-001", "marca": "MobileEye", "modelo": "ME1"},
        {"tipo": "camara_frontal", "serial": "CAM-STOCK-001", "marca": "Hikvision", "modelo": "DS-2"},
    ]
    
    for inv in inventario_demo:
        inv_data = {
            "id": str(uuid.uuid4()),
            "tipo_dispositivo": inv["tipo"],
            "serial": inv["serial"],
            "marca": inv["marca"],
            "modelo": inv["modelo"],
            "estado": "disponible",
            "empresa_id": empresa_id,
            "created_at": datetime.now(timezone.utc).isoformat()
        }
        await db.ordenes_inventario.update_one(
            {"serial": inv["serial"], "empresa_id": empresa_id},
            {"$setOnInsert": inv_data},
            upsert=True
        )
    
    return {
        "message": "Datos de demostración creados",
        "clientes": len(clientes_demo),
        "vehiculos": len(vehiculos_demo),
        "dispositivos_instalados": len(dispositivos_demo),
        "inventario": len(inventario_demo)
    }

@api_router.get("/")
async def root():
    return {"message": "Multisistemas - API de Gestión Empresarial"}

# Include the router in the main app
app.include_router(api_router)

app.add_middleware(
    CORSMiddleware,
    allow_credentials=True,
    allow_origins=os.environ.get('CORS_ORIGINS', '*').split(','),
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.on_event("shutdown")
async def shutdown_db_client():
    client.close()
