<?php

declare(strict_types=1);

namespace App\Controllers;

require_once __DIR__ . '/../Services/LogService.php';
require_once __DIR__ . '/../Services/ApiService.php';

use PDO;
use PDOException;
use Database;
use AppConfig;
use Request;
use Response;
use Session;
use App\Services\LogService;
use App\Services\ApiService;
use Exception;

class FileController {
    private PDO $db;
    private AppConfig $appConfig;

    // Catégories autorisées par type de support
    private const FILE_CATEGORIES = [
        'entite' => ['logo', 'document', 'reglement', 'statut'],
        'user' => ['avatar', 'photo'],
        'operation' => ['planning', 'liste', 'export', 'backup'],
        'passage' => ['recu', 'photo', 'justificatif', 'carte']
    ];

    // Extensions autorisées
    private const ALLOWED_EXTENSIONS = [
        'pdf',
        'jpg',
        'jpeg',
        'png',
        'gif',
        'webp',
        'xlsx',
        'xls',
        'json',
        'csv'
    ];

    public function __construct() {
        $this->db = Database::getInstance();
        $this->appConfig = AppConfig::getInstance();
    }

    /**
     * Récupère les informations utilisateur (rôle et entité)
     */
    private function getUserInfo(int $userId): ?array {
        try {
            $stmt = $this->db->prepare('SELECT fk_entite, fk_role FROM users WHERE id = ?');
            $stmt->execute([$userId]);
            return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
        } catch (Exception $e) {
            LogService::log('Erreur lors de la récupération des infos utilisateur', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'userId' => $userId
            ]);
            return null;
        }
    }

    /**
     * Valide qu'un chemin est autorisé pour l'utilisateur
     */
    private function validatePath(string $path, int $userRole, int $userEntiteId): bool {
        // Empêcher les traversées de répertoire
        if (strpos($path, '..') !== false || strpos($path, './') !== false) {
            return false;
        }

        // Normaliser le chemin
        $path = trim($path, '/');

        // Super admin : accès total
        if ($userRole > 2) {
            return true;
        }

        // Admin entité : limité à son entité
        if ($userRole == 2) {
            return strpos($path, "entites/{$userEntiteId}") === 0 || $path === "entites/{$userEntiteId}";
        }

        return false;
    }

    /**
     * Vérifie si l'utilisateur peut accéder à un fichier
     */
    private function canAccessFile(int $fileId, int $userRole, int $userEntiteId): bool {
        try {
            $stmt = $this->db->prepare('SELECT fk_entite FROM medias WHERE id = ?');
            $stmt->execute([$fileId]);
            $file = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$file) {
                return false;
            }

            // Super admin : accès total
            if ($userRole > 2) {
                return true;
            }

            // Admin entité : seulement ses fichiers
            return (int)$file['fk_entite'] === $userEntiteId;
        } catch (Exception $e) {
            LogService::log('Erreur lors de la vérification d\'accès au fichier', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'fileId' => $fileId,
                'userId' => Session::getUserId()
            ]);
            return false;
        }
    }

    /**
     * Extrait et valide les paramètres de filtrage
     */
    private function extractFilters(array $params): array {
        return [
            'page' => max(1, (int)($params['page'] ?? 1)),
            'per_page' => min(100, max(1, (int)($params['per_page'] ?? 50))),
            'search' => !empty($params['search']) ? trim($params['search']) : null,
            'type' => !empty($params['type']) && in_array($params['type'], self::ALLOWED_EXTENSIONS) ? $params['type'] : null,
            'category' => !empty($params['category']) ? trim($params['category']) : null,
            'sort' => in_array($params['sort'] ?? '', ['name', 'date', 'size', 'type']) ? $params['sort'] : 'date',
            'order' => in_array($params['order'] ?? '', ['asc', 'desc']) ? $params['order'] : 'desc'
        ];
    }

    /**
     * Construit la clause WHERE pour les requêtes de recherche
     */
    private function buildWhereClause(array $filters, int $userRole, int $userEntiteId, ?string $path = null): array {
        $conditions = [];
        $params = [];

        // Restriction par entité selon le rôle
        if ($userRole == 2) {
            $conditions[] = 'm.fk_entite = ?';
            $params[] = $userEntiteId;
        }

        // Filtrage par chemin si spécifié
        if ($path !== null) {
            $conditions[] = 'm.file_path LIKE ?';
            $params[] = "uploads/{$path}%";
        }

        // Recherche textuelle
        if ($filters['search']) {
            $searchTerm = '%' . $filters['search'] . '%';
            $conditions[] = '(m.fichier LIKE ? OR m.original_name LIKE ? OR m.description LIKE ?)';
            $params[] = $searchTerm;
            $params[] = $searchTerm;
            $params[] = $searchTerm;
        }

        // Filtrage par type (extension)
        if ($filters['type']) {
            $conditions[] = 'm.file_type = ?';
            $params[] = $filters['type'];
        }

        // Filtrage par catégorie
        if ($filters['category']) {
            $conditions[] = 'm.file_category = ?';
            $params[] = $filters['category'];
        }

        $whereClause = !empty($conditions) ? 'WHERE ' . implode(' AND ', $conditions) : '';

        return [$whereClause, $params];
    }

    /**
     * Construit la clause ORDER BY
     */
    private function buildOrderClause(array $filters): string {
        $sortField = match ($filters['sort']) {
            'name' => 'm.original_name',
            'size' => 'm.file_size',
            'type' => 'm.file_type',
            default => 'm.created_at'
        };

        return "ORDER BY {$sortField} {$filters['order']}";
    }

    /**
     * Navigation dans l'arborescence avec recherche et pagination
     */
    public function browse(): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            $userInfo = $this->getUserInfo($userId);
            if (!$userInfo) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Informations utilisateur non trouvées'
                ], 404);
                return;
            }

            $userRole = (int)$userInfo['fk_role'];
            $userEntiteId = (int)$userInfo['fk_entite'];

            $path = $_GET['path'] ?? '';
            $filters = $this->extractFilters($_GET);

            // Validation du chemin
            if (!$this->validatePath($path, $userRole, $userEntiteId)) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Accès refusé à ce répertoire'
                ], 403);
                return;
            }

            // Construction de la requête
            [$whereClause, $params] = $this->buildWhereClause($filters, $userRole, $userEntiteId, $path);
            $orderClause = $this->buildOrderClause($filters);

            // Requête pour compter le total
            $countSql = "
                SELECT COUNT(*) as total
                FROM medias m
                {$whereClause}
            ";

            $stmt = $this->db->prepare($countSql);
            $stmt->execute($params);
            $totalItems = (int)$stmt->fetchColumn();

            // Calcul de la pagination
            $totalPages = ceil($totalItems / $filters['per_page']);
            $offset = ($filters['page'] - 1) * $filters['per_page'];

            // Requête principale avec pagination
            $sql = "
                SELECT 
                    m.id, m.fichier, m.original_name, m.file_type, m.file_category,
                    m.file_size, m.file_path, m.description, m.created_at,
                    m.fk_user_creat, u.encrypted_name as creator_name
                FROM medias m
                LEFT JOIN users u ON u.id = m.fk_user_creat
                {$whereClause}
                {$orderClause}
                LIMIT ? OFFSET ?
            ";

            $params[] = $filters['per_page'];
            $params[] = $offset;

            $stmt = $this->db->prepare($sql);
            $stmt->execute($params);
            $files = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Déchiffrer les noms des créateurs
            foreach ($files as &$file) {
                if ($file['creator_name']) {
                    $file['creator_name'] = ApiService::decryptData($file['creator_name']);
                }
                unset($file['encrypted_name']);
            }

            // Statistiques rapides
            $statsSql = "
                SELECT 
                    COUNT(*) as total_files,
                    SUM(m.file_size) as total_size,
                    m.file_category,
                    COUNT(*) as category_count
                FROM medias m
                {$whereClause}
                GROUP BY m.file_category
            ";

            $stmt = $this->db->prepare($statsSql);
            $stmt->execute(array_slice($params, 0, -2)); // Enlever LIMIT et OFFSET
            $stats = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $summary = [
                'total_files' => $totalItems,
                'total_size' => array_sum(array_column($stats, 'total_size')),
                'by_category' => []
            ];

            foreach ($stats as $stat) {
                if ($stat['file_category']) {
                    $summary['by_category'][$stat['file_category']] = (int)$stat['category_count'];
                }
            }

            Response::json([
                'status' => 'success',
                'current_path' => $path,
                'parent_path' => dirname($path) !== '.' ? dirname($path) : null,
                'pagination' => [
                    'current_page' => $filters['page'],
                    'per_page' => $filters['per_page'],
                    'total_items' => $totalItems,
                    'total_pages' => $totalPages,
                    'has_next' => $filters['page'] < $totalPages,
                    'has_prev' => $filters['page'] > 1
                ],
                'filters' => [
                    'search' => $filters['search'],
                    'type' => $filters['type'],
                    'category' => $filters['category'],
                    'sort' => $filters['sort'],
                    'order' => $filters['order']
                ],
                'files' => $files,
                'summary' => $summary
            ], 200);
        } catch (Exception $e) {
            LogService::log('Erreur lors de la navigation des fichiers', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'userId' => $userId ?? null,
                'path' => $_GET['path'] ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors de la navigation des fichiers'
            ], 500);
        }
    }

    /**
     * Liste des fichiers par support avec recherche et pagination
     */
    public function listBySupport(string $support, string $supportId): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            $userInfo = $this->getUserInfo($userId);
            if (!$userInfo) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Informations utilisateur non trouvées'
                ], 404);
                return;
            }

            $userRole = (int)$userInfo['fk_role'];
            $userEntiteId = (int)$userInfo['fk_entite'];
            $supportIdInt = (int)$supportId;

            $filters = $this->extractFilters($_GET);

            // Construction de la requête de base
            $conditions = ['m.support = ?', 'm.support_id = ?'];
            $params = [$support, $supportIdInt];

            // Restriction par entité selon le rôle
            if ($userRole == 2) {
                $conditions[] = 'm.fk_entite = ?';
                $params[] = $userEntiteId;
            }

            // Recherche textuelle
            if ($filters['search']) {
                $searchTerm = '%' . $filters['search'] . '%';
                $conditions[] = '(m.fichier LIKE ? OR m.original_name LIKE ? OR m.description LIKE ?)';
                $params[] = $searchTerm;
                $params[] = $searchTerm;
                $params[] = $searchTerm;
            }

            // Filtrage par type
            if ($filters['type']) {
                $conditions[] = 'm.file_type = ?';
                $params[] = $filters['type'];
            }

            // Filtrage par catégorie
            if ($filters['category']) {
                $conditions[] = 'm.file_category = ?';
                $params[] = $filters['category'];
            }

            $whereClause = 'WHERE ' . implode(' AND ', $conditions);
            $orderClause = $this->buildOrderClause($filters);

            // Compter le total
            $countSql = "SELECT COUNT(*) as total FROM medias m {$whereClause}";
            $stmt = $this->db->prepare($countSql);
            $stmt->execute($params);
            $totalItems = (int)$stmt->fetchColumn();

            // Calcul pagination
            $totalPages = ceil($totalItems / $filters['per_page']);
            $offset = ($filters['page'] - 1) * $filters['per_page'];

            // Requête principale
            $sql = "
                SELECT 
                    m.id, m.fichier, m.original_name, m.file_type, m.file_category,
                    m.file_size, m.file_path, m.description, m.created_at,
                    m.fk_user_creat, u.encrypted_name as creator_name
                FROM medias m
                LEFT JOIN users u ON u.id = m.fk_user_creat
                {$whereClause}
                {$orderClause}
                LIMIT ? OFFSET ?
            ";

            $params[] = $filters['per_page'];
            $params[] = $offset;

            $stmt = $this->db->prepare($sql);
            $stmt->execute($params);
            $files = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Déchiffrer les noms
            foreach ($files as &$file) {
                if ($file['creator_name']) {
                    $file['creator_name'] = ApiService::decryptData($file['creator_name']);
                }
                unset($file['encrypted_name']);
            }

            Response::json([
                'status' => 'success',
                'support' => $support,
                'support_id' => $supportIdInt,
                'pagination' => [
                    'current_page' => $filters['page'],
                    'per_page' => $filters['per_page'],
                    'total_items' => $totalItems,
                    'total_pages' => $totalPages,
                    'has_next' => $filters['page'] < $totalPages,
                    'has_prev' => $filters['page'] > 1
                ],
                'filters' => [
                    'search' => $filters['search'],
                    'type' => $filters['type'],
                    'category' => $filters['category']
                ],
                'files' => $files
            ], 200);
        } catch (Exception $e) {
            LogService::log('Erreur lors de la liste des fichiers par support', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'support' => $support,
                'supportId' => $supportId,
                'userId' => $userId ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors de la récupération des fichiers'
            ], 500);
        }
    }

    /**
     * Recherche globale de fichiers
     */
    public function search(): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            $userInfo = $this->getUserInfo($userId);
            if (!$userInfo) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Informations utilisateur non trouvées'
                ], 404);
                return;
            }

            $userRole = (int)$userInfo['fk_role'];
            $userEntiteId = (int)$userInfo['fk_entite'];

            $query = $_GET['q'] ?? '';
            if (empty(trim($query))) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Terme de recherche requis'
                ], 400);
                return;
            }

            $filters = $this->extractFilters($_GET);
            $filters['search'] = trim($query);

            [$whereClause, $params] = $this->buildWhereClause($filters, $userRole, $userEntiteId);
            $orderClause = $this->buildOrderClause($filters);

            // Compter le total
            $countSql = "SELECT COUNT(*) as total FROM medias m {$whereClause}";
            $stmt = $this->db->prepare($countSql);
            $stmt->execute($params);
            $totalItems = (int)$stmt->fetchColumn();

            // Pagination
            $totalPages = ceil($totalItems / $filters['per_page']);
            $offset = ($filters['page'] - 1) * $filters['per_page'];

            // Requête principale
            $sql = "
                SELECT 
                    m.id, m.fichier, m.original_name, m.file_type, m.file_category,
                    m.file_size, m.file_path, m.description, m.created_at, m.support,
                    m.support_id, m.fk_user_creat, u.encrypted_name as creator_name
                FROM medias m
                LEFT JOIN users u ON u.id = m.fk_user_creat
                {$whereClause}
                {$orderClause}
                LIMIT ? OFFSET ?
            ";

            $params[] = $filters['per_page'];
            $params[] = $offset;

            $stmt = $this->db->prepare($sql);
            $stmt->execute($params);
            $files = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Déchiffrer les noms
            foreach ($files as &$file) {
                if ($file['creator_name']) {
                    $file['creator_name'] = ApiService::decryptData($file['creator_name']);
                }
                unset($file['encrypted_name']);
            }

            Response::json([
                'status' => 'success',
                'query' => $query,
                'pagination' => [
                    'current_page' => $filters['page'],
                    'per_page' => $filters['per_page'],
                    'total_items' => $totalItems,
                    'total_pages' => $totalPages,
                    'has_next' => $filters['page'] < $totalPages,
                    'has_prev' => $filters['page'] > 1
                ],
                'filters' => [
                    'type' => $filters['type'],
                    'category' => $filters['category']
                ],
                'files' => $files
            ], 200);
        } catch (Exception $e) {
            LogService::log('Erreur lors de la recherche de fichiers', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'query' => $_GET['q'] ?? null,
                'userId' => $userId ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors de la recherche'
            ], 500);
        }
    }

    /**
     * Statistiques d'utilisation des fichiers
     */
    public function getStats(): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            $userInfo = $this->getUserInfo($userId);
            if (!$userInfo) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Informations utilisateur non trouvées'
                ], 404);
                return;
            }

            $userRole = (int)$userInfo['fk_role'];
            $userEntiteId = (int)$userInfo['fk_entite'];

            if ($userRole == 2) {
                // Stats pour admin d'entité
                $sql = "
                    SELECT 
                        COUNT(*) as total_files,
                        SUM(file_size) as total_size,
                        support,
                        file_category,
                        file_type,
                        COUNT(*) as count
                    FROM medias 
                    WHERE fk_entite = ?
                    GROUP BY support, file_category, file_type
                    ORDER BY support, file_category
                ";

                $stmt = $this->db->prepare($sql);
                $stmt->execute([$userEntiteId]);
                $stats = $stmt->fetchAll(PDO::FETCH_ASSOC);

                $response = [
                    'status' => 'success',
                    'entite_id' => $userEntiteId,
                    'storage' => [
                        'total_files' => 0,
                        'total_size' => 0,
                        'by_support' => [],
                        'by_category' => [],
                        'by_type' => []
                    ]
                ];

                foreach ($stats as $stat) {
                    $response['storage']['total_files'] += (int)$stat['count'];
                    $response['storage']['total_size'] += (int)$stat['total_size'];

                    $support = $stat['support'];
                    $category = $stat['file_category'] ?: 'non_categorise';
                    $type = $stat['file_type'] ?: 'inconnu';

                    if (!isset($response['storage']['by_support'][$support])) {
                        $response['storage']['by_support'][$support] = ['count' => 0, 'size' => 0];
                    }
                    $response['storage']['by_support'][$support]['count'] += (int)$stat['count'];
                    $response['storage']['by_support'][$support]['size'] += (int)$stat['total_size'];

                    if (!isset($response['storage']['by_category'][$category])) {
                        $response['storage']['by_category'][$category] = 0;
                    }
                    $response['storage']['by_category'][$category] += (int)$stat['count'];

                    if (!isset($response['storage']['by_type'][$type])) {
                        $response['storage']['by_type'][$type] = 0;
                    }
                    $response['storage']['by_type'][$type] += (int)$stat['count'];
                }
            } else {
                // Stats globales pour super admin
                $sql = "
                    SELECT 
                        fk_entite,
                        COUNT(*) as files,
                        SUM(file_size) as size
                    FROM medias 
                    GROUP BY fk_entite
                    ORDER BY size DESC
                ";

                $stmt = $this->db->prepare($sql);
                $stmt->execute();
                $entiteStats = $stmt->fetchAll(PDO::FETCH_ASSOC);

                $totalSql = "
                    SELECT 
                        COUNT(*) as total_files,
                        SUM(file_size) as total_size,
                        COUNT(DISTINCT fk_entite) as entites_count
                    FROM medias
                ";

                $stmt = $this->db->prepare($totalSql);
                $stmt->execute();
                $totals = $stmt->fetch(PDO::FETCH_ASSOC);

                $response = [
                    'status' => 'success',
                    'global_stats' => [
                        'total_files' => (int)$totals['total_files'],
                        'total_size' => (int)$totals['total_size'],
                        'entites_count' => (int)$totals['entites_count'],
                        'by_entite' => []
                    ]
                ];

                foreach ($entiteStats as $stat) {
                    $response['global_stats']['by_entite'][] = [
                        'entite_id' => (int)$stat['fk_entite'],
                        'files' => (int)$stat['files'],
                        'size' => (int)$stat['size']
                    ];
                }
            }

            Response::json($response, 200);
        } catch (Exception $e) {
            LogService::log('Erreur lors de la récupération des statistiques', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'userId' => $userId ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors de la récupération des statistiques'
            ], 500);
        }
    }

    /**
     * Téléchargement sécurisé d'un fichier
     */
    public function download(string $id): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            $userInfo = $this->getUserInfo($userId);
            if (!$userInfo) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Informations utilisateur non trouvées'
                ], 404);
                return;
            }

            $userRole = (int)$userInfo['fk_role'];
            $userEntiteId = (int)$userInfo['fk_entite'];
            $fileId = (int)$id;

            // Vérifier l'accès au fichier
            if (!$this->canAccessFile($fileId, $userRole, $userEntiteId)) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Accès refusé à ce fichier'
                ], 403);
                return;
            }

            // Récupérer les informations du fichier
            $stmt = $this->db->prepare('
                SELECT fichier, file_path, mime_type, original_name, file_size
                FROM medias 
                WHERE id = ?
            ');
            $stmt->execute([$fileId]);
            $file = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$file) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Fichier non trouvé'
                ], 404);
                return;
            }

            $filepath = getcwd() . '/' . $file['file_path'];

            if (!file_exists($filepath)) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Fichier physique non trouvé'
                ], 404);
                return;
            }

            // Log du téléchargement
            LogService::log('Téléchargement de fichier', [
                'level' => 'info',
                'userId' => $userId,
                'fileId' => $fileId,
                'filename' => $file['original_name']
            ]);

            // Envoyer le fichier
            header('Content-Type: ' . $file['mime_type']);
            header('Content-Disposition: attachment; filename="' . $file['original_name'] . '"');
            header('Content-Length: ' . filesize($filepath));
            header('Cache-Control: no-cache, must-revalidate');
            header('Expires: 0');

            readfile($filepath);
            exit;
        } catch (Exception $e) {
            LogService::log('Erreur lors du téléchargement', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'fileId' => $id,
                'userId' => $userId ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors du téléchargement'
            ], 500);
        }
    }

    /**
     * Suppression sécurisée d'un fichier
     */
    public function deleteFile(string $id): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            $userInfo = $this->getUserInfo($userId);
            if (!$userInfo) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Informations utilisateur non trouvées'
                ], 404);
                return;
            }

            $userRole = (int)$userInfo['fk_role'];
            $userEntiteId = (int)$userInfo['fk_entite'];
            $fileId = (int)$id;

            // Vérifier l'accès au fichier
            if (!$this->canAccessFile($fileId, $userRole, $userEntiteId)) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Accès refusé à ce fichier'
                ], 403);
                return;
            }

            // Récupérer les informations du fichier
            $stmt = $this->db->prepare('
                SELECT fichier, file_path, original_name, support, support_id
                FROM medias 
                WHERE id = ?
            ');
            $stmt->execute([$fileId]);
            $file = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$file) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Fichier non trouvé'
                ], 404);
                return;
            }

            // Supprimer le fichier physique
            $filepath = getcwd() . '/' . $file['file_path'];
            if (file_exists($filepath)) {
                unlink($filepath);
            }

            // Supprimer l'enregistrement en base
            $stmt = $this->db->prepare('DELETE FROM medias WHERE id = ?');
            $stmt->execute([$fileId]);

            LogService::log('Suppression de fichier', [
                'level' => 'info',
                'userId' => $userId,
                'fileId' => $fileId,
                'filename' => $file['original_name'],
                'support' => $file['support'],
                'support_id' => $file['support_id']
            ]);

            Response::json([
                'status' => 'success',
                'message' => 'Fichier supprimé avec succès'
            ], 200);
        } catch (Exception $e) {
            LogService::log('Erreur lors de la suppression de fichier', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'fileId' => $id,
                'userId' => $userId ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors de la suppression'
            ], 500);
        }
    }

    /**
     * Informations détaillées d'un fichier
     */
    public function getFileInfo(string $id): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            $userInfo = $this->getUserInfo($userId);
            if (!$userInfo) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Informations utilisateur non trouvées'
                ], 404);
                return;
            }

            $userRole = (int)$userInfo['fk_role'];
            $userEntiteId = (int)$userInfo['fk_entite'];
            $fileId = (int)$id;

            // Vérifier l'accès au fichier
            if (!$this->canAccessFile($fileId, $userRole, $userEntiteId)) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Accès refusé à ce fichier'
                ], 403);
                return;
            }

            // Récupérer toutes les informations du fichier
            $stmt = $this->db->prepare('
                SELECT 
                    m.*, 
                    u_creat.encrypted_name as creator_name,
                    u_modif.encrypted_name as modifier_name
                FROM medias m
                LEFT JOIN users u_creat ON u_creat.id = m.fk_user_creat
                LEFT JOIN users u_modif ON u_modif.id = m.fk_user_modif
                WHERE m.id = ?
            ');
            $stmt->execute([$fileId]);
            $file = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$file) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Fichier non trouvé'
                ], 404);
                return;
            }

            // Déchiffrer les noms d'utilisateurs
            if ($file['creator_name']) {
                $file['creator_name'] = ApiService::decryptData($file['creator_name']);
            }
            if ($file['modifier_name']) {
                $file['modifier_name'] = ApiService::decryptData($file['modifier_name']);
            }

            // Vérifier si le fichier physique existe
            $filepath = getcwd() . '/' . $file['file_path'];
            $file['file_exists'] = file_exists($filepath);

            Response::json([
                'status' => 'success',
                'file' => $file
            ], 200);
        } catch (Exception $e) {
            LogService::log('Erreur lors de la récupération des infos fichier', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'fileId' => $id,
                'userId' => $userId ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors de la récupération des informations'
            ], 500);
        }
    }

    /**
     * Métadonnées du système de fichiers (catégories, extensions, etc.)
     */
    public function getMetadata(): void {
        try {
            $userId = Session::getUserId();
            if (!$userId) {
                Response::json([
                    'status' => 'error',
                    'message' => 'Vous devez être connecté pour effectuer cette action'
                ], 401);
                return;
            }

            Response::json([
                'status' => 'success',
                'categories' => self::FILE_CATEGORIES,
                'extensions' => self::ALLOWED_EXTENSIONS,
                'mime_types' => [
                    'pdf' => 'application/pdf',
                    'jpg' => 'image/jpeg',
                    'jpeg' => 'image/jpeg',
                    'png' => 'image/png',
                    'gif' => 'image/gif',
                    'webp' => 'image/webp',
                    'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                    'xls' => 'application/vnd.ms-excel',
                    'json' => 'application/json',
                    'csv' => 'text/csv'
                ],
                'max_file_sizes' => [
                    'entite' => 20971520,    // 20 MB
                    'user' => 5242880,       // 5 MB
                    'operation' => 20971520, // 20 MB
                    'passage' => 10485760    // 10 MB
                ]
            ], 200);
        } catch (Exception $e) {
            LogService::log('Erreur lors de la récupération des métadonnées', [
                'level' => 'error',
                'error' => $e->getMessage(),
                'userId' => $userId ?? null
            ]);

            Response::json([
                'status' => 'error',
                'message' => 'Erreur lors de la récupération des métadonnées'
            ], 500);
        }
    }
}
