<?php
// /partition_utils.php
// Contiene la lógica para gestionar las particiones de la tabla de logs.

/**
 * Registra un mensaje en el log de particiones.
 */
function log_partition_task($message) {
    $logFile = __DIR__ . '/_logs/partition_manager.log';
    if (!is_dir(__DIR__ . '/_logs')) {
        @mkdir(__DIR__ . '/_logs', 0775);
    }
    $timestamp = date('Y-m-d H:i:s');
    @file_put_contents($logFile, "[$timestamp] $message\n", FILE_APPEND);
}

/**
 * Función principal que revisa y crea las particiones de log necesarias.
 * Esta función es llamada por el "cron simulado" en dashboard.php.
 */
function check_and_run_partition_maintenance() {
    global $db; // Asume que $db (PDO) está disponible globalmente

    try {
        if (!$db) {
            throw new Exception("Conexión PDO no disponible.");
        }

        // 1. Comprobar cuándo fue la última revisión
        $stmt_check = $db->query("SELECT setting_value FROM app_settings WHERE setting_key = 'last_partition_maintenance'");
        $last_run_date_str = $stmt_check->fetchColumn();

        if (!$last_run_date_str) {
            // No existe la configuración, no continuar para evitar bucles.
            log_partition_task("ERROR: No se encontró la clave 'last_partition_maintenance' en app_settings.");
            return;
        }

        $last_run_date = new DateTime($last_run_date_str);
        $today = new DateTime('now');

        // 2. ¿Ya se ejecutó este mes?
        if ($last_run_date->format('Y-m') === $today->format('Y-m')) {
            // Sí, ya se ejecutó. No hacer nada.
            // log_partition_task("Mantenimiento ya ejecutado en " . $today->format('Y-m') . ". Omitiendo.");
            return;
        }

        // --- NO SE HA EJECUTADO ESTE MES: Iniciar Tarea ---
        log_partition_task("--- Iniciando Tarea de Mantenimiento de Particiones (Trigger por Admin) ---");

        // 3. Calcular cuántos meses en el futuro queremos crear (ej. 3 meses)
        $months_to_create_ahead = 3;

        for ($i = 0; $i <= $months_to_create_ahead; $i++) {

            $target_month = (clone $today)->modify("+$i month");

            // Límite: siempre es el primer día del MES SIGUIENTE
            $partition_limit_date = (clone $target_month)->modify('+1 month')->format('Y-m-01');

            // Nombre de la partición (ej: p2025_12)
            $partition_name = 'p' . $target_month->format('Y_m');

            // Límite en formato TO_DAYS()
            $partition_limit_value = "TO_DAYS('$partition_limit_date')";

            // 4. Comprobar si esta partición ya existe
            // (Comprobamos si el límite de p_future es mayor que el que queremos crear)

            $check_sql = "
                SELECT PARTITION_DESCRIPTION
                FROM INFORMATION_SCHEMA.PARTITIONS
                WHERE TABLE_SCHEMA = DATABASE()
                  AND TABLE_NAME = 'log_auditoria'
                  AND PARTITION_NAME = 'p_future';
            ";
            $p_future_desc = $db->query($check_sql)->fetchColumn();
            $current_limit_days = $db->query("SELECT $partition_limit_value")->fetchColumn();

            $needs_creation = false;
            if (strtoupper($p_future_desc) === 'MAXVALUE') {
                $needs_creation = true;
            } else if (is_numeric($p_future_desc) && (int)$p_future_desc > (int)$current_limit_days) {
                $needs_creation = true;
            }

            if ($needs_creation) {
                log_partition_task("'$partition_name' no existe. Creándola con límite < $partition_limit_value ('$partition_limit_date')...");

                // 5. Ejecutar el comando REORGANIZE
                $sql_reorganize = "
                    ALTER TABLE log_auditoria
                    REORGANIZE PARTITION p_future INTO (
                        PARTITION $partition_name VALUES LESS THAN ($partition_limit_value),
                        PARTITION p_future VALUES LESS THAN (MAXVALUE)
                    );
                ";

                $db->exec($sql_reorganize);
                log_partition_task("ÉXITO: Partición '$partition_name' creada.");

            } else {
                 log_partition_task("La partición '$partition_name' (o una posterior) ya existe. Omitiendo.");
                 // Si la de este mes ya existe, las futuras también (o están al día).
                 // Rompemos el bucle 'for' para no seguir comprobando.
                 break;
            }
        } // Fin del bucle for

        // 6. Actualizar la fecha de última revisión en la BD
        $stmt_update = $db->prepare("UPDATE app_settings SET setting_value = ? WHERE setting_key = 'last_partition_maintenance'");
        $stmt_update->execute([$today->format('Y-m-d')]);

        log_partition_task("--- Mantenimiento de Particiones Finalizado. Próxima revisión en " . $today->modify('+1 month')->format('Y-m') . " ---");

    } catch (Exception $e) {
        log_partition_task("ERROR CRÍTICO durante mantenimiento de particiones: " . $e->getMessage());
        // No relanzar la excepción para no bloquear la carga del dashboard del admin
    }
}
?>
