db = Database::getInstance(); } /** * Verifica si actualmente estamos en horario de atención * @return bool */ public function isBusinessHours(): bool { $now = new DateTime('now', new DateTimeZone('America/Bogota')); $dayOfWeek = (int)$now->format('N'); // 1=Lunes, 7=Domingo $currentTime = $now->format('H:i'); // Domingo (7) siempre cerrado if ($dayOfWeek === 7) { return false; } // Sábado (6) if ($dayOfWeek === 6) { $saturdayHours = $this->getBusinessHoursConfig('business_hours_saturday'); return $this->isTimeInRange($currentTime, $saturdayHours); } // Lunes a Viernes (1-5) $weekdayHours = $this->getBusinessHoursConfig('business_hours_weekday'); return $this->isTimeInRange($currentTime, $weekdayHours); } /** * Obtiene el mensaje apropiado según el horario * @return string */ public function getMessage(): string { if ($this->isBusinessHours()) { return $this->getWelcomeMessage(); } else { return $this->getOutOfHoursMessage(); } } /** * Obtiene el mensaje de bienvenida * @return string */ private function getWelcomeMessage(): string { $stmt = $this->db->prepare(" SELECT config_value FROM system_config WHERE config_key = 'welcome_message' LIMIT 1 "); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result) { return $result['config_value']; } // Mensaje por defecto return "¡Hola! 👋 Bienvenido(a) a nuestro servicio de WhatsApp.\n\nEscribe MENÚ para ver las opciones."; } /** * Obtiene el mensaje fuera de horario * @return string */ private function getOutOfHoursMessage(): string { $stmt = $this->db->prepare(" SELECT config_value FROM system_config WHERE config_key = 'out_of_hours_message' LIMIT 1 "); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result) { return $result['config_value']; } // Mensaje por defecto return "GRACIAS POR COMUNICARSE CON NOSOTROS ⏳\n\nEn este momento NO nos encontramos disponibles.\n\nTe responderemos lo antes posible en nuestro horario de atención.\n\n💻 Este es un mensaje automático\nGracias por tu comprensión 😊"; } /** * Obtiene la configuración de horarios * @param string $key * @return string */ private function getBusinessHoursConfig(string $key): string { $stmt = $this->db->prepare(" SELECT config_value FROM system_config WHERE config_key = ? LIMIT 1 "); $stmt->execute([$key]); $result = $stmt->fetch(PDO::FETCH_ASSOC); return $result ? $result['config_value'] : ''; } /** * Verifica si una hora está dentro de un rango * @param string $currentTime Formato HH:mm * @param string $rangesString Formato "HH:mm-HH:mm,HH:mm-HH:mm" * @return bool */ private function isTimeInRange(string $currentTime, string $rangesString): bool { if (empty($rangesString) || $rangesString === 'closed') { return false; } // Dividir por comas para múltiples rangos (ej: "7:00-12:00,14:00-17:00") $ranges = explode(',', $rangesString); foreach ($ranges as $range) { $times = explode('-', trim($range)); if (count($times) !== 2) { continue; } $start = trim($times[0]); $end = trim($times[1]); if ($currentTime >= $start && $currentTime <= $end) { return true; } } return false; } /** * Obtiene información detallada del horario actual * @return array */ public function getCurrentStatus(): array { $now = new DateTime('now', new DateTimeZone('America/Bogota')); $dayOfWeek = (int)$now->format('N'); $dayName = $this->getDayName($dayOfWeek); $currentTime = $now->format('H:i'); $isOpen = $this->isBusinessHours(); return [ 'is_open' => $isOpen, 'current_day' => $dayName, 'current_time' => $currentTime, 'day_of_week' => $dayOfWeek, 'timezone' => 'America/Bogota' ]; } /** * Obtiene el nombre del día en español * @param int $dayNumber 1-7 (1=Lunes) * @return string */ private function getDayName(int $dayNumber): string { $days = [ 1 => 'Lunes', 2 => 'Martes', 3 => 'Miércoles', 4 => 'Jueves', 5 => 'Viernes', 6 => 'Sábado', 7 => 'Domingo' ]; return $days[$dayNumber] ?? 'Desconocido'; } /** * Determina si se debe mostrar el mensaje de fuera de horario * @param string $phoneNumber * @return bool */ public function shouldShowOutOfHoursMessage(string $phoneNumber): bool { if ($this->isBusinessHours()) { return false; } // Verificar si ya se le envió el mensaje fuera de horario hoy $stmt = $this->db->prepare(" SELECT id FROM conversations WHERE phone_number = ? AND message_type = 'outgoing' AND message_text LIKE '%NO nos encontramos disponibles%' AND DATE(created_at) = CURDATE() LIMIT 1 "); $stmt->execute([$phoneNumber]); // Si ya se le envió hoy, no enviar de nuevo return $stmt->fetch() === false; } }