<?php

/**
 * Servicio de Horarios de Atención
 * Detecta si el bot está dentro del horario de atención
 * y proporciona mensajes personalizados
 */

class BusinessHoursService
{
    private $db;
    
    public function __construct()
    {
        $this->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;
    }
}
