<?php
require_once __DIR__ . '/../middleware/AuthMiddleware.php';
require_once __DIR__ . '/../middleware/RoleMiddleware.php';
require_once __DIR__ . '/../utils/SecurityLogger.php';
require_once __DIR__ . '/../utils/SecureFileManager.php';

class SecurityController {
    private $fileManager;
    
    public function __construct() {
        $this->fileManager = new SecureFileManager();
    }
    
    // GET /api/security/stats - Obtener estadísticas de seguridad
    public function getSecurityStats() {
        try {
            // Solo administradores pueden ver estadísticas de seguridad
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador']);
            
            $days = $_GET['days'] ?? 7;
            $stats = SecurityLogger::getSecurityStats($days);
            
            http_response_code(200);
            return json_encode([
                'success' => true,
                'data' => $stats
            ]);
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al obtener estadísticas: ' . $e->getMessage()
            ]);
        }
    }
    
    // POST /api/security/cleanup - Limpiar archivos huérfanos y logs antiguos
    public function cleanup() {
        try {
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador']);
            
            $results = [
                'orphaned_files' => 0,
                'old_logs' => 0,
                'errors' => []
            ];
            
            // Obtener lista de archivos válidos de la base de datos
            $validFiles = $this->getValidFileNames();
            
            // Limpiar archivos huérfanos
            try {
                $results['orphaned_files'] = $this->fileManager->cleanOrphanedFiles($validFiles);
            } catch (Exception $e) {
                $results['errors'][] = 'Error limpiando archivos huérfanos: ' . $e->getMessage();
            }
            
            // Limpiar logs antiguos (mantener 30 días)
            try {
                SecurityLogger::cleanOldLogs(30);
                $results['old_logs'] = 'Logs antiguos eliminados';
            } catch (Exception $e) {
                $results['errors'][] = 'Error limpiando logs: ' . $e->getMessage();
            }
            
            SecurityLogger::logSystemError('Security cleanup executed by user ' . $user['user_id'], $results);
            
            http_response_code(200);
            return json_encode([
                'success' => true,
                'data' => $results
            ]);
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error en limpieza: ' . $e->getMessage()
            ]);
        }
    }
    
    // GET /api/security/audit - Auditoría de seguridad del sistema
    public function audit() {
        try {
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador']);
            
            $audit = [
                'timestamp' => date('Y-m-d H:i:s'),
                'directories' => $this->auditDirectories(),
                'files' => $this->auditFiles(),
                'permissions' => $this->auditPermissions(),
                'configuration' => $this->auditConfiguration(),
                'security_score' => 0
            ];
            
            // Calcular puntuación de seguridad
            $audit['security_score'] = $this->calculateSecurityScore($audit);
            
            SecurityLogger::logSystemError('Security audit performed by user ' . $user['user_id'], $audit);
            
            http_response_code(200);
            return json_encode([
                'success' => true,
                'data' => $audit
            ]);
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error en auditoría: ' . $e->getMessage()
            ]);
        }
    }
    
    /**
     * Obtener nombres de archivos válidos de la base de datos
     */
    private function getValidFileNames() {
        try {
            require_once __DIR__ . '/../config/database.php';
            $database = new Database();
            $pdo = $database->getConnection();
            
            $stmt = $pdo->query("
                SELECT doc_tenencia_path, doc_regencia_path 
                FROM proyectos 
                WHERE doc_tenencia_path IS NOT NULL 
                   OR doc_regencia_path IS NOT NULL
            ");
            
            $validFiles = [];
            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                if ($row['doc_tenencia_path']) {
                    $validFiles[] = basename($row['doc_tenencia_path']);
                }
                if ($row['doc_regencia_path']) {
                    $validFiles[] = basename($row['doc_regencia_path']);
                }
            }
            
            return $validFiles;
            
        } catch (Exception $e) {
            SecurityLogger::logSystemError('Error getting valid file names: ' . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Auditar directorios del sistema
     */
    private function auditDirectories() {
        $directories = [
            'uploads/documents' => __DIR__ . '/../../uploads/documents/',
            'logs' => __DIR__ . '/../../logs/',
            'api/config' => __DIR__ . '/../config/'
        ];
        
        $results = [];
        
        foreach ($directories as $name => $path) {
            $results[$name] = [
                'exists' => is_dir($path),
                'writable' => is_writable($path),
                'protected' => file_exists($path . '.htaccess') || file_exists($path . 'index.php'),
                'permissions' => is_dir($path) ? substr(sprintf('%o', fileperms($path)), -4) : null
            ];
        }
        
        return $results;
    }
    
    /**
     * Auditar archivos críticos
     */
    private function auditFiles() {
        $files = [
            '.htaccess' => __DIR__ . '/../../.htaccess',
            'install.php' => __DIR__ . '/../../install.php',
            'api/config/database.php' => __DIR__ . '/../config/database.php'
        ];
        
        $results = [];
        
        foreach ($files as $name => $path) {
            $results[$name] = [
                'exists' => file_exists($path),
                'readable' => is_readable($path),
                'writable' => is_writable($path),
                'size' => file_exists($path) ? filesize($path) : 0,
                'modified' => file_exists($path) ? date('Y-m-d H:i:s', filemtime($path)) : null
            ];
        }
        
        return $results;
    }
    
    /**
     * Auditar permisos del sistema
     */
    private function auditPermissions() {
        $checks = [
            'php_version' => PHP_VERSION,
            'extensions' => [
                'pdo' => extension_loaded('pdo'),
                'pdo_mysql' => extension_loaded('pdo_mysql'),
                'fileinfo' => extension_loaded('fileinfo'),
                'openssl' => extension_loaded('openssl')
            ],
            'functions' => [
                'file_get_contents' => function_exists('file_get_contents'),
                'finfo_open' => function_exists('finfo_open'),
                'password_hash' => function_exists('password_hash'),
                'openssl_random_pseudo_bytes' => function_exists('openssl_random_pseudo_bytes')
            ],
            'ini_settings' => [
                'file_uploads' => ini_get('file_uploads'),
                'upload_max_filesize' => ini_get('upload_max_filesize'),
                'post_max_size' => ini_get('post_max_size'),
                'max_execution_time' => ini_get('max_execution_time'),
                'memory_limit' => ini_get('memory_limit')
            ]
        ];
        
        return $checks;
    }
    
    /**
     * Auditar configuración de seguridad
     */
    private function auditConfiguration() {
        $config = [
            'https_enabled' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on',
            'secure_headers' => $this->checkSecureHeaders(),
            'error_reporting' => ini_get('display_errors') == '0',
            'session_security' => [
                'cookie_secure' => ini_get('session.cookie_secure'),
                'cookie_httponly' => ini_get('session.cookie_httponly'),
                'use_strict_mode' => ini_get('session.use_strict_mode')
            ]
        ];
        
        return $config;
    }
    
    /**
     * Verificar headers de seguridad
     */
    private function checkSecureHeaders() {
        // Esta función verificaría si los headers de seguridad están configurados
        // En un entorno real, esto requeriría hacer una petición HTTP para verificar
        return [
            'x_content_type_options' => 'configured_in_htaccess',
            'x_frame_options' => 'configured_in_htaccess',
            'x_xss_protection' => 'configured_in_htaccess',
            'content_security_policy' => 'configured_in_htaccess'
        ];
    }
    
    /**
     * Calcular puntuación de seguridad
     */
    private function calculateSecurityScore($audit) {
        $score = 100;
        
        // Verificar directorios
        foreach ($audit['directories'] as $dir => $info) {
            if (!$info['exists']) $score -= 10;
            if (!$info['protected']) $score -= 15;
        }
        
        // Verificar archivos críticos
        foreach ($audit['files'] as $file => $info) {
            if (!$info['exists']) $score -= 5;
        }
        
        // Verificar extensiones PHP
        foreach ($audit['permissions']['extensions'] as $ext => $loaded) {
            if (!$loaded) $score -= 5;
        }
        
        // Verificar configuración
        if (!$audit['configuration']['error_reporting']) $score -= 10;
        
        return max(0, $score);
    }
}