<?php
require_once __DIR__ . '/../config/config.php';

// Establecer la zona horaria predeterminada
date_default_timezone_set('America/Mexico_City');

/**
 * Clase para manejar la conexión a la base de datos con reconexión automática
 */
class DatabaseConnection {
    private static $instance = null;
    private $pdo = null;
    private $config = [];
    
    private function __construct() {
        $this->config = [
            'host' => $_ENV['DB_HOST'] ?? 'localhost',
            'port' => $_ENV['DB_PORT'] ?? '3306',
            'name' => $_ENV['DB_NAME'] ?? 'bot',
            'user' => $_ENV['DB_USER'] ?? 'nickpons666',
            'pass' => $_ENV['DB_PASS'] ?? 'MiPo6425@@',
            'charset' => 'utf8mb4',
            'timeout' => 30, // Tiempo de espera de conexión en segundos
            'reconnect_attempts' => 3, // Número de intentos de reconexión
            'reconnect_delay' => 1, // Tiempo de espera entre reconexiones en segundos
        ];
        
        $this->connect();
    }
    
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    public function getConnection() {
        // Verificar si la conexión sigue activa
        try {
            $this->pdo->query('SELECT 1');
            return $this->pdo;
        } catch (PDOException $e) {
            // Si la conexión se perdió, intentar reconectar
            error_log("La conexión a la base de datos se perdió. Intentando reconectar...");
            $this->connect();
            return $this->pdo;
        }
    }
    
    private function connect() {
        $dsn = sprintf(
            'mysql:host=%s;port=%s;dbname=%s;charset=%s',
            $this->config['host'],
            $this->config['port'],
            $this->config['name'],
            $this->config['charset']
        );
        
        $options = [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
            PDO::ATTR_TIMEOUT            => $this->config['timeout'],
            PDO::ATTR_PERSISTENT         => false, // No usar conexiones persistentes para evitar problemas
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
        ];
        
        $attempts = 0;
        $lastException = null;
        
        while ($attempts < $this->config['reconnect_attempts']) {
            try {
                $this->pdo = new PDO(
                    $dsn,
                    $this->config['user'],
                    $this->config['pass'],
                    $options
                );
                
                // Configuración adicional de la conexión
                $this->pdo->exec("SET time_zone = '-06:00';");
                $this->pdo->exec("SET SESSION wait_timeout=28800;"); // 8 horas
                $this->pdo->exec("SET SESSION interactive_timeout=28800;"); // 8 horas
                
                error_log("Conexión a la base de datos establecida correctamente.");
                return;
                
            } catch (PDOException $e) {
                $lastException = $e;
                $attempts++;
                error_log(sprintf(
                    "Intento de conexión %d fallido: %s. Reintentando en %d segundos...",
                    $attempts,
                    $e->getMessage(),
                    $this->config['reconnect_delay']
                ));
                
                if ($attempts < $this->config['reconnect_attempts']) {
                    sleep($this->config['reconnect_delay']);
                }
            }
        }
        
        // Si llegamos aquí, todos los intentos fallaron
        error_log("No se pudo establecer la conexión después de {$this->config['reconnect_attempts']} intentos.");
        throw $lastException;
    }
}

// Crear una instancia de la conexión
try {
    $pdo = DatabaseConnection::getInstance()->getConnection();
} catch (PDOException $e) {
    error_log("Error crítico de conexión a la base de datos: " . $e->getMessage());
    // No usar die() aquí porque mata a los workers - dejar que el código maneje el error
    // Para scripts web, el error se mostrará en el log y el script continuará
    // Para workers, pueden manejar la excepción y reintentar
    if (php_sapi_name() !== 'cli') {
        // Solo para contexto web
        die("Error de conexión a la base de datos. Por favor, inténtalo de nuevo más tarde.");
    }
    // Para CLI (workers), lanzar la excepción para que el worker la maneje
    throw $e;
}
?>