<?php
declare(strict_types=1);

final class AdminController {
    private static function ensureAdmin(): void {
        if (session_status() === PHP_SESSION_NONE) session_start();
        
        $isAdmin = isset($_SESSION['user']['role']) && in_array($_SESSION['user']['role'], ['admin', 'moderator']);
        if (!$isAdmin) {
            http_response_code(403);
            view('admin/error', [
                'message' => 'Acceso denegado. No tienes permisos para acceder a esta área.'
            ]);
            exit;
        }
    }

    private static function getStats(PDO $db): array {
        // Usar la función mejorada de helpers.php
        $stats = $db->query("
            SELECT 
                (SELECT COUNT(*) FROM users) as total_users,
                (SELECT COUNT(*) FROM posts) as total_posts,
                (SELECT COUNT(*) FROM comments) as total_comments,
                (SELECT COUNT(*) FROM reports WHERE status = 'pending') as pending_reports,
                (SELECT COUNT(*) FROM security_logs WHERE created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)) as daily_logs,
                (SELECT COUNT(*) FROM login_attempts WHERE locked_until > NOW()) as locked_attempts,
                (SELECT COUNT(*) FROM ads WHERE status = 'active') as active_ads,
                (SELECT SUM(budget) FROM ads) as total_ad_budget
        ")->fetch();
        
        // Agregar estadísticas de anuncios actualizadas
        $adStats = getAdStats($db);
        if (!empty($adStats)) {
            $stats = array_merge($stats, $adStats);
        }
        
        return $stats;
    }

    // ===== DASHBOARD PRINCIPAL MEJORADO =====
    public static function dashboard(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        $quick_stats = getAdminQuickStats($db);
        $system_usage = getSystemUsage($db);
        $recent_activity = getRecentSystemActivity($db, 8);
        $system_updates = checkSystemUpdates();
        $ad_stats = getAdStats($db);
        $urgent_reports = getUrgentReports($db, 5);
        
        // Obtener actividad reciente
        $activity = $db->query("
            SELECT sl.*, u.username 
            FROM security_logs sl 
            LEFT JOIN users u ON sl.user_id = u.id 
            ORDER BY sl.created_at DESC 
            LIMIT 10
        ")->fetchAll();
        
        // Obtener reportes recientes
        $recentReports = $db->query("
            SELECT r.*, u.username as reporter_username 
            FROM reports r 
            LEFT JOIN users u ON r.reporter_id = u.id 
            ORDER BY r.created_at DESC 
            LIMIT 5
        ")->fetchAll();
        
        // Obtener anuncios que expiran pronto (CORREGIDO)
        $expiringAds = $db->query("
            SELECT title, advertiser, end_date, status
            FROM ads 
            WHERE status IN ('active', 'pending')
            AND end_date BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY)
            ORDER BY end_date ASC 
            LIMIT 5
        ")->fetchAll();
        
        view('admin/dashboard', [
            'stats' => $stats,
            'quick_stats' => $quick_stats,
            'system_usage' => $system_usage,
            'recent_activity' => $recent_activity,
            'system_updates' => $system_updates,
            'ad_stats' => $ad_stats,
            'urgent_reports' => $urgent_reports,
            'recent_activity_full' => $activity,
            'recent_reports' => $recentReports,
            'expiring_ads' => $expiringAds,
            'currentPage' => 'dashboard',
            'pageTitle' => 'Dashboard de Administración',
            'pageSubtitle' => 'Resumen del sistema y actividad reciente'
        ]);
    }

    // ===== ACTUALIZACIÓN DE ESTADÍSTICAS EN TIEMPO REAL =====
    public static function refreshStats(PDO $db): void {
        self::ensureAdmin();
        
        header('Content-Type: application/json');
        
        try {
            $stats = getAdminQuickStats($db);
            echo json_encode([
                'success' => true,
                'new_users_week' => $stats['new_users_week'] ?? 0,
                'new_posts_week' => $stats['new_posts_week'] ?? 0,
                'pending_reports' => $stats['pending_reports'] ?? 0,
                'locked_accounts' => $stats['locked_accounts'] ?? 0,
                'active_ads' => $stats['active_ads'] ?? 0,
                'daily_logs' => $stats['daily_logs'] ?? 0
            ]);
        } catch (Exception $e) {
            echo json_encode([
                'success' => false,
                'error' => $e->getMessage()
            ]);
        }
        exit;
    }

    // ===== PANEL DE CONTROL COMPLETO =====
    public static function controlPanel(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Obtener configuración del sistema
        $system_config = $db->query("SELECT * FROM system_config WHERE id = 1")->fetch();
        if (!$system_config) {
            // Crear configuración por defecto si no existe
            $db->query("INSERT INTO system_config (id, site_name, site_description, maintenance_mode, allow_registrations, max_login_attempts, session_timeout, cookie_lifetime, ad_cookie_duration, birthday_panel_duration, created_at) VALUES (1, 'Thirty', 'La red social de tus amigos de verdad', 0, 1, 5, 7200, 86400, 86400, 3600, NOW())");
            $system_config = $db->query("SELECT * FROM system_config WHERE id = 1")->fetch();
        }
        
        view('admin/control-panel', [
            'stats' => $stats,
            'system_config' => $system_config,
            'currentPage' => 'control-panel',
            'pageTitle' => 'Panel de Control Completo',
            'pageSubtitle' => 'Gestión total del sistema'
        ]);
    }

    // ===== NUEVAS FUNCIONES DE CONTROL DEL SISTEMA =====
    
    public static function systemSettings(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Obtener configuración actual
        $config = $db->query("SELECT * FROM system_config WHERE id = 1")->fetch();
        if (!$config) {
            // Crear configuración por defecto si no existe
            $db->query("INSERT INTO system_config (id, site_name, site_description, maintenance_mode, allow_registrations, max_login_attempts, session_timeout, cookie_lifetime, ad_cookie_duration, birthday_panel_duration, created_at) VALUES (1, 'Thirty', 'La red social de tus amigos de verdad', 0, 1, 5, 7200, 86400, 86400, 3600, NOW())");
            $config = $db->query("SELECT * FROM system_config WHERE id = 1")->fetch();
        }
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $site_name = trim($_POST['site_name'] ?? '');
            $site_description = trim($_POST['site_description'] ?? '');
            $maintenance_mode = isset($_POST['maintenance_mode']) ? 1 : 0;
            $maintenance_message = trim($_POST['maintenance_message'] ?? '');
            $allow_registrations = isset($_POST['allow_registrations']) ? 1 : 0;
            $max_login_attempts = (int)($_POST['max_login_attempts'] ?? 5);
            $session_timeout = (int)($_POST['session_timeout'] ?? 7200);
            $cookie_lifetime = (int)($_POST['cookie_lifetime'] ?? 86400);
            $ad_cookie_duration = (int)($_POST['ad_cookie_duration'] ?? 86400);
            $birthday_panel_duration = (int)($_POST['birthday_panel_duration'] ?? 3600);
            
            // Validaciones
            if (empty($site_name)) {
                flash('error', 'El nombre del sitio es obligatorio');
                redirect('admin/system-settings');
                return;
            }
            
            if ($max_login_attempts < 1 || $max_login_attempts > 20) {
                flash('error', 'Los intentos de login deben estar entre 1 y 20');
                redirect('admin/system-settings');
                return;
            }
            
            // Actualizar configuración
            $stmt = $db->prepare("
                UPDATE system_config SET 
                    site_name = ?, site_description = ?, maintenance_mode = ?, maintenance_message = ?,
                    allow_registrations = ?, max_login_attempts = ?, session_timeout = ?, 
                    cookie_lifetime = ?, ad_cookie_duration = ?, birthday_panel_duration = ?,
                    updated_at = NOW()
                WHERE id = 1
            ");
            
            try {
                $stmt->execute([
                    $site_name, $site_description, $maintenance_mode, $maintenance_message,
                    $allow_registrations, $max_login_attempts, $session_timeout,
                    $cookie_lifetime, $ad_cookie_duration, $birthday_panel_duration
                ]);
                
                // Registrar en logs
                SecurityHelper::logSecurityEvent($db, 'system_settings_updated', 
                    "Configuración del sistema actualizada", 
                    $_SESSION['user']['id'], 'medium');
                
                flash('success', 'Configuración del sistema actualizada correctamente');
            } catch (Exception $e) {
                flash('error', 'Error al actualizar la configuración: ' . $e->getMessage());
            }
            
            redirect('admin/system-settings');
        }
        
        view('admin/system-settings', [
            'stats' => $stats,
            'config' => $config,
            'currentPage' => 'system-settings',
            'pageTitle' => 'Configuración del Sistema',
            'pageSubtitle' => 'Ajustes generales de la plataforma'
        ]);
    }
    
    public static function maintenance(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Obtener configuración actual
        $config = $db->query("SELECT * FROM system_config WHERE id = 1")->fetch();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $action = $_POST['action'] ?? '';
            
            if ($action === 'enable') {
                $maintenance_mode = 1;
                $maintenance_message = trim($_POST['maintenance_message'] ?? 'El sitio está en mantenimiento. Vuelve pronto.');
                
                $stmt = $db->prepare("UPDATE system_config SET maintenance_mode = ?, maintenance_message = ?, updated_at = NOW() WHERE id = 1");
                $stmt->execute([$maintenance_mode, $maintenance_message]);
                
                SecurityHelper::logSecurityEvent($db, 'maintenance_enabled', 
                    "Modo mantenimiento activado: " . $maintenance_message, 
                    $_SESSION['user']['id'], 'high');
                
                flash('success', 'Modo mantenimiento activado correctamente');
                
            } elseif ($action === 'disable') {
                $stmt = $db->prepare("UPDATE system_config SET maintenance_mode = 0, updated_at = NOW() WHERE id = 1");
                $stmt->execute();
                
                SecurityHelper::logSecurityEvent($db, 'maintenance_disabled', 
                    "Modo mantenimiento desactivado", 
                    $_SESSION['user']['id'], 'high');
                
                flash('success', 'Modo mantenimiento desactivado correctamente');
            }
            
            redirect('admin/maintenance');
        }
        
        view('admin/maintenance', [
            'stats' => $stats,
            'config' => $config,
            'currentPage' => 'maintenance',
            'pageTitle' => 'Modo Mantenimiento',
            'pageSubtitle' => 'Gestionar el estado del sitio'
        ]);
    }
    
    public static function policies(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Obtener políticas actuales
        $policies = $db->query("SELECT * FROM site_policies WHERE id = 1")->fetch();
        if (!$policies) {
            // Crear políticas por defecto
            $db->query("INSERT INTO site_policies (id, terms_content, privacy_content, cookies_content, community_guidelines, created_at) VALUES (1, '', '', '', '', NOW())");
            $policies = $db->query("SELECT * FROM site_policies WHERE id = 1")->fetch();
        }
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $terms_content = trim($_POST['terms_content'] ?? '');
            $privacy_content = trim($_POST['privacy_content'] ?? '');
            $cookies_content = trim($_POST['cookies_content'] ?? '');
            $community_guidelines = trim($_POST['community_guidelines'] ?? '');
            
            $stmt = $db->prepare("
                UPDATE site_policies SET 
                    terms_content = ?, privacy_content = ?, cookies_content = ?, 
                    community_guidelines = ?, updated_at = NOW()
                WHERE id = 1
            ");
            
            try {
                $stmt->execute([
                    $terms_content, $privacy_content, $cookies_content, $community_guidelines
                ]);
                
                SecurityHelper::logSecurityEvent($db, 'policies_updated', 
                    "Políticas del sitio actualizadas", 
                    $_SESSION['user']['id'], 'medium');
                
                flash('success', 'Políticas actualizadas correctamente');
            } catch (Exception $e) {
                flash('error', 'Error al actualizar las políticas: ' . $e->getMessage());
            }
            
            redirect('admin/policies');
        }
        
        view('admin/policies', [
            'stats' => $stats,
            'policies' => $policies,
            'currentPage' => 'policies',
            'pageTitle' => 'Políticas del Sitio',
            'pageSubtitle' => 'Gestionar términos, privacidad y cookies'
        ]);
    }
    
    public static function cache(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $action = $_POST['action'] ?? '';
            $result = false;
            
            switch ($action) {
                case 'clear_cache':
                    // Limpiar caché de estadísticas (simulado)
                    $result = true;
                    SecurityHelper::logSecurityEvent($db, 'cache_cleared', 
                        "Caché del sistema limpiado", 
                        $_SESSION['user']['id'], 'low');
                    flash('success', 'Caché limpiado correctamente');
                    break;
                    
                case 'clear_logs':
                    // Limpiar logs antiguos (mantener últimos 30 días)
                    $stmt = $db->prepare("DELETE FROM security_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY)");
                    $result = $stmt->execute();
                    $deleted_rows = $stmt->rowCount();
                    
                    SecurityHelper::logSecurityEvent($db, 'logs_cleared', 
                        "Logs antiguos eliminados: $deleted_rows registros", 
                        $_SESSION['user']['id'], 'medium');
                    flash('success', "Logs antiguos eliminados: $deleted_rows registros");
                    break;
                    
                case 'optimize_tables':
                    // Optimizar tablas
                    $tables = ['users', 'posts', 'comments', 'likes', 'friends', 'reports', 'security_logs', 'login_attempts', 'ads'];
                    $optimized = 0;
                    
                    foreach ($tables as $table) {
                        try {
                            $db->query("OPTIMIZE TABLE $table");
                            $optimized++;
                        } catch (Exception $e) {
                            error_log("Error optimizando tabla $table: " . $e->getMessage());
                        }
                    }
                    
                    SecurityHelper::logSecurityEvent($db, 'tables_optimized', 
                        "Tablas optimizadas: $optimized de " . count($tables), 
                        $_SESSION['user']['id'], 'low');
                    flash('success', "Tablas optimizadas: $optimized de " . count($tables));
                    break;
            }
            
            redirect('admin/cache');
        }
        
        // Obtener información de caché
        $cache_info = [
            'total_users' => $stats['total_users'],
            'total_posts' => $stats['total_posts'],
            'total_logs' => $db->query("SELECT COUNT(*) as total FROM security_logs")->fetch()['total'],
            'db_size' => self::getDatabaseSize($db)
        ];
        
        view('admin/cache', [
            'stats' => $stats,
            'cache_info' => $cache_info,
            'currentPage' => 'cache',
            'pageTitle' => 'Cache y Optimización',
            'pageSubtitle' => 'Gestionar caché y optimizar sistema'
        ]);
    }
    
    public static function backup(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $action = $_POST['action'] ?? '';
            
            if ($action === 'create_backup') {
                $backup_result = self::createDatabaseBackup($db);
                
                if ($backup_result['success']) {
                    SecurityHelper::logSecurityEvent($db, 'backup_created', 
                        "Backup creado: " . $backup_result['filename'], 
                        $_SESSION['user']['id'], 'medium');
                    flash('success', 'Backup creado correctamente: ' . $backup_result['filename']);
                } else {
                    flash('error', 'Error al crear backup: ' . $backup_result['error']);
                }
            }
            
            redirect('admin/backup');
        }
        
        // Obtener lista de backups
        $backups = self::getBackupList();
        
        view('admin/backup', [
            'stats' => $stats,
            'backups' => $backups,
            'currentPage' => 'backup',
            'pageTitle' => 'Backup del Sistema',
            'pageSubtitle' => 'Gestionar copias de seguridad'
        ]);
    }
    
    // ===== FUNCIONES AUXILIARES =====
    
    private static function getDatabaseSize($db): string {
        try {
            $stmt = $db->query("
                SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as size_mb 
                FROM information_schema.tables 
                WHERE table_schema = DATABASE()
            ");
            $result = $stmt->fetch();
            return $result ? $result['size_mb'] . ' MB' : 'Desconocido';
        } catch (Exception $e) {
            return 'Error: ' . $e->getMessage();
        }
    }
    
    private static function createDatabaseBackup($db): array {
        $config = include __DIR__ . '/../config.php';
        $backup_dir = __DIR__ . '/../backups';
        
        // Crear directorio de backups si no existe
        if (!is_dir($backup_dir)) {
            mkdir($backup_dir, 0755, true);
        }
        
        $filename = 'backup_' . date('Y-m-d_H-i-s') . '.sql';
        $filepath = $backup_dir . '/' . $filename;
        
        try {
            // Obtener todas las tablas
            $tables = $db->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
            
            $backup_content = "-- Thirty Database Backup\n";
            $backup_content .= "-- Generated: " . gmdate('Y-m-d H:i:s') . "\n--\n\n";
            
            foreach ($tables as $table) {
                // Estructura de la tabla
                $backup_content .= "--\n-- Table structure for table `$table`\n--\n";
                $create_table = $db->query("SHOW CREATE TABLE `$table`")->fetch();
                $backup_content .= $create_table['Create Table'] . ";\n\n";
                
                // Datos de la tabla
                $backup_content .= "--\n-- Dumping data for table `$table`\n--\n";
                
                $rows = $db->query("SELECT * FROM `$table`")->fetchAll(PDO::FETCH_ASSOC);
                if (!empty($rows)) {
                    $columns = array_keys($rows[0]);
                    $backup_content .= "INSERT INTO `$table` (`" . implode('`, `', $columns) . "`) VALUES \n";
                    
                    $values = [];
                    foreach ($rows as $row) {
                        $escaped_values = array_map(function($value) use ($db) {
                            if ($value === null) return 'NULL';
                            return $db->quote($value);
                        }, $row);
                        $values[] = "(" . implode(', ', $escaped_values) . ")";
                    }
                    
                    $backup_content .= implode(",\n", $values) . ";\n\n";
                }
            }
            
            // Guardar archivo
            if (file_put_contents($filepath, $backup_content) !== false) {
                return [
                    'success' => true,
                    'filename' => $filename,
                    'filepath' => $filepath,
                    'size' => filesize($filepath)
                ];
            } else {
                return [
                    'success' => false,
                    'error' => 'No se pudo escribir el archivo de backup'
                ];
            }
            
        } catch (Exception $e) {
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }
    
    private static function getBackupList(): array {
        $backup_dir = __DIR__ . '/../backups';
        $backups = [];
        
        if (is_dir($backup_dir)) {
            $files = scandir($backup_dir);
            foreach ($files as $file) {
                if ($file !== '.' && $file !== '..' && pathinfo($file, PATHINFO_EXTENSION) === 'sql') {
                    $filepath = $backup_dir . '/' . $file;
                    $backups[] = [
                        'filename' => $file,
                        'size' => filesize($filepath),
                        'modified' => filemtime($filepath)
                    ];
                }
            }
            
            // Ordenar por fecha (más reciente primero)
            usort($backups, function($a, $b) {
                return $b['modified'] - $a['modified'];
            });
        }
        
        return $backups;
    }

    // ===== FUNCIONES EXISTENTES (MANTENER) =====
    
    public static function users(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Parámetros de paginación
        $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
        $limit = 20;
        $offset = ($page - 1) * $limit;
        
        // Construir consulta con filtros
        $whereConditions = [];
        $params = [];
        
        if (!empty($_GET['q'])) {
            $whereConditions[] = "(username LIKE ? OR email LIKE ?)";
            $params[] = '%' . $_GET['q'] . '%';
            $params[] = '%' . $_GET['q'] . '%';
        }
        
        if (!empty($_GET['role'])) {
            $whereConditions[] = "role = ?";
            $params[] = $_GET['role'];
        }
        
        if (!empty($_GET['status'])) {
            if ($_GET['status'] === 'locked') {
                $whereConditions[] = "locked_until > NOW()";
            } elseif ($_GET['status'] === 'active') {
                $whereConditions[] = "(locked_until IS NULL OR locked_until <= NOW())";
            }
        }
        
        $whereClause = $whereConditions ? 'WHERE ' . implode(' AND ', $whereConditions) : '';
        
        // Obtener usuarios
        $sql = "
            SELECT id, username, email, role, email_verified, created_at, last_login, locked_until 
            FROM users 
            $whereClause
            ORDER BY created_at DESC 
            LIMIT ? OFFSET ?
        ";
        
        $users = $db->prepare($sql);
        
        // Añadir límite y offset a los parámetros
        $params[] = $limit;
        $params[] = $offset;
        
        $users->execute($params);
        $users = $users->fetchAll();
        
        // Contar total para paginación
        $countSql = "SELECT COUNT(*) as total FROM users $whereClause";
        $totalUsers = $db->prepare($countSql);
        
        // Remover límite y offset para el count
        $countParams = array_slice($params, 0, count($params) - 2);
        if (!empty($countParams)) {
            $totalUsers->execute($countParams);
        } else {
            $totalUsers->execute();
        }
        $totalUsers = $totalUsers->fetch()['total'];
        $totalPages = ceil($totalUsers / $limit);
        
        // Obtener logs de administración
        $admin_logs = $db->prepare("
            SELECT sl.*, u.username as admin_username, 
                   COALESCE(target_user.username, 'Sistema') as target_username,
                   sl.details, sl.admin_reason
            FROM security_logs sl 
            LEFT JOIN users u ON sl.user_id = u.id 
            LEFT JOIN users target_user ON sl.details LIKE CONCAT('%', target_user.id, '%')
            WHERE sl.action IN ('user_manually_blocked', 'user_unblocked', 'user_updated', 'post_deleted', 'comment_deleted', 'report_updated')
            ORDER BY sl.created_at DESC 
            LIMIT 20
        ");
        $admin_logs->execute();
        $admin_logs = $admin_logs->fetchAll();
        
        view('admin/users', [
            'users' => $users,
            'stats' => $stats,
            'admin_logs' => $admin_logs,
            'currentPage' => 'users',
            'pageTitle' => 'Gestión de Usuarios',
            'pageSubtitle' => 'Administrar usuarios del sistema',
            'pagination' => [
                'page' => $page,
                'totalPages' => $totalPages,
                'totalItems' => $totalUsers,
                'limit' => $limit
            ],
            'filters' => $_GET
        ]);
    }

    public static function unblockUser(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $user_id = $_POST['user_id'] ?? '';
            $reason = trim($_POST['reason'] ?? '');
            
            if (empty($user_id) || empty($reason)) {
                flash('error', 'Datos incompletos');
                redirect('admin/users');
                return;
            }
            
            // Desbloquear usuario
            $stmt = $db->prepare("UPDATE users SET locked_until = NULL WHERE id = ?");
            $stmt->execute([$user_id]);
            
            // Obtener username para el log
            $user_stmt = $db->prepare("SELECT username FROM users WHERE id = ?");
            $user_stmt->execute([$user_id]);
            $user = $user_stmt->fetch();
            $username = $user ? $user['username'] : $user_id;
            
            // Registrar en logs de seguridad con el motivo
            SecurityHelper::logSecurityEvent($db, 'user_unblocked', 
                "Usuario desbloqueado: $username (ID: $user_id)", 
                $_SESSION['user']['id'], 'medium', $reason);
            
            flash('success', 'Usuario desbloqueado correctamente');
            redirect('admin/users');
        }
    }
    
    public static function updateUser(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $user_id = $_POST['user_id'] ?? '';
            $role = $_POST['role'] ?? '';
            $email_verified = $_POST['email_verified'] ?? 0;
            $reason = trim($_POST['reason'] ?? '');
            
            if (empty($user_id) || empty($role) || empty($reason)) {
                flash('error', 'Datos incompletos');
                redirect('admin/users');
                return;
            }
            
            if (!in_array($role, ['user', 'moderator', 'admin'])) {
                flash('error', 'Rol no válido');
                redirect('admin/users');
                return;
            }
            
            // Obtener datos actuales para comparación
            $current_stmt = $db->prepare("SELECT role, email_verified FROM users WHERE id = ?");
            $current_stmt->execute([$user_id]);
            $current_data = $current_stmt->fetch();
            
            // Actualizar usuario
            $stmt = $db->prepare("UPDATE users SET role = ?, email_verified = ? WHERE id = ?");
            $stmt->execute([$role, $email_verified, $user_id]);
            
            // Obtener username para el log
            $user_stmt = $db->prepare("SELECT username FROM users WHERE id = ?");
            $user_stmt->execute([$user_id]);
            $user = $user_stmt->fetch();
            $username = $user ? $user['username'] : $user_id;
            
            // Preparar detalles del cambio
            $changes = [];
            if ($current_data['role'] !== $role) {
                $changes[] = "Rol: {$current_data['role']} → $role";
            }
            if ($current_data['email_verified'] != $email_verified) {
                $status = $email_verified ? "Verificado" : "No verificado";
                $changes[] = "Estado: $status";
            }
            
            $details = "Usuario actualizado: $username (ID: $user_id). " . implode(', ', $changes);
            
            // Registrar en logs de seguridad con el motivo
            SecurityHelper::logSecurityEvent($db, 'user_updated', 
                $details, 
                $_SESSION['user']['id'], 'medium', $reason);
            
            flash('success', 'Usuario actualizado correctamente');
            redirect('admin/users');
        }
    }

    public static function posts(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Obtener total de likes para estadísticas
        $totalLikes = $db->query("SELECT COUNT(*) as total FROM likes")->fetch()['total'];
        
        // Parámetros de paginación
        $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
        $limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 12;
        $offset = ($page - 1) * $limit;
        
        // Construir consulta con filtros
        $whereConditions = [];
        $params = [];
        $orderBy = "p.created_at DESC";
        
        if (!empty($_GET['author'])) {
            $whereConditions[] = "u.username LIKE ?";
            $params[] = '%' . $_GET['author'] . '%';
        }
        
        if (!empty($_GET['sort'])) {
            switch ($_GET['sort']) {
                case 'oldest':
                    $orderBy = "p.created_at ASC";
                    break;
                case 'popular':
                    $orderBy = "likes_count DESC, p.created_at DESC";
                    break;
                default:
                    $orderBy = "p.created_at DESC";
            }
        }
        
        $whereClause = $whereConditions ? 'WHERE ' . implode(' AND ', $whereConditions) : '';
        
        // Obtener publicaciones
        $posts = $db->prepare("
            SELECT p.*, u.username, 
                   (SELECT COUNT(*) FROM likes l WHERE l.post_id = p.id) as likes_count,
                   (SELECT COUNT(*) FROM comments c WHERE c.post_id = p.id) as comments_count,
                   (SELECT url FROM photos WHERE post_id = p.id LIMIT 1) as image_url
            FROM posts p 
            LEFT JOIN users u ON p.author_id = u.id 
            $whereClause
            ORDER BY $orderBy
            LIMIT ? OFFSET ?
        ");
        
        // Añadir límite y offset
        $params[] = $limit;
        $params[] = $offset;
        
        $posts->execute($params);
        $posts = $posts->fetchAll();
        
        // Contar total para paginación
        $totalPosts = $db->prepare("
            SELECT COUNT(*) as total 
            FROM posts p 
            LEFT JOIN users u ON p.author_id = u.id 
            $whereClause
        ");
        
        // Remover límite y offset para el count
        $countParams = array_slice($params, 0, count($params) - 2);
        if (!empty($countParams)) {
            $totalPosts->execute($countParams);
        } else {
            $totalPosts->execute();
        }
        $totalPosts = $totalPosts->fetch()['total'];
        $totalPages = ceil($totalPosts / $limit);
        
        view('admin/posts', [
            'posts' => $posts,
            'stats' => $stats,
            'totalLikes' => $totalLikes,
            'currentPage' => 'posts',
            'pageTitle' => 'Gestión de Publicaciones',
            'pageSubtitle' => 'Administrar publicaciones del sistema',
            'pagination' => [
                'page' => $page,
                'totalPages' => $totalPages,
                'totalItems' => $totalPosts,
                'limit' => $limit
            ],
            'filters' => $_GET
        ]);
    }

    public static function deletePost(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $post_id = $_POST['post_id'] ?? '';
            $reason = trim($_POST['reason'] ?? '');
            
            if (empty($post_id) || empty($reason)) {
                flash('error', 'Datos incompletos');
                redirect('admin/posts');
                return;
            }
            
            // Obtener información del post para el log
            $post_stmt = $db->prepare("SELECT p.*, u.username FROM posts p LEFT JOIN users u ON p.author_id = u.id WHERE p.id = ?");
            $post_stmt->execute([$post_id]);
            $post = $post_stmt->fetch();
            
            // Eliminar post y sus relaciones (likes, comentarios, fotos)
            $db->beginTransaction();
            
            try {
                // Eliminar likes
                $db->prepare("DELETE FROM likes WHERE post_id = ?")->execute([$post_id]);
                
                // Eliminar comentarios
                $db->prepare("DELETE FROM comments WHERE post_id = ?")->execute([$post_id]);
                
                // Eliminar fotos
                $photos = $db->prepare("SELECT * FROM photos WHERE post_id = ?");
                $photos->execute([$post_id]);
                $photos_data = $photos->fetchAll();
                
                // Aquí podrías añadir código para eliminar los archivos físicos si es necesario
                $db->prepare("DELETE FROM photos WHERE post_id = ?")->execute([$post_id]);
                
                // Eliminar tags
                $db->prepare("DELETE FROM tags WHERE post_id = ?")->execute([$post_id]);
                
                // Eliminar el post
                $db->prepare("DELETE FROM posts WHERE id = ?")->execute([$post_id]);
                
                $db->commit();
                
                // Registrar en logs de seguridad con el motivo
                $author = $post ? $post['username'] : 'Desconocido';
                SecurityHelper::logSecurityEvent($db, 'post_deleted', 
                    "Publicación eliminada: ID $post_id del usuario $author", 
                    $_SESSION['user']['id'], 'medium', $reason);
                
                flash('success', 'Publicación eliminada correctamente');
            } catch (Exception $e) {
                $db->rollBack();
                flash('error', 'Error al eliminar la publicación: ' . $e->getMessage());
            }
            
            redirect('admin/posts');
        }
    }

    public static function logs(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Parámetros de paginación
        $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
        $limit = 50;
        $offset = ($page - 1) * $limit;
        
        // Construir consulta con filtros
        $whereConditions = [];
        $params = [];
        
        if (!empty($_GET['action'])) {
            $whereConditions[] = "action = ?";
            $params[] = $_GET['action'];
        }
        
        if (!empty($_GET['severity'])) {
            $whereConditions[] = "severity = ?";
            $params[] = $_GET['severity'];
        }
        
        if (!empty($_GET['user'])) {
            $whereConditions[] = "username LIKE ?";
            $params[] = '%' . $_GET['user'] . '%';
        }
        
        $whereClause = $whereConditions ? 'WHERE ' . implode(' AND ', $whereConditions) : '';
        
        // Obtener logs
        $logs = $db->prepare("
            SELECT sl.*, u.username 
            FROM security_logs sl 
            LEFT JOIN users u ON sl.user_id = u.id 
            $whereClause
            ORDER BY sl.created_at DESC 
            LIMIT ? OFFSET ?
        ");
        
        // Añadir límite y offset
        $params[] = $limit;
        $params[] = $offset;
        
        $logs->execute($params);
        $logs = $logs->fetchAll();
        
        // Contar total para paginación
        $countQuery = $db->prepare("
            SELECT COUNT(*) as total 
            FROM security_logs sl 
            LEFT JOIN users u ON sl.user_id = u.id 
            $whereClause
        ");
        
        // Remover límite y offset para el count
        $countParams = array_slice($params, 0, count($params) - 2);
        if (!empty($countParams)) {
            $countQuery->execute($countParams);
        } else {
            $countQuery->execute();
        }
        $totalLogs = $countQuery->fetch()['total'];
        $totalPages = ceil($totalLogs / $limit);
        
        // Obtener acciones únicas para filtro
        $actions = $db->query("
            SELECT DISTINCT action 
            FROM security_logs 
            ORDER by action
        ")->fetchAll(PDO::FETCH_COLUMN);
        
        view('admin/logs', [
            'logs' => $logs,
            'stats' => $stats,
            'currentPage' => 'logs',
            'pageTitle' => 'Logs de Seguridad',
            'pageSubtitle' => 'Registros de actividad del sistema',
            'pagination' => [
                'page' => $page,
                'totalPages' => $totalPages,
                'totalItems' => $totalLogs,
                'limit' => $limit
            ],
            'filters' => $_GET,
            'actions' => $actions
        ]);
    }

    public static function loginAttempts(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Parámetros de paginación
        $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
        $limit = 50;
        $offset = ($page - 1) * $limit;
        
        // Construir consulta con filtros
        $whereConditions = ["locked_until > NOW()"];
        $params = [];
        
        if (!empty($_GET['status'])) {
            $whereConditions[] = "status = ?";
            $params[] = $_GET['status'];
        }
        
        if (!empty($_GET['ip'])) {
            $whereConditions[] = "ip LIKE ?";
            $params[] = '%' . $_GET['ip'] . '%';
        }
        
        $whereClause = 'WHERE ' . implode(' AND ', $whereConditions);
        
        // Obtener intentos
        $attempts = $db->prepare("
            SELECT * FROM login_attempts 
            $whereClause
            ORDER BY last_attempt DESC 
            LIMIT ? OFFSET ?
        ");
        
        // Añadir límite y offset
        $params[] = $limit;
        $params[] = $offset;
        
        $attempts->execute($params);
        $attempts = $attempts->fetchAll();
        
        // Contar total para paginación
        $totalAttempts = $db->prepare("SELECT COUNT(*) as total FROM login_attempts $whereClause");
        
        // Remover límite y offset para el count
        $countParams = array_slice($params, 0, count($params) - 2);
        if (!empty($countParams)) {
            $totalAttempts->execute($countParams);
        } else {
            $totalAttempts->execute();
        }
        $totalAttempts = $totalAttempts->fetch()['total'];
        $totalPages = ceil($totalAttempts / $limit);
        
        view('admin/login_attempts', [
            'attempts' => $attempts,
            'stats' => $stats,
            'currentPage' => 'login-attempts',
            'pageTitle' => 'Intentos de Login',
            'pageSubtitle' => 'Registro de intentos de acceso',
            'pagination' => [
                'page' => $page,
                'totalPages' => $totalPages,
                'totalItems' => $totalAttempts,
                'limit' => $limit
            ],
            'filters' => $_GET
        ]);
    }
    
    public static function reports(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Parámetros de paginación
        $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
        $limit = 20;
        $offset = ($page - 1) * $limit;
        
        // Construir consulta con filtros
        $whereConditions = [];
        $params = [];
        
        if (!empty($_GET['status'])) {
            $whereConditions[] = "r.status = ?";
            $params[] = $_GET['status'];
        }
        
        if (!empty($_GET['reason'])) {
            $whereConditions[] = "r.reason = ?";
            $params[] = $_GET['reason'];
        }
        
        if (!empty($_GET['type'])) {
            $whereConditions[] = "r.target_type = ?";
            $params[] = $_GET['type'];
        }
        
        if (!empty($_GET['q'])) {
            $whereConditions[] = "(r.id LIKE ? OR u.username LIKE ? OR ru.username LIKE ?)";
            $params[] = '%' . $_GET['q'] . '%';
            $params[] = '%' . $_GET['q'] . '%';
            $params[] = '%' . $_GET['q'] . '%';
        }
        
        $whereClause = $whereConditions ? 'WHERE ' . implode(' AND ', $whereConditions) : '';
        
        // Obtener reportes
        $reports = $db->prepare("
            SELECT r.*, u.username as reporter_username, 
                   ru.username as target_username,
                   p.caption as post_content
            FROM reports r 
            LEFT JOIN users u ON r.reporter_id = u.id 
            LEFT JOIN users ru ON r.target_id = ru.id AND r.target_type = 'user'
            LEFT JOIN posts p ON r.target_id = p.id AND r.target_type = 'post'
            $whereClause
            ORDER BY r.created_at DESC 
            LIMIT ? OFFSET ?
        ");
        
        // Añadir límite y offset
        $params[] = $limit;
        $params[] = $offset;
        
        $reports->execute($params);
        $reports = $reports->fetchAll();
        
        // Contar total para paginación
        $totalReports = $db->prepare("
            SELECT COUNT(*) as total 
            FROM reports r 
            LEFT JOIN users u ON r.reporter_id = u.id 
            $whereClause
        ");
        
        // Remover límite y offset para el count
        $countParams = array_slice($params, 0, count($params) - 2);
        if (!empty($countParams)) {
            $totalReports->execute($countParams);
        } else {
            $totalReports->execute();
        }
        $totalReports = $totalReports->fetch()['total'];
        $totalPages = ceil($totalReports / $limit);
        
        view('admin/reports', [
            'reports' => $reports,
            'stats' => $stats,
            'currentPage' => 'reports',
            'pageTitle' => 'Gestión de Reportes',
            'pageSubtitle' => 'Revisar y gestionar reportes de usuarios',
            'pagination' => [
                'page' => $page,
                'totalPages' => $totalPages,
                'totalItems' => $totalReports,
                'limit' => $limit
            ],
            'filters' => $_GET
        ]);
    }
    
    public static function updateReport(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $report_id = $_POST['report_id'] ?? '';
            $status = $_POST['status'] ?? '';
            $admin_notes = trim($_POST['admin_notes'] ?? '');
            
            if (empty($report_id) || empty($status)) {
                flash('error', 'Datos incompletos');
                redirect('admin/reports');
                return;
            }
            
            // Actualizar reporte
            $stmt = $db->prepare("UPDATE reports SET status = ?, admin_notes = ?, updated_at = NOW() WHERE id = ?");
            $stmt->execute([$status, $admin_notes, $report_id]);
            
            // Registrar en logs de seguridad
            SecurityHelper::logSecurityEvent($db, 'report_updated', 
                "Reporte actualizado: ID $report_id, estado: $status", 
                $_SESSION['user']['id'], 'low');
            
            flash('success', 'Reporte actualizado correctamente');
            redirect('admin/reports');
        }
    }
    
    public static function comments(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Parámetros de paginación
        $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
        $limit = 20;
        $offset = ($page - 1) * $limit;
        
        // Construir consulta con filtros
        $whereConditions = [];
        $params = [];
        
        if (!empty($_GET['author'])) {
            $whereConditions[] = "u.username LIKE ?";
            $params[] = '%' . $_GET['author'] . '%';
        }
        
        if (!empty($_GET['post'])) {
            $whereConditions[] = "p.id = ?";
            $params[] = $_GET['post'];
        }
        
        $whereClause = $whereConditions ? 'WHERE ' . implode(' AND ', $whereConditions) : '';
        
        // Obtener comentarios
        $comments = $db->prepare("
            SELECT c.*, u.username, p.id as post_id, p.caption as post_caption
            FROM comments c 
            LEFT JOIN users u ON c.user_id = u.id 
            LEFT JOIN posts p ON c.post_id = p.id 
            $whereClause
            ORDER BY c.created_at DESC 
            LIMIT ? OFFSET ?
        ");
        
        // Añadir límite y offset
        $params[] = $limit;
        $params[] = $offset;
        
        $comments->execute($params);
        $comments = $comments->fetchAll();
        
        // Contar total para paginación
        $totalComments = $db->prepare("
            SELECT COUNT(*) as total 
            FROM comments c 
            LEFT JOIN users u ON c.user_id = u.id 
            $whereClause
        ");
        
        // Remover límite y offset para el count
        $countParams = array_slice($params, 0, count($params) - 2);
        if (!empty($countParams)) {
            $totalComments->execute($countParams);
        } else {
            $totalComments->execute();
        }
        $totalComments = $totalComments->fetch()['total'];
        $totalPages = ceil($totalComments / $limit);
        
        view('admin/comments', [
            'comments' => $comments,
            'stats' => $stats,
            'currentPage' => 'comments',
            'pageTitle' => 'Gestión de Comentarios',
            'pageSubtitle' => 'Administrar comentarios del sistema',
            'pagination' => [
                'page' => $page,
                'totalPages' => $totalPages,
                'totalItems' => $totalComments,
                'limit' => $limit
            ],
            'filters' => $_GET
        ]);
    }
    
    public static function deleteComment(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $comment_id = $_POST['comment_id'] ?? '';
            $reason = trim($_POST['reason'] ?? '');
            
            if (empty($comment_id) || empty($reason)) {
                flash('error', 'Datos incompletos');
                redirect('admin/comments');
                return;
            }
            
            // Obtener información del comentario para el log
            $comment_stmt = $db->prepare("
                SELECT c.*, u.username 
                FROM comments c 
                LEFT JOIN users u ON c.user_id = u.id 
                WHERE c.id = ?
            ");
            $comment_stmt->execute([$comment_id]);
            $comment = $comment_stmt->fetch();
            
            // Eliminar comentario
            $stmt = $db->prepare("DELETE FROM comments WHERE id = ?");
            $stmt->execute([$comment_id]);
            
            // Registrar en logs de seguridad con el motivo
            $author = $comment ? $comment['username'] : 'Desconocido';
            SecurityHelper::logSecurityEvent($db, 'comment_deleted', 
                "Comentario eliminado: ID $comment_id del usuario $author", 
                $_SESSION['user']['id'], 'medium', $reason);
            
            flash('success', 'Comentario eliminado correctamente');
            redirect('admin/comments');
        }
    }
    
    // ===== FUNCIONES DE ANUNCIOS MEJORADAS =====
    
    public static function ads(PDO $db): void {
        self::ensureAdmin();
        
        $stats = self::getStats($db);
        
        // Parámetros de paginación
        $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
        $limit = 15;
        $offset = ($page - 1) * $limit;
        
        // Construir consulta con filtros
        $whereConditions = [];
        $params = [];
        
        if (!empty($_GET['status'])) {
            $whereConditions[] = "status = ?";
            $params[] = $_GET['status'];
        }
        
        if (!empty($_GET['advertiser'])) {
            $whereConditions[] = "advertiser LIKE ?";
            $params[] = '%' . $_GET['advertiser'] . '%';
        }
        
        $whereClause = $whereConditions ? 'WHERE ' . implode(' AND ', $whereConditions) : '';
        
        // Obtener anuncios (ACTUALIZADO para incluir todos los estados)
        $ads = $db->prepare("
            SELECT * FROM ads 
            $whereClause
            ORDER BY 
                CASE 
                    WHEN status = 'active' AND start_date <= NOW() AND end_date > NOW() THEN 1
                    WHEN status = 'pending' THEN 2
                    WHEN status = 'paused' THEN 3
                    WHEN status = 'expired' THEN 4
                    ELSE 5
                END,
                created_at DESC 
            LIMIT ? OFFSET ?
        ");
        
        // Añadir límite y offset
        $params[] = $limit;
        $params[] = $offset;
        
        $ads->execute($params);
        $ads = $ads->fetchAll();
        
        // Contar total para paginación
        $totalAds = $db->prepare("SELECT COUNT(*) as total FROM ads $whereClause");
        
        // Remover límite y offset para el count
        $countParams = array_slice($params, 0, count($params) - 2);
        if (!empty($countParams)) {
            $totalAds->execute($countParams);
        } else {
            $totalAds->execute();
        }
        $totalAds = $totalAds->fetch()['total'];
        $totalPages = ceil($totalAds / $limit);
        
        // Obtener estadísticas de anuncios usando función helper
        $adStats = getAdStats($db);
        
        view('admin/ads', [
            'ads' => $ads,
            'stats' => $stats,
            'adStats' => $adStats,
            'currentPage' => 'ads',
            'pageTitle' => 'Gestión de Anuncios',
            'pageSubtitle' => 'Administrar campañas publicitarias',
            'pagination' => [
                'page' => $page,
                'totalPages' => $totalPages,
                'totalItems' => $totalAds,
                'limit' => $limit
            ],
            'filters' => $_GET
        ]);
    }
    
    public static function createAd(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $title = trim($_POST['title'] ?? '');
            $description = trim($_POST['description'] ?? '');
            $target_url = trim($_POST['target_url'] ?? '');
            $advertiser = trim($_POST['advertiser'] ?? '');
            $budget = (float)($_POST['budget'] ?? 0);
            $start_date = $_POST['start_date'] ?? '';
            $end_date = $_POST['end_date'] ?? '';
            $max_impressions = !empty($_POST['max_impressions']) ? (int)$_POST['max_impressions'] : null;
            $target_audience = $_POST['target_audience'] ?? 'all';
            $status = $_POST['status'] ?? 'pending';
            
            // Validaciones básicas
            if (empty($title) || empty($target_url) || empty($advertiser)) {
                flash('error', 'Todos los campos obligatorios deben ser completados');
                redirect('admin/ads');
                return;
            }
            
            // Validar archivo de imagen
            if (!isset($_FILES['ad_image']) || $_FILES['ad_image']['error'] !== UPLOAD_ERR_OK) {
                flash('error', 'Debe seleccionar una imagen válida para el anuncio');
                redirect('admin/ads');
                return;
            }
            
            $imageFile = $_FILES['ad_image'];
            $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
            $maxSize = 2 * 1024 * 1024; // 2MB
            
            if (!in_array($imageFile['type'], $allowedTypes)) {
                flash('error', 'Formato de imagen no válido. Use JPG, PNG, GIF o WebP');
                redirect('admin/ads');
                return;
            }
            
            if ($imageFile['size'] > $maxSize) {
                flash('error', 'La imagen es demasiado grande. Máximo 2MB permitido');
                redirect('admin/ads');
                return;
            }
            
            // Crear directorio de anuncios si no existe
            $adsDir = $_SERVER['DOCUMENT_ROOT'] . '/uploads/ads';
            if (!is_dir($adsDir)) {
                mkdir($adsDir, 0755, true);
            }
            
            // Generar nombre único para la imagen
            $fileExtension = pathinfo($imageFile['name'], PATHINFO_EXTENSION);
            $fileName = 'ad_' . uniqid() . '_' . time() . '.' . $fileExtension;
            $imagePath = $adsDir . '/' . $fileName;
            
            // Mover archivo subido
            if (!move_uploaded_file($imageFile['tmp_name'], $imagePath)) {
                flash('error', 'Error al subir la imagen');
                redirect('admin/ads');
                return;
            }
            
            // Ruta relativa para la base de datos
            $image_url = '/uploads/ads/' . $fileName;
            
            if ($budget <= 0) {
                // Eliminar imagen subida si hay error
                if (file_exists($imagePath)) {
                    unlink($imagePath);
                }
                flash('error', 'El presupuesto debe ser mayor a 0');
                redirect('admin/ads');
                return;
            }
            
            if (empty($start_date) || empty($end_date)) {
                // Eliminar imagen subida si hay error
                if (file_exists($imagePath)) {
                    unlink($imagePath);
                }
                flash('error', 'Las fechas de inicio y fin son obligatorias');
                redirect('admin/ads');
                return;
            }
            
            if (strtotime($end_date) <= strtotime($start_date)) {
                // Eliminar imagen subida si hay error
                if (file_exists($imagePath)) {
                    unlink($imagePath);
                }
                flash('error', 'La fecha de fin debe ser posterior a la fecha de inicio');
                redirect('admin/ads');
                return;
            }
            
            // Determinar estado automáticamente basado en fechas (MEJORADO)
            $now = time();
            $start_timestamp = strtotime($start_date);
            $end_timestamp = strtotime($end_date);
            
            if ($now >= $start_timestamp && $now <= $end_timestamp) {
                $status = 'active';
            } elseif ($now < $start_timestamp) {
                $status = 'pending';
            } else {
                $status = 'expired';
            }
            
            // Insertar anuncio (created_by YA EXISTE en la tabla)
            $stmt = $db->prepare("
                INSERT INTO ads (title, description, image_url, target_url, advertiser, budget, start_date, end_date, max_impressions, target_audience, status, created_by)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ");
            
            try {
                $stmt->execute([
                    $title, $description, $image_url, $target_url, $advertiser, $budget,
                    $start_date, $end_date, $max_impressions, $target_audience, $status, $_SESSION['user']['id']
                ]);
                
                // Registrar en logs de seguridad
                SecurityHelper::logSecurityEvent($db, 'ad_created', 
                    "Anuncio creado: $title para $advertiser (Estado: $status)", 
                    $_SESSION['user']['id'], 'low');
                
                flash('success', 'Anuncio creado correctamente con estado: ' . $status);
            } catch (Exception $e) {
                // Eliminar imagen si hay error en la base de datos
                if (file_exists($imagePath)) {
                    unlink($imagePath);
                }
                flash('error', 'Error al crear el anuncio: ' . $e->getMessage());
            }
            
            redirect('admin/ads');
        }
    }
    
    public static function editAd(PDO $db): void {
        self::ensureAdmin();
        
        $ad_id = $_GET['id'] ?? '';
        if (empty($ad_id)) {
            flash('error', 'ID de anuncio no válido');
            redirect('admin/ads');
            return;
        }
        
        // Obtener información del anuncio
        $stmt = $db->prepare("SELECT * FROM ads WHERE id = ?");
        $stmt->execute([$ad_id]);
        $ad = $stmt->fetch();
        
        if (!$ad) {
            flash('error', 'Anuncio no encontrado');
            redirect('admin/ads');
            return;
        }
        
        $stats = self::getStats($db);
        
        view('admin/edit-ad', [
            'ad' => $ad,
            'stats' => $stats,
            'currentPage' => 'ads',
            'pageTitle' => 'Editar Anuncio',
            'pageSubtitle' => 'Modificar campaña publicitaria'
        ]);
    }
    
    public static function updateAd(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $ad_id = $_POST['ad_id'] ?? '';
            $title = trim($_POST['title'] ?? '');
            $description = trim($_POST['description'] ?? '');
            $target_url = trim($_POST['target_url'] ?? '');
            $advertiser = trim($_POST['advertiser'] ?? '');
            $budget = (float)($_POST['budget'] ?? 0);
            $start_date = $_POST['start_date'] ?? '';
            $end_date = $_POST['end_date'] ?? '';
            $max_impressions = !empty($_POST['max_impressions']) ? (int)$_POST['max_impressions'] : null;
            $target_audience = $_POST['target_audience'] ?? 'all';
            $status = $_POST['status'] ?? 'active';
            
            // Validaciones básicas
            if (empty($ad_id) || empty($title) || empty($target_url) || empty($advertiser)) {
                flash('error', 'Todos los campos obligatorios deben ser completados');
                redirect('admin/ads');
                return;
            }
            
            if ($budget <= 0) {
                flash('error', 'El presupuesto debe ser mayor a 0');
                redirect('admin/ads');
                return;
            }
            
            if (empty($start_date) || empty($end_date)) {
                flash('error', 'Las fechas de inicio y fin son obligatorias');
                redirect('admin/ads');
                return;
            }
            
            // Verificar que el anuncio existe
            $check_stmt = $db->prepare("SELECT id, image_url FROM ads WHERE id = ?");
            $check_stmt->execute([$ad_id]);
            $existing_ad = $check_stmt->fetch();
            
            if (!$existing_ad) {
                flash('error', 'Anuncio no encontrado');
                redirect('admin/ads');
                return;
            }
            
            $image_url = $existing_ad['image_url'];
            
            // Manejar nueva imagen si se subió
            if (isset($_FILES['ad_image']) && $_FILES['ad_image']['error'] === UPLOAD_ERR_OK) {
                $imageFile = $_FILES['ad_image'];
                $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
                $maxSize = 2 * 1024 * 1024; // 2MB
                
                if (!in_array($imageFile['type'], $allowedTypes)) {
                    flash('error', 'Formato de imagen no válido. Use JPG, PNG, GIF o WebP');
                    redirect('admin/ads');
                    return;
                }
                
                if ($imageFile['size'] > $maxSize) {
                    flash('error', 'La imagen es demasiado grande. Máximo 2MB permitido');
                    redirect('admin/ads');
                    return;
                }
                
                // Crear directorio de anuncios si no existe
                $adsDir = $_SERVER['DOCUMENT_ROOT'] . '/uploads/ads';
                if (!is_dir($adsDir)) {
                    mkdir($adsDir, 0755, true);
                }
                
                // Generar nombre único para la nueva imagen
                $fileExtension = pathinfo($imageFile['name'], PATHINFO_EXTENSION);
                $fileName = 'ad_' . uniqid() . '_' . time() . '.' . $fileExtension;
                $imagePath = $adsDir . '/' . $fileName;
                
                // Mover archivo subido
                if (!move_uploaded_file($imageFile['tmp_name'], $imagePath)) {
                    flash('error', 'Error al subir la nueva imagen');
                    redirect('admin/ads');
                    return;
                }
                
                // Eliminar imagen anterior si existe
                $oldImagePath = $_SERVER['DOCUMENT_ROOT'] . $existing_ad['image_url'];
                if (file_exists($oldImagePath) && strpos($existing_ad['image_url'], '/uploads/ads/') === 0) {
                    unlink($oldImagePath);
                }
                
                $image_url = '/uploads/ads/' . $fileName;
            }
            
            // Actualizar estado automáticamente si es necesario (MEJORADO)
            $now = time();
            $start_timestamp = strtotime($start_date);
            $end_timestamp = strtotime($end_date);
            
            if ($status !== 'paused') {
                if ($now >= $start_timestamp && $now <= $end_timestamp) {
                    $status = 'active';
                } elseif ($now < $start_timestamp) {
                    $status = 'pending';
                } else {
                    $status = 'expired';
                }
            }
            
            // Actualizar anuncio
            $stmt = $db->prepare("
                UPDATE ads SET 
                    title = ?, description = ?, image_url = ?, target_url = ?, 
                    advertiser = ?, budget = ?, start_date = ?, end_date = ?, 
                    max_impressions = ?, target_audience = ?, status = ?
                WHERE id = ?
            ");
            
            try {
                $stmt->execute([
                    $title, $description, $image_url, $target_url, $advertiser, $budget,
                    $start_date, $end_date, $max_impressions, $target_audience, $status, $ad_id
                ]);
                
                // Registrar en logs de seguridad
                SecurityHelper::logSecurityEvent($db, 'ad_updated', 
                    "Anuncio actualizado: $title para $advertiser (Estado: $status)", 
                    $_SESSION['user']['id'], 'low');
                
                flash('success', 'Anuncio actualizado correctamente. Estado: ' . $status);
            } catch (Exception $e) {
                flash('error', 'Error al actualizar el anuncio: ' . $e->getMessage());
            }
            
            redirect('admin/ads');
        }
    }
    
    public static function updateAdStatus(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $ad_id = $_POST['ad_id'] ?? '';
            $status = $_POST['status'] ?? '';
            
            if (empty($ad_id) || empty($status)) {
                flash('error', 'Datos incompletos');
                redirect('admin/ads');
                return;
            }
            
            if (!in_array($status, ['active', 'paused', 'pending', 'expired'])) {
                flash('error', 'Estado no válido');
                redirect('admin/ads');
                return;
            }
            
            // Si se activa un anuncio, verificar fechas (MEJORADO)
            if ($status === 'active') {
                $ad_stmt = $db->prepare("SELECT start_date, end_date FROM ads WHERE id = ?");
                $ad_stmt->execute([$ad_id]);
                $ad = $ad_stmt->fetch();
                
                if ($ad) {
                    $now = time();
                    $start = strtotime($ad['start_date']);
                    $end = strtotime($ad['end_date']);
                    
                    if ($now < $start) {
                        flash('warning', 'El anuncio se activará automáticamente cuando llegue su fecha de inicio');
                        $status = 'pending';
                    } elseif ($now > $end) {
                        flash('error', 'No se puede activar un anuncio que ya ha expirado');
                        redirect('admin/ads');
                        return;
                    }
                }
            }
            
            // Actualizar estado
            $stmt = $db->prepare("UPDATE ads SET status = ? WHERE id = ?");
            $stmt->execute([$status, $ad_id]);
            
            // Registrar en logs de seguridad
            SecurityHelper::logSecurityEvent($db, 'ad_status_updated', 
                "Estado de anuncio actualizado: ID $ad_id a $status", 
                $_SESSION['user']['id'], 'low');
            
            flash('success', 'Estado del anuncio actualizado correctamente');
            redirect('admin/ads');
        }
    }
    
    public static function deleteAd(PDO $db): void {
        self::ensureAdmin();
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            validate_csrf();
            
            $ad_id = $_POST['ad_id'] ?? '';
            $reason = trim($_POST['reason'] ?? '');
            
            if (empty($ad_id) || empty($reason)) {
                flash('error', 'Datos incompletos');
                redirect('admin/ads');
                return;
            }
            
            // Obtener información del anuncio para el log y eliminar imagen
            $ad_stmt = $db->prepare("SELECT title, advertiser, image_url FROM ads WHERE id = ?");
            $ad_stmt->execute([$ad_id]);
            $ad = $ad_stmt->fetch();
            
            // Eliminar imagen del servidor si existe
            if ($ad && strpos($ad['image_url'], '/uploads/ads/') === 0) {
                $imagePath = $_SERVER['DOCUMENT_ROOT'] . $ad['image_url'];
                if (file_exists($imagePath)) {
                    unlink($imagePath);
                }
            }
            
            // Eliminar anuncio de la base de datos
            $stmt = $db->prepare("DELETE FROM ads WHERE id = ?");
            $stmt->execute([$ad_id]);
            
            // Registrar en logs de seguridad con el motivo
            $title = $ad ? $ad['title'] : 'Desconocido';
            $advertiser = $ad ? $ad['advertiser'] : 'Desconocido';
            SecurityHelper::logSecurityEvent($db, 'ad_deleted', 
                "Anuncio eliminado: $title de $advertiser", 
                $_SESSION['user']['id'], 'medium', $reason);
            
            flash('success', 'Anuncio eliminado correctamente');
            redirect('admin/ads');
        }
    }
    
    // ===== FUNCIONES AUXILIARES MEJORADAS =====
    
    /**
     * Obtener anuncios activos para dashboard (ACTUALIZADO)
     */
    public static function getActiveAds(PDO $db, $user_id = null): array {
        try {
            // Primero actualizar estados automáticamente
            updateAdStatusAutomatically($db);
            
            $stmt = $db->prepare("
                SELECT * FROM ads 
                WHERE status = 'active' 
                AND start_date <= NOW() 
                AND end_date > NOW()
                AND (max_impressions IS NULL OR impressions < max_impressions)
                ORDER BY created_at DESC
                LIMIT 5
            ");
            $stmt->execute();
            return $stmt->fetchAll();
        } catch (Exception $e) {
            error_log("❌ Error obteniendo anuncios activos: " . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Forzar actualización de estados de anuncios (NUEVO)
     */
    public static function forceRefreshAdStatuses(PDO $db): bool {
        try {
            return updateAdStatusAutomatically($db);
        } catch (Exception $e) {
            error_log("❌ Error forzando actualización de estados: " . $e->getMessage());
            return false;
        }
    }
}