<?php
/**
 * Script para poblar la base de datos con datos iniciales
 * Sistema de Inventario Forestal de Guatemala V1.0
 * 
 * Este script inserta:
 * - Especies forestales comunes de Guatemala
 * - Configuraciones iniciales del sistema
 * - Datos de prueba para desarrollo
 */

require_once __DIR__ . '/../api/config/database.php';

class InitialDataPopulator {
    private $pdo;
    private $errors = [];
    private $success = [];
    
    public function __construct() {
        try {
            $database = new Database();
            $this->pdo = $database->getConnection();
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (Exception $e) {
            die("Error de conexión a la base de datos: " . $e->getMessage());
        }
    }
    
    /**
     * Ejecutar todo el proceso de población de datos
     */
    public function populateAll() {
        echo "=== Iniciando población de datos iniciales ===\n\n";
        
        $this->populateSpecies();
        $this->populateConfiguration();
        $this->populateTestData();
        $this->validateDataIntegrity();
        
        $this->showResults();
    }
    
    /**
     * Insertar especies forestales comunes de Guatemala
     */
    private function populateSpecies() {
        echo "Insertando especies forestales...\n";
        
        $especies = [
            ['Pinus maximinoi', 'Pino Candelillo'],
            ['Cupressus lusitanica', 'Ciprés Común'],
            ['Pinus oocarpa', 'Pino Ocote'],
            ['Pinus pseudostrobus', 'Pino Blanco'],
            ['Pinus ayacahuite', 'Pino Blanco Ayacahuite'],
            ['Abies guatemalensis', 'Pinabete'],
            ['Quercus sp.', 'Encino'],
            ['Alnus acuminata', 'Aliso'],
            ['Liquidambar styraciflua', 'Liquidámbar'],
            ['Cedrela odorata', 'Cedro'],
            ['Swietenia macrophylla', 'Caoba'],
            ['Cordia alliodora', 'Laurel'],
            ['Tabebuia rosea', 'Matilisguate'],
            ['Ceiba pentandra', 'Ceiba'],
            ['Terminalia amazonia', 'Volador'],
            ['Vochysia guatemalensis', 'San Juan'],
            ['Dalbergia retusa', 'Cocobolo'],
            ['Calophyllum brasiliense', 'Santa María'],
            ['Virola koschnyi', 'Sangre'],
            ['Brosimum alicastrum', 'Ramón'],
            ['Manilkara zapota', 'Chicozapote'],
            ['Astronium graveolens', 'Ron Ron'],
            ['Platymiscium dimorphandrum', 'Hormigo'],
            ['Hyeronima alchorneoides', 'Pilón'],
            ['Dialium guianense', 'Tamarindo de Montaña']
        ];
        
        try {
            // Verificar si ya existen especies
            $stmt = $this->pdo->query("SELECT COUNT(*) FROM especies");
            $existingCount = $stmt->fetchColumn();
            
            if ($existingCount > 0) {
                $this->success[] = "Ya existen {$existingCount} especies en la base de datos";
                return;
            }
            
            $stmt = $this->pdo->prepare("
                INSERT INTO especies (nombre_cientifico, nombre_comun, activa) 
                VALUES (?, ?, TRUE)
            ");
            
            $insertedCount = 0;
            foreach ($especies as $especie) {
                try {
                    $stmt->execute([$especie[0], $especie[1]]);
                    $insertedCount++;
                } catch (PDOException $e) {
                    if ($e->getCode() != 23000) { // No es error de duplicado
                        $this->errors[] = "Error insertando especie {$especie[1]}: " . $e->getMessage();
                    }
                }
            }
            
            $this->success[] = "Insertadas {$insertedCount} especies forestales";
            
        } catch (Exception $e) {
            $this->errors[] = "Error general insertando especies: " . $e->getMessage();
        }
    }
    
    /**
     * Insertar configuraciones iniciales del sistema
     */
    private function populateConfiguration() {
        echo "Insertando configuraciones del sistema...\n";
        
        $configuraciones = [
            ['sistema_version', '1.0.0', 'Versión actual del sistema'],
            ['sistema_nombre', 'SIF-GT V1.0', 'Nombre completo del sistema'],
            ['max_file_size', '5242880', 'Tamaño máximo de archivo en bytes (5MB)'],
            ['allowed_file_types', 'application/pdf', 'Tipos de archivo permitidos para documentos'],
            ['session_timeout', '86400', 'Tiempo de expiración de sesión en segundos (24 horas)'],
            ['jwt_expiration', '86400', 'Tiempo de expiración de JWT en segundos (24 horas)'],
            ['backup_frequency', '7', 'Frecuencia de respaldo automático en días'],
            ['gps_precision', '6', 'Precisión decimal para coordenadas GPS'],
            ['dap_min_value', '1', 'Valor mínimo de DAP permitido (cm)'],
            ['dap_max_alert', '200', 'Valor máximo de DAP antes de mostrar alerta (cm)'],
            ['altura_min_value', '0.5', 'Valor mínimo de altura permitido (m)'],
            ['altura_max_alert', '50', 'Valor máximo de altura antes de mostrar alerta (m)'],
            ['sync_batch_size', '100', 'Cantidad de registros por lote en sincronización'],
            ['offline_storage_days', '30', 'Días de retención de datos offline'],
            ['parcela_max_number', '999', 'Número máximo de parcela permitido'],
            ['export_format', 'CSV', 'Formato por defecto para exportación de datos'],
            ['timezone', 'America/Guatemala', 'Zona horaria del sistema'],
            ['language', 'es', 'Idioma por defecto del sistema'],
            ['currency', 'GTQ', 'Moneda por defecto'],
            ['area_unit', 'hectareas', 'Unidad de medida para áreas'],
            ['distance_unit', 'metros', 'Unidad de medida para distancias'],
            ['diameter_unit', 'centimetros', 'Unidad de medida para diámetros'],
            ['enable_gps_validation', '1', 'Habilitar validación de coordenadas GPS'],
            ['min_gps_accuracy', '10', 'Precisión mínima requerida para GPS (metros)'],
            ['enable_offline_mode', '1', 'Habilitar modo offline'],
            ['auto_sync_interval', '300', 'Intervalo de sincronización automática (segundos)'],
            ['max_sync_retries', '3', 'Número máximo de reintentos de sincronización'],
            ['enable_data_validation', '1', 'Habilitar validación de datos en tiempo real'],
            ['enable_audit_log', '1', 'Habilitar registro de auditoría'],
            ['log_retention_days', '90', 'Días de retención de logs de auditoría']
        ];
        
        try {
            // Verificar configuraciones existentes
            $stmt = $this->pdo->query("SELECT COUNT(*) FROM configuracion");
            $existingCount = $stmt->fetchColumn();
            
            $stmt = $this->pdo->prepare("
                INSERT INTO configuracion (clave, valor, descripcion) 
                VALUES (?, ?, ?)
                ON DUPLICATE KEY UPDATE 
                valor = VALUES(valor), 
                descripcion = VALUES(descripcion)
            ");
            
            $insertedCount = 0;
            $updatedCount = 0;
            
            foreach ($configuraciones as $config) {
                try {
                    // Verificar si existe
                    $checkStmt = $this->pdo->prepare("SELECT COUNT(*) FROM configuracion WHERE clave = ?");
                    $checkStmt->execute([$config[0]]);
                    $exists = $checkStmt->fetchColumn() > 0;
                    
                    $stmt->execute($config);
                    
                    if ($exists) {
                        $updatedCount++;
                    } else {
                        $insertedCount++;
                    }
                } catch (PDOException $e) {
                    $this->errors[] = "Error con configuración {$config[0]}: " . $e->getMessage();
                }
            }
            
            $this->success[] = "Configuraciones: {$insertedCount} insertadas, {$updatedCount} actualizadas";
            
        } catch (Exception $e) {
            $this->errors[] = "Error general insertando configuraciones: " . $e->getMessage();
        }
    }
    
    /**
     * Crear datos de prueba para desarrollo y testing
     */
    private function populateTestData() {
        echo "Creando datos de prueba...\n";
        
        try {
            // Verificar si ya existen datos de prueba
            $stmt = $this->pdo->query("SELECT COUNT(*) FROM usuarios WHERE email LIKE '%@test.com'");
            $testUsersCount = $stmt->fetchColumn();
            
            if ($testUsersCount > 0) {
                $this->success[] = "Ya existen {$testUsersCount} usuarios de prueba";
                return;
            }
            
            // Crear usuarios de prueba
            $this->createTestUsers();
            $this->createTestProjects();
            
        } catch (Exception $e) {
            $this->errors[] = "Error creando datos de prueba: " . $e->getMessage();
        }
    }
    
    /**
     * Crear usuarios de prueba
     */
    private function createTestUsers() {
        $usuarios = [
            [
                'nombre' => 'Administrador Test',
                'email' => 'admin@test.com',
                'password' => password_hash('admin123', PASSWORD_DEFAULT),
                'rol' => 'Administrador'
            ],
            [
                'nombre' => 'Regente Test',
                'email' => 'regente@test.com',
                'password' => password_hash('regente123', PASSWORD_DEFAULT),
                'rol' => 'Regente'
            ],
            [
                'nombre' => 'Técnico Test',
                'email' => 'tecnico@test.com',
                'password' => password_hash('tecnico123', PASSWORD_DEFAULT),
                'rol' => 'Técnico de Campo'
            ]
        ];
        
        $stmt = $this->pdo->prepare("
            INSERT INTO usuarios (nombre, email, password_hash, rol) 
            VALUES (?, ?, ?, ?)
        ");
        
        $insertedUsers = 0;
        foreach ($usuarios as $usuario) {
            try {
                $stmt->execute([
                    $usuario['nombre'],
                    $usuario['email'],
                    $usuario['password'],
                    $usuario['rol']
                ]);
                $insertedUsers++;
            } catch (PDOException $e) {
                if ($e->getCode() != 23000) { // No es error de duplicado
                    $this->errors[] = "Error creando usuario {$usuario['email']}: " . $e->getMessage();
                }
            }
        }
        
        $this->success[] = "Creados {$insertedUsers} usuarios de prueba";
    }
    
    /**
     * Crear proyectos de prueba
     */
    private function createTestProjects() {
        // Obtener ID del usuario administrador de prueba
        $stmt = $this->pdo->prepare("SELECT id FROM usuarios WHERE email = ? LIMIT 1");
        $stmt->execute(['admin@test.com']);
        $adminId = $stmt->fetchColumn();
        
        if (!$adminId) {
            $this->errors[] = "No se pudo encontrar usuario administrador para crear proyectos de prueba";
            return;
        }
        
        $proyectos = [
            [
                'nombre_proyecto' => 'Inventario Forestal Petén Norte',
                'nombre_finca' => 'Finca El Bosque',
                'departamento' => 'Petén',
                'municipio' => 'Flores',
                'aldea' => 'El Remate',
                'nombre_propietario' => 'Juan Carlos Méndez',
                'nombre_regente_forestal' => 'Ing. María González',
                'usuario_id' => $adminId
            ],
            [
                'nombre_proyecto' => 'Plan de Manejo Quetzaltenango',
                'nombre_finca' => 'Finca Los Pinos',
                'departamento' => 'Quetzaltenango',
                'municipio' => 'Zunil',
                'aldea' => 'Chuicavioc',
                'nombre_propietario' => 'Cooperativa Forestal Los Altos',
                'nombre_regente_forestal' => 'Ing. Carlos Rodríguez',
                'usuario_id' => $adminId
            ]
        ];
        
        $stmt = $this->pdo->prepare("
            INSERT INTO proyectos (
                nombre_proyecto, nombre_finca, departamento, municipio, aldea,
                nombre_propietario, nombre_regente_forestal, usuario_id
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
        ");
        
        $insertedProjects = 0;
        foreach ($proyectos as $proyecto) {
            try {
                $stmt->execute([
                    $proyecto['nombre_proyecto'],
                    $proyecto['nombre_finca'],
                    $proyecto['departamento'],
                    $proyecto['municipio'],
                    $proyecto['aldea'],
                    $proyecto['nombre_propietario'],
                    $proyecto['nombre_regente_forestal'],
                    $proyecto['usuario_id']
                ]);
                $insertedProjects++;
                
                // Crear rodales para cada proyecto
                $projectId = $this->pdo->lastInsertId();
                $this->createTestRodales($projectId);
                
            } catch (PDOException $e) {
                $this->errors[] = "Error creando proyecto {$proyecto['nombre_proyecto']}: " . $e->getMessage();
            }
        }
        
        $this->success[] = "Creados {$insertedProjects} proyectos de prueba";
    }
    
    /**
     * Crear rodales de prueba para un proyecto
     */
    private function createTestRodales($projectId) {
        $rodales = [
            ['Rodal A', 15.5],
            ['Rodal B', 22.3],
            ['Rodal C', 8.7]
        ];
        
        $stmt = $this->pdo->prepare("
            INSERT INTO rodales (proyecto_id, nombre_rodal, area_ha) 
            VALUES (?, ?, ?)
        ");
        
        foreach ($rodales as $rodal) {
            try {
                $stmt->execute([$projectId, $rodal[0], $rodal[1]]);
            } catch (PDOException $e) {
                $this->errors[] = "Error creando rodal {$rodal[0]}: " . $e->getMessage();
            }
        }
    }
    
    /**
     * Validar integridad de datos iniciales
     */
    private function validateDataIntegrity() {
        echo "Validando integridad de datos...\n";
        
        $validations = [
            [
                'name' => 'Especies activas',
                'query' => "SELECT COUNT(*) FROM especies WHERE activa = TRUE",
                'min_expected' => 20
            ],
            [
                'name' => 'Configuraciones del sistema',
                'query' => "SELECT COUNT(*) FROM configuracion",
                'min_expected' => 25
            ],
            [
                'name' => 'Usuarios con roles válidos',
                'query' => "SELECT COUNT(*) FROM usuarios WHERE rol IN ('Administrador', 'Regente', 'Técnico de Campo')",
                'min_expected' => 1
            ],
            [
                'name' => 'Integridad referencial proyectos-usuarios',
                'query' => "SELECT COUNT(*) FROM proyectos p LEFT JOIN usuarios u ON p.usuario_id = u.id WHERE u.id IS NULL",
                'max_expected' => 0
            ],
            [
                'name' => 'Integridad referencial rodales-proyectos',
                'query' => "SELECT COUNT(*) FROM rodales r LEFT JOIN proyectos p ON r.proyecto_id = p.id WHERE p.id IS NULL",
                'max_expected' => 0
            ]
        ];
        
        $validationsPassed = 0;
        foreach ($validations as $validation) {
            try {
                $stmt = $this->pdo->query($validation['query']);
                $result = $stmt->fetchColumn();
                
                $passed = true;
                if (isset($validation['min_expected']) && $result < $validation['min_expected']) {
                    $passed = false;
                    $this->errors[] = "Validación '{$validation['name']}': esperado mínimo {$validation['min_expected']}, obtenido {$result}";
                }
                
                if (isset($validation['max_expected']) && $result > $validation['max_expected']) {
                    $passed = false;
                    $this->errors[] = "Validación '{$validation['name']}': esperado máximo {$validation['max_expected']}, obtenido {$result}";
                }
                
                if ($passed) {
                    $validationsPassed++;
                    $this->success[] = "Validación '{$validation['name']}': PASÓ ({$result})";
                }
                
            } catch (Exception $e) {
                $this->errors[] = "Error en validación '{$validation['name']}': " . $e->getMessage();
            }
        }
        
        $this->success[] = "Validaciones completadas: {$validationsPassed}/" . count($validations);
    }
    
    /**
     * Mostrar resultados del proceso
     */
    private function showResults() {
        echo "\n=== RESULTADOS ===\n";
        
        if (!empty($this->success)) {
            echo "\n✅ ÉXITOS:\n";
            foreach ($this->success as $message) {
                echo "  • {$message}\n";
            }
        }
        
        if (!empty($this->errors)) {
            echo "\n❌ ERRORES:\n";
            foreach ($this->errors as $error) {
                echo "  • {$error}\n";
            }
        }
        
        echo "\n=== RESUMEN FINAL ===\n";
        echo "Éxitos: " . count($this->success) . "\n";
        echo "Errores: " . count($this->errors) . "\n";
        
        if (empty($this->errors)) {
            echo "\n🎉 Población de datos completada exitosamente!\n";
        } else {
            echo "\n⚠️  Población completada con algunos errores.\n";
        }
    }
    
    /**
     * Obtener estadísticas de la base de datos
     */
    public function getStats() {
        $stats = [];
        
        $queries = [
            'usuarios' => "SELECT COUNT(*) FROM usuarios",
            'especies' => "SELECT COUNT(*) FROM especies WHERE activa = TRUE",
            'configuraciones' => "SELECT COUNT(*) FROM configuracion",
            'proyectos' => "SELECT COUNT(*) FROM proyectos",
            'rodales' => "SELECT COUNT(*) FROM rodales"
        ];
        
        foreach ($queries as $table => $query) {
            try {
                $stmt = $this->pdo->query($query);
                $stats[$table] = $stmt->fetchColumn();
            } catch (Exception $e) {
                $stats[$table] = 'Error: ' . $e->getMessage();
            }
        }
        
        return $stats;
    }
}

// Ejecutar si se llama directamente
if (basename(__FILE__) == basename($_SERVER['SCRIPT_NAME'])) {
    $populator = new InitialDataPopulator();
    $populator->populateAll();
    
    echo "\n=== ESTADÍSTICAS FINALES ===\n";
    $stats = $populator->getStats();
    foreach ($stats as $table => $count) {
        echo ucfirst($table) . ": {$count}\n";
    }
}
?>