<?php
/**
 * Script de Mantenimiento del Sistema
 * Sistema de Inventario Forestal de Guatemala
 * 
 * Este script centraliza todas las tareas de mantenimiento
 */

require_once __DIR__ . '/../api/config/environment.php';
require_once __DIR__ . '/backup-database.php';
require_once __DIR__ . '/cleanup-logs.php';
require_once __DIR__ . '/cache-cleanup.php';
require_once __DIR__ . '/system-monitor.php';

class MaintenanceManager {
    private $logFile;
    
    public function __construct() {
        $this->logFile = __DIR__ . '/../logs/maintenance.log';
        
        // Crear directorio de logs si no existe
        $logDir = dirname($this->logFile);
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
    }
    
    /**
     * Ejecutar mantenimiento completo
     */
    public function runFullMaintenance() {
        $results = [
            'timestamp' => date('Y-m-d H:i:s'),
            'type' => 'full_maintenance',
            'tasks' => [],
            'summary' => [
                'total_tasks' => 0,
                'successful_tasks' => 0,
                'failed_tasks' => 0,
                'warnings' => 0
            ]
        ];
        
        $this->log("Iniciando mantenimiento completo del sistema");
        
        // 1. Monitoreo del sistema
        $results['tasks']['system_monitor'] = $this->runSystemMonitor();
        
        // 2. Backup de base de datos
        $results['tasks']['database_backup'] = $this->runDatabaseBackup();
        
        // 3. Limpieza de logs
        $results['tasks']['log_cleanup'] = $this->runLogCleanup();
        
        // 4. Limpieza de cache
        $results['tasks']['cache_cleanup'] = $this->runCacheCleanup();
        
        // 5. Optimización de base de datos
        $results['tasks']['database_optimization'] = $this->runDatabaseOptimization();
        
        // 6. Verificación de integridad
        $results['tasks']['integrity_check'] = $this->runIntegrityCheck();
        
        // 7. Actualización de estadísticas
        $results['tasks']['update_stats'] = $this->updateSystemStats();
        
        // Calcular resumen
        foreach ($results['tasks'] as $task) {
            $results['summary']['total_tasks']++;
            
            if ($task['status'] === 'success') {
                $results['summary']['successful_tasks']++;
            } elseif ($task['status'] === 'error') {
                $results['summary']['failed_tasks']++;
            } elseif ($task['status'] === 'warning') {
                $results['summary']['warnings']++;
            }
        }
        
        // Registrar resultados
        $this->logMaintenanceResults($results);
        
        $this->log("Mantenimiento completo finalizado");
        
        return $results;
    }
    
    /**
     * Ejecutar mantenimiento rápido (tareas esenciales)
     */
    public function runQuickMaintenance() {
        $results = [
            'timestamp' => date('Y-m-d H:i:s'),
            'type' => 'quick_maintenance',
            'tasks' => [],
            'summary' => [
                'total_tasks' => 0,
                'successful_tasks' => 0,
                'failed_tasks' => 0,
                'warnings' => 0
            ]
        ];
        
        $this->log("Iniciando mantenimiento rápido del sistema");
        
        // Solo tareas esenciales
        $results['tasks']['system_monitor'] = $this->runSystemMonitor();
        $results['tasks']['cache_cleanup'] = $this->runCacheCleanup('expired');
        $results['tasks']['integrity_check'] = $this->runIntegrityCheck();
        
        // Calcular resumen
        foreach ($results['tasks'] as $task) {
            $results['summary']['total_tasks']++;
            
            if ($task['status'] === 'success') {
                $results['summary']['successful_tasks']++;
            } elseif ($task['status'] === 'error') {
                $results['summary']['failed_tasks']++;
            } elseif ($task['status'] === 'warning') {
                $results['summary']['warnings']++;
            }
        }
        
        $this->logMaintenanceResults($results);
        
        $this->log("Mantenimiento rápido finalizado");
        
        return $results;
    }
    
    /**
     * Ejecutar monitoreo del sistema
     */
    private function runSystemMonitor() {
        try {
            $monitor = new SystemMonitor();
            $result = $monitor->runFullMonitoring();
            
            return [
                'name' => 'Monitoreo del Sistema',
                'status' => strtolower($result['status']) === 'ok' ? 'success' : 'warning',
                'message' => "Estado del sistema: {$result['status']}",
                'details' => $result
            ];
            
        } catch (Exception $e) {
            return [
                'name' => 'Monitoreo del Sistema',
                'status' => 'error',
                'message' => 'Error en monitoreo: ' . $e->getMessage(),
                'details' => []
            ];
        }
    }
    
    /**
     * Ejecutar backup de base de datos
     */
    private function runDatabaseBackup() {
        try {
            $backup = new DatabaseBackup();
            $result = $backup->createFullBackup();
            
            if ($result['success']) {
                return [
                    'name' => 'Backup de Base de Datos',
                    'status' => 'success',
                    'message' => "Backup creado: {$result['filename']}",
                    'details' => $result
                ];
            } else {
                return [
                    'name' => 'Backup de Base de Datos',
                    'status' => 'error',
                    'message' => 'Error creando backup: ' . $result['error'],
                    'details' => $result
                ];
            }
            
        } catch (Exception $e) {
            return [
                'name' => 'Backup de Base de Datos',
                'status' => 'error',
                'message' => 'Error en backup: ' . $e->getMessage(),
                'details' => []
            ];
        }
    }
    
    /**
     * Ejecutar limpieza de logs
     */
    private function runLogCleanup() {
        try {
            $cleanup = new LogCleanup();
            $result = $cleanup->runCleanup();
            
            return [
                'name' => 'Limpieza de Logs',
                'status' => 'success',
                'message' => "Archivos eliminados: {$result['stats']['files_deleted']}, Espacio liberado: " . number_format($result['stats']['space_freed'] / 1024, 2) . " KB",
                'details' => $result
            ];
            
        } catch (Exception $e) {
            return [
                'name' => 'Limpieza de Logs',
                'status' => 'error',
                'message' => 'Error en limpieza: ' . $e->getMessage(),
                'details' => []
            ];
        }
    }
    
    /**
     * Ejecutar limpieza de cache
     */
    private function runCacheCleanup($type = 'expired') {
        try {
            $cache = new CacheCleanup();
            
            if ($type === 'all') {
                $result = $cache->clearAll();
            } else {
                $result = $cache->clearExpired();
            }
            
            return [
                'name' => 'Limpieza de Cache',
                'status' => 'success',
                'message' => "Archivos eliminados: {$result['files_deleted']}, Espacio liberado: " . number_format($result['space_freed'] / 1024, 2) . " KB",
                'details' => $result
            ];
            
        } catch (Exception $e) {
            return [
                'name' => 'Limpieza de Cache',
                'status' => 'error',
                'message' => 'Error en limpieza de cache: ' . $e->getMessage(),
                'details' => []
            ];
        }
    }
    
    /**
     * Ejecutar optimización de base de datos
     */
    private function runDatabaseOptimization() {
        try {
            $pdo = new PDO(
                "mysql:host=" . Environment::get('DB_HOST') . ";dbname=" . Environment::get('DB_NAME'),
                Environment::get('DB_USER'),
                Environment::get('DB_PASS')
            );
            
            // Obtener lista de tablas
            $stmt = $pdo->query("SHOW TABLES");
            $tables = $stmt->fetchAll(PDO::FETCH_COLUMN);
            
            $optimized = 0;
            $errors = [];
            
            foreach ($tables as $table) {
                try {
                    $pdo->exec("OPTIMIZE TABLE `{$table}`");
                    $optimized++;
                } catch (Exception $e) {
                    $errors[] = "Error optimizando {$table}: " . $e->getMessage();
                }
            }
            
            $status = empty($errors) ? 'success' : 'warning';
            $message = "Tablas optimizadas: {$optimized}/" . count($tables);
            
            if (!empty($errors)) {
                $message .= ", Errores: " . count($errors);
            }
            
            return [
                'name' => 'Optimización de Base de Datos',
                'status' => $status,
                'message' => $message,
                'details' => [
                    'tables_optimized' => $optimized,
                    'total_tables' => count($tables),
                    'errors' => $errors
                ]
            ];
            
        } catch (Exception $e) {
            return [
                'name' => 'Optimización de Base de Datos',
                'status' => 'error',
                'message' => 'Error en optimización: ' . $e->getMessage(),
                'details' => []
            ];
        }
    }
    
    /**
     * Ejecutar verificación de integridad
     */
    private function runIntegrityCheck() {
        try {
            $issues = [];
            
            // Verificar archivos críticos
            $criticalFiles = [
                'api/index.php',
                'api/config/database.php',
                'install.php',
                '.htaccess'
            ];
            
            foreach ($criticalFiles as $file) {
                if (!file_exists($file)) {
                    $issues[] = "Archivo crítico faltante: {$file}";
                }
            }
            
            // Verificar directorios críticos
            $criticalDirs = ['uploads', 'logs', 'cache', 'backups'];
            
            foreach ($criticalDirs as $dir) {
                if (!is_dir($dir)) {
                    $issues[] = "Directorio crítico faltante: {$dir}";
                } elseif (!is_writable($dir)) {
                    $issues[] = "Directorio sin permisos de escritura: {$dir}";
                }
            }
            
            // Verificar conexión a base de datos
            try {
                $pdo = new PDO(
                    "mysql:host=" . Environment::get('DB_HOST') . ";dbname=" . Environment::get('DB_NAME'),
                    Environment::get('DB_USER'),
                    Environment::get('DB_PASS'),
                    [PDO::ATTR_TIMEOUT => 5]
                );
                
                $stmt = $pdo->query('SELECT COUNT(*) FROM usuarios');
                $userCount = $stmt->fetchColumn();
                
                if ($userCount == 0) {
                    $issues[] = "No hay usuarios en el sistema";
                }
                
            } catch (Exception $e) {
                $issues[] = "Error de conexión a base de datos: " . $e->getMessage();
            }
            
            // Verificar configuración PHP
            $requiredExtensions = ['mysqli', 'pdo_mysql', 'json', 'mbstring', 'curl'];
            foreach ($requiredExtensions as $ext) {
                if (!extension_loaded($ext)) {
                    $issues[] = "Extensión PHP faltante: {$ext}";
                }
            }
            
            $status = empty($issues) ? 'success' : 'warning';
            $message = empty($issues) ? 'Integridad del sistema correcta' : 'Problemas detectados: ' . count($issues);
            
            return [
                'name' => 'Verificación de Integridad',
                'status' => $status,
                'message' => $message,
                'details' => [
                    'issues' => $issues,
                    'checks_performed' => count($criticalFiles) + count($criticalDirs) + count($requiredExtensions) + 2
                ]
            ];
            
        } catch (Exception $e) {
            return [
                'name' => 'Verificación de Integridad',
                'status' => 'error',
                'message' => 'Error en verificación: ' . $e->getMessage(),
                'details' => []
            ];
        }
    }
    
    /**
     * Actualizar estadísticas del sistema
     */
    private function updateSystemStats() {
        try {
            $pdo = new PDO(
                "mysql:host=" . Environment::get('DB_HOST') . ";dbname=" . Environment::get('DB_NAME'),
                Environment::get('DB_USER'),
                Environment::get('DB_PASS')
            );
            
            // Obtener estadísticas
            $stats = [];
            
            // Usuarios
            $stmt = $pdo->query('SELECT COUNT(*) FROM usuarios WHERE activo = 1');
            $stats['active_users'] = $stmt->fetchColumn();
            
            // Proyectos
            $stmt = $pdo->query('SELECT COUNT(*) FROM proyectos');
            $stats['total_projects'] = $stmt->fetchColumn();
            
            // Rodales
            $stmt = $pdo->query('SELECT COUNT(*) FROM rodales');
            $stats['total_rodales'] = $stmt->fetchColumn();
            
            // Datos de campo
            $stmt = $pdo->query('SELECT COUNT(*) FROM datos_campo');
            $stats['total_field_data'] = $stmt->fetchColumn();
            
            // Datos pendientes de sincronización
            $stmt = $pdo->query('SELECT COUNT(*) FROM datos_campo WHERE estado_sincronizacion = "Pendiente"');
            $stats['pending_sync'] = $stmt->fetchColumn();
            
            // Actualizar tabla de configuración
            foreach ($stats as $key => $value) {
                $stmt = $pdo->prepare('
                    INSERT INTO configuracion (clave, valor, descripcion) 
                    VALUES (?, ?, ?) 
                    ON DUPLICATE KEY UPDATE valor = ?, fecha_modificacion = CURRENT_TIMESTAMP
                ');
                $stmt->execute([
                    "stats_{$key}",
                    $value,
                    "Estadística del sistema: {$key}",
                    $value
                ]);
            }
            
            return [
                'name' => 'Actualización de Estadísticas',
                'status' => 'success',
                'message' => 'Estadísticas actualizadas correctamente',
                'details' => $stats
            ];
            
        } catch (Exception $e) {
            return [
                'name' => 'Actualización de Estadísticas',
                'status' => 'error',
                'message' => 'Error actualizando estadísticas: ' . $e->getMessage(),
                'details' => []
            ];
        }
    }
    
    /**
     * Registrar resultados de mantenimiento
     */
    private function logMaintenanceResults($results) {
        $logEntry = [
            'timestamp' => $results['timestamp'],
            'type' => $results['type'],
            'summary' => $results['summary'],
            'task_results' => []
        ];
        
        foreach ($results['tasks'] as $taskName => $task) {
            $logEntry['task_results'][$taskName] = [
                'status' => $task['status'],
                'message' => $task['message']
            ];
        }
        
        $logLine = json_encode($logEntry) . "\n";
        file_put_contents($this->logFile, $logLine, FILE_APPEND | LOCK_EX);
    }
    
    /**
     * Registrar mensaje en log
     */
    private function log($message) {
        $timestamp = date('Y-m-d H:i:s');
        $logLine = "[{$timestamp}] {$message}\n";
        file_put_contents($this->logFile, $logLine, FILE_APPEND | LOCK_EX);
    }
    
    /**
     * Obtener historial de mantenimiento
     */
    public function getMaintenanceHistory($limit = 10) {
        if (!file_exists($this->logFile)) {
            return [];
        }
        
        $lines = file($this->logFile, FILE_IGNORE_NEW_LINES);
        $lines = array_reverse($lines);
        $lines = array_slice($lines, 0, $limit);
        
        $history = [];
        foreach ($lines as $line) {
            $data = json_decode($line, true);
            if ($data) {
                $history[] = $data;
            }
        }
        
        return $history;
    }
}

// Ejecutar mantenimiento si se llama directamente
if (php_sapi_name() === 'cli' || (isset($_GET['action']) && $_GET['action'] === 'maintenance')) {
    $maintenance = new MaintenanceManager();
    
    $type = $_GET['type'] ?? 'quick';
    
    if ($type === 'full') {
        $results = $maintenance->runFullMaintenance();
    } else {
        $results = $maintenance->runQuickMaintenance();
    }
    
    if (php_sapi_name() === 'cli') {
        echo "=== MAINTENANCE REPORT ===\n";
        echo "Fecha: " . $results['timestamp'] . "\n";
        echo "Tipo: " . $results['type'] . "\n";
        echo "Tareas totales: " . $results['summary']['total_tasks'] . "\n";
        echo "Exitosas: " . $results['summary']['successful_tasks'] . "\n";
        echo "Fallidas: " . $results['summary']['failed_tasks'] . "\n";
        echo "Advertencias: " . $results['summary']['warnings'] . "\n\n";
        
        echo "DETALLES DE TAREAS:\n";
        echo str_repeat("=", 50) . "\n";
        
        foreach ($results['tasks'] as $taskName => $task) {
            echo "\n{$task['name']}: {$task['status']}\n";
            echo "  {$task['message']}\n";
        }
        
        echo "\n" . str_repeat("=", 50) . "\n";
    } else {
        header('Content-Type: application/json');
        echo json_encode($results, JSON_PRETTY_PRINT);
    }
}
?>