// handlers.js import { respuestaMCP } from './respuestas/respuestaMCP.js'; // <- NUEVA IMPORTACIÓN import fs from 'fs/promises'; import { log } from './logger.js'; // Ya no se necesitan: sendText, fetchChatMessages, setTypingStatus, askGemini aquí import { processMessage } from './utils/processMessage.js'; import { saveMedia } from './utils/saveMedia.js'; // import { respuestaNormal } from './respuestas/respuestaNormal.js'; // <- NUEVA IMPORTACIÓN import { respuestaBrave } from './respuestas/respuestaBrave.js'; // <- NUEVA IMPORTACIÓN import { sendText } from './whatsapp.js'; // <- NUEVA IMPORTACIÓN // Mock Data for Employees const mockEmployees = [ { id: '1', // Ensure ID is string if components expect string name: 'Ana García Mock', cedula: 123456789, // Ensure cedula is number avatar_url: 'https://randomuser.me/api/portraits/women/60.jpg', telefono: '0991234567', ubicacion: 'Oficina Mock Central', idciat: 'AG001M', grupo_estudio: 'Desarrollo Frontend Mock', empleado: true, }, { id: '2', name: 'Carlos Rodriguez Mock', cedula: 987654321, avatar_url: 'https://randomuser.me/api/portraits/men/45.jpg', telefono: '0987654321', ubicacion: 'Sucursal Mock Norte', idciat: 'CR002M', grupo_estudio: 'Backend Services Mock', empleado: true, }, { id: '3', name: 'Luisa Martinez Mock', cedula: 112233445, avatar_url: 'https://randomuser.me/api/portraits/women/61.jpg', telefono: '0976543210', ubicacion: 'Remoto Mock', idciat: 'LM003M', grupo_estudio: 'QA Mock', empleado: true, }, { id: '4', name: 'Jorge Herrera Mock', cedula: 223344556, avatar_url: 'https://randomuser.me/api/portraits/men/50.jpg', telefono: '0965432109', ubicacion: 'Oficina Mock Sur', idciat: 'JH004M', grupo_estudio: 'DevOps Mock', empleado: true, }, { id: '5', name: 'Patricia Fernández Mock', cedula: 334455667, avatar_url: 'https://randomuser.me/api/portraits/women/62.jpg', telefono: '0954321098', ubicacion: 'Oficina Mock Central', idciat: 'PF005M', grupo_estudio: 'Diseño UX/UI Mock', empleado: true, } ]; /* carpeta raíz donde saveMedia deja todo */ const MEDIA_DIR = '/media'; await fs.mkdir(MEDIA_DIR, { recursive: true }); // La función cleanForGemini se movió a respuestaNormal.js export async function processIncoming(raw) { // Guarda media si no es un mensaje de texto plano if (raw.type !== 'chat') { try { // Nota: saveMedia podría necesitar acceso a MEDIA_DIR si no está codificado internamente await saveMedia(raw /*, MEDIA_DIR */); // Podrías necesitar pasar MEDIA_DIR si saveMedia lo requiere } catch (error) { log('error', 'Error guardando media:', error); } } const msg = processMessage(raw); const text = msg.text || ''; // Logica para componentes UI de Empleados if (/^Quiero crear un nuevo @empleado/i.test(text)) { log('info', `Comando recibido: Crear nuevo empleado. Enviando componente EmpleadoForm.`); sendText(msg.chatId, 'CHAT_UI_COMPONENT::EmpleadoForm'); return; // Termina el procesamiento para este comando } const verEmpleadoMatch = text.match(/^Ver @empleado(\d+)/i); if (verEmpleadoMatch && verEmpleadoMatch[1]) { const cedula = parseInt(verEmpleadoMatch[1], 10); log('info', `Comando recibido: Ver empleado con cédula ${cedula}.`); const employee = mockEmployees.find(emp => emp.cedula === cedula); if (employee) { log('info', `Empleado encontrado: ${employee.name}. Enviando componente cardEmpleado.`); // La cédula se pasa como parámetro para que el frontend la use si es necesario para buscar o mostrar. sendText(msg.chatId, `CHAT_UI_COMPONENT::cardEmpleado::${cedula}`); } else { log('warn', `Empleado con cédula ${cedula} no encontrado.`); sendText(msg.chatId, `No se encontró un empleado con la cédula ${cedula}.`); } return; // Termina el procesamiento para este comando } const mostrarEmpleadosMatch = text.match(/^Mostrame los primeros (\d+) @empleados/i); if (mostrarEmpleadosMatch && mostrarEmpleadosMatch[1]) { const count = parseInt(mostrarEmpleadosMatch[1], 10); log('info', `Comando recibido: Mostrar los primeros ${count} empleados.`); // El count se pasa como parámetro para que el frontend lo use para determinar cuántos mostrar. // La lógica de obtener los X primeros empleados realmente estará en el frontend o en una API. // Aquí solo indicamos el componente y el count deseado. sendText(msg.chatId, `CHAT_UI_COMPONENT::tablaEmpleados::${count}`); return; // Termina el procesamiento para este comando } /* ----- comando @nucleo ----- */ // Se comenta la condicion original de @nucleo para evitar doble respuesta si no se hace return antes. // if (/^@nucleo(\s|$)/i.test(text)) { // // Llama a la función importada // // await respuestaNormal(msg); // Ya no se usa respuestaNormal aquí directamente. // await respuestaMCP(msg); // respuestaMCP ya no es relevante en este flujo si @nucleo siempre va a brave. // } if (/^@nucleo(\s|$)/i.test(text)) { // Modificado para que @nucleo solo dispare respuestaBrave log('info', '🧠 Generando respuesta para @nucleo...'); const respuestaObjMCP = await respuestaBrave(msg); log('info', 'Respuesta de @nucleo (Brave):', respuestaObjMCP); sendText(msg.chatId, respuestaObjMCP); } else { // Lógica para otros mensajes si no son comandos de UI ni @nucleo log('debug', 'Mensaje no reconocido como comando UI o @nucleo:', text); // Considerar si se debe enviar una respuesta por defecto o ninguna si no coincide con nada. // Por ahora, no se envía nada si no es un comando específico. } }