/** * Handler para el estado WAITING_WEBHOOKS */ import { ConversationState } from "../fsm.js"; import { createEmptyOrder, formatCartForDisplay } from "../orderModel.js"; import { renderReply } from "../replyTemplates.js"; /** * Detecta si el usuario pregunta por horarios/días de entrega */ function isDeliveryInfoQuestion(text) { const t = String(text || "").toLowerCase(); const patterns = [ /cu[aá]ndo\s+(entrega|llega|env[ií])/i, /qu[eé]\s+d[ií]as?\s+(entrega|env[ií]|repart)/i, /d[ií]as?\s+de\s+(entrega|env[ií]|reparto)/i, /horario\s+de\s+(entrega|env[ií]|reparto)/i, /qu[eé]\s+horarios?/i, /a\s+qu[eé]\s+hora/i, /en\s+qu[eé]\s+horario/i, /cuando\s+(me\s+)?lo\s+traen/i, /d[ií]a\s+y\s+hora/i, ]; return patterns.some(p => p.test(t)); } /** * Detecta si el usuario pregunta por horarios de retiro */ function isPickupInfoQuestion(text) { const t = String(text || "").toLowerCase(); const patterns = [ /horario.*(retir|buscar|pasar)/i, /cu[aá]ndo.*(retir|buscar|pasar)/i, /a\s+qu[eé]\s+hora.*(retir|buscar)/i, /d[ií]as?.*(retir|buscar)/i, ]; return patterns.some(p => p.test(t)); } /** * Maneja el estado WAITING_WEBHOOKS (esperando confirmación de pago) */ export async function handleWaitingState({ tenantId, text, nlu, order, audit, storeConfig = {}, recentReplies }) { const intent = nlu?.intent || "other"; const currentOrder = order || createEmptyOrder(); // view_cart if (intent === "view_cart") { const cartDisplay = formatCartForDisplay(currentOrder); const status = currentOrder.is_paid ? "✓ Pagado" : "Esperando pago..."; return { plan: { reply: `${cartDisplay}\n\nEstado: ${status}`, next_state: ConversationState.WAITING_WEBHOOKS, intent: "view_cart", missing_fields: [], order_action: "none", }, decision: { actions: [], order: currentOrder, audit }, }; } // Preguntas sobre horarios/días de entrega if (isDeliveryInfoQuestion(text)) { // Usar deliveryHours que ya viene formateado desde getStoreConfig // (agrupa días con mismos horarios: "Lunes a Viernes de 9:00 a 14:00, Sábado de 9:00 a 13:00") const deliveryHours = storeConfig.deliveryHours; let reply = ""; if (deliveryHours && deliveryHours !== "No disponible") { reply = `Hacemos entregas: ${deliveryHours}. `; } else if (storeConfig.deliveryEnabled === false) { reply = "Por el momento no ofrecemos delivery. "; } else { reply = "Todavía no tengo configurados los horarios de entrega. "; } reply += "Tu pedido ya está en proceso, avisame cualquier cosa."; return { plan: { reply, next_state: ConversationState.WAITING_WEBHOOKS, intent: "delivery_info", missing_fields: [], order_action: "none", }, decision: { actions: [], order: currentOrder, audit }, }; } // Preguntas sobre horarios de retiro if (isPickupInfoQuestion(text)) { const pickupHours = storeConfig.pickupHours; let reply = ""; if (pickupHours && pickupHours !== "No disponible") { reply = `Podés retirar: ${pickupHours}. `; } else if (storeConfig.pickupEnabled === false) { reply = "Por el momento no ofrecemos retiro en tienda. "; } else { reply = "Todavía no tengo configurados los horarios de retiro. "; } reply += "Tu pedido ya está en proceso, avisame cualquier cosa."; return { plan: { reply, next_state: ConversationState.WAITING_WEBHOOKS, intent: "pickup_info", missing_fields: [], order_action: "none", }, decision: { actions: [], order: currentOrder, audit }, }; } // Default const r = await renderReply({ tenantId, templateKey: "waiting.in_progress", recentReplies }); return { plan: { reply: r.reply, next_state: ConversationState.WAITING_WEBHOOKS, intent: "other", missing_fields: [], order_action: "none", }, decision: { actions: [], order: currentOrder, audit, template_ids_used: [r.template_id] }, }; }