<?php

declare(strict_types=1);

namespace App\Controllers;

require_once __DIR__ . '/../Services/Security/AlertService.php';
require_once __DIR__ . '/../Services/Security/SecurityMonitor.php';
require_once __DIR__ . '/../Services/Security/PerformanceMonitor.php';
require_once __DIR__ . '/../Services/Security/IPBlocker.php';
require_once __DIR__ . '/../Services/Security/EmailThrottler.php';

use App\Services\Security\AlertService;
use App\Services\Security\SecurityMonitor;
use App\Services\Security\PerformanceMonitor;
use App\Services\Security\IPBlocker;
use App\Services\Security\EmailThrottler;
use Database;
use Session;
use Response;
use Request;

class SecurityController {
    
    /**
     * Obtenir les métriques de performance
     * GET /api/admin/metrics
     */
    public function getMetrics(): void {
        // Vérifier l'authentification et les droits admin
        if (!Session::isLoggedIn() || Session::getRole() < 2) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        $endpoint = Request::getQuery('endpoint');
        $hours = (int)(Request::getQuery('hours') ?? 24);
        
        $stats = PerformanceMonitor::getStats($endpoint, $hours);
        
        Response::json([
            'success' => true,
            'data' => $stats
        ]);
    }
    
    /**
     * Obtenir les alertes actives
     * GET /api/admin/alerts
     */
    public function getAlerts(): void {
        // Vérifier l'authentification et les droits admin
        if (!Session::isLoggedIn() || Session::getRole() < 2) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        $limit = (int)(Request::getQuery('limit') ?? 50);
        $alerts = AlertService::getActiveAlerts($limit);
        
        Response::json([
            'success' => true,
            'data' => $alerts
        ]);
    }
    
    /**
     * Résoudre une alerte
     * POST /api/admin/alerts/:id/resolve
     */
    public function resolveAlert(string $id): void {
        // Vérifier l'authentification et les droits admin
        if (!Session::isLoggedIn() || Session::getRole() < 2) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        $data = Request::getJson();
        $notes = $data['notes'] ?? '';
        $userId = Session::getUserId();
        
        $success = AlertService::resolve((int)$id, $userId, $notes);
        
        Response::json([
            'success' => $success,
            'message' => $success ? 'Alerte résolue' : 'Erreur lors de la résolution'
        ]);
    }
    
    /**
     * Obtenir les IPs bloquées
     * GET /api/admin/blocked-ips
     */
    public function getBlockedIPs(): void {
        // Vérifier l'authentification et les droits admin
        if (!Session::isLoggedIn() || Session::getRole() < 2) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        $activeOnly = Request::getQuery('active_only') !== 'false';
        $ips = IPBlocker::getBlockedIPs($activeOnly);
        
        Response::json([
            'success' => true,
            'data' => $ips
        ]);
    }
    
    /**
     * Débloquer une IP
     * POST /api/admin/unblock-ip
     */
    public function unblockIP(): void {
        // Vérifier l'authentification et les droits admin
        if (!Session::isLoggedIn() || Session::getRole() < 2) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        $data = Request::getJson();
        
        if (!isset($data['ip'])) {
            Response::json(['error' => 'IP address required'], 400);
            return;
        }
        
        $userId = Session::getUserId();
        $success = IPBlocker::unblock($data['ip'], $userId);
        
        Response::json([
            'success' => $success,
            'message' => $success ? 'IP débloquée' : 'Erreur lors du déblocage'
        ]);
    }
    
    /**
     * Bloquer une IP manuellement
     * POST /api/admin/block-ip
     */
    public function blockIP(): void {
        // Vérifier l'authentification et les droits admin
        if (!Session::isLoggedIn() || Session::getRole() < 2) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        $data = Request::getJson();
        
        if (!isset($data['ip'])) {
            Response::json(['error' => 'IP address required'], 400);
            return;
        }
        
        $reason = $data['reason'] ?? 'Blocked by admin';
        $duration = (int)($data['duration'] ?? 3600);
        $permanent = $data['permanent'] ?? false;
        
        if ($permanent) {
            $success = IPBlocker::blockPermanent($data['ip'], $reason, 'admin_' . Session::getUserId());
        } else {
            $success = IPBlocker::block($data['ip'], $duration, $reason, 'admin_' . Session::getUserId());
        }
        
        Response::json([
            'success' => $success,
            'message' => $success ? 'IP bloquée' : 'Erreur lors du blocage'
        ]);
    }
    
    /**
     * Obtenir le rapport de sécurité
     * GET /api/admin/security-report
     */
    public function getSecurityReport(): void {
        // Vérifier l'authentification et les droits admin
        if (!Session::isLoggedIn() || Session::getRole() < 2) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        // Compiler le rapport
        $report = [
            'security_stats' => SecurityMonitor::getSecurityStats(),
            'performance_stats' => PerformanceMonitor::getStats(null, 24),
            'blocked_ips_stats' => IPBlocker::getStats(),
            'email_throttle_stats' => (new EmailThrottler())->getStats(),
            'recent_alerts' => AlertService::getActiveAlerts(10)
        ];
        
        Response::json([
            'success' => true,
            'data' => $report,
            'generated_at' => date('Y-m-d H:i:s')
        ]);
    }
    
    /**
     * Nettoyer les anciennes données
     * POST /api/admin/cleanup
     */
    public function cleanup(): void {
        // Vérifier l'authentification et les droits super admin
        if (!Session::isLoggedIn() || Session::getRole() < 9) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        $data = Request::getJson();
        $daysToKeep = (int)($data['days_to_keep'] ?? 30);
        
        // Nettoyer les métriques de performance
        $cleanedMetrics = PerformanceMonitor::cleanup($daysToKeep);
        
        // Nettoyer les IPs expirées
        $cleanedIPs = IPBlocker::cleanupExpired();
        
        Response::json([
            'success' => true,
            'message' => 'Nettoyage effectué',
            'cleaned' => [
                'performance_metrics' => $cleanedMetrics,
                'expired_ips' => $cleanedIPs
            ]
        ]);
    }
    
    /**
     * Tester les alertes email
     * POST /api/admin/test-alert
     */
    public function testAlert(): void {
        // Vérifier l'authentification et les droits super admin
        if (!Session::isLoggedIn() || Session::getRole() < 9) {
            Response::json(['error' => 'Unauthorized'], 401);
            return;
        }
        
        // Déclencher une alerte de test
        AlertService::trigger('TEST_ALERT', [
            'message' => 'Ceci est une alerte de test déclenchée manuellement',
            'triggered_by' => Session::getUsername(),
            'timestamp' => date('Y-m-d H:i:s')
        ], 'INFO');
        
        Response::json([
            'success' => true,
            'message' => 'Alerte de test envoyée'
        ]);
    }
}