<?php
// ==========================================
// CONFIGURATION & SÉCURITÉ (MajOrWare IT Solutions)
// ==========================================
session_start();

// Chargement des variables d environnement (.env)
function loadEnv($path) {
    if (!file_exists($path)) return;
    $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    foreach ($lines as $line) {
        if (strpos(trim($line), "#") === 0) continue;
        list($name, $value) = explode("=", $line, 2);
        $_ENV[trim($name)] = trim($value, " \t\n\r\0\x0B\"'");
    }
}

loadEnv(__DIR__ . "/.env");

$appName = $_ENV["APP_NAME"] ?? "MajOrCloud S3";
$bucketName = $_ENV["BUCKET_NAME"] ?? "majorware-production-storage";
$adminPassword = $_ENV["ADMIN_PASSWORD"] ?? "Admin123!";
$apiUploadToken = $_ENV["API_UPLOAD_TOKEN"] ?? "MW-S3-Sec-Token-2026";
$s3Engine = $_ENV["S3_ENGINE"] ?? "Garage S3 v2.4";

// Authentification API par Bearer Token (pour Hope et scripts)
$authHeader = $_SERVER["HTTP_AUTHORIZATION"] ?? "";
$isApiAuth = false;
if (preg_match("/Bearer\s+(.*)$/i", $authHeader, $matches)) {
    if (hash_equals($apiUploadToken, trim($matches[1]))) {
        $isApiAuth = true;
    }
}

// Gestion Authentification Session Admin
if (isset($_POST["action"]) && $_POST["action"] === "login") {
    if (isset($_POST["password"]) && $_POST["password"] === $adminPassword) {
        $_SESSION["authenticated"] = true;
        header("Location: " . $_SERVER["PHP_SELF"]);
        exit;
    } else {
        $loginError = "Mot de passe incorrect.";
    }
}

if (isset($_GET["action"]) && $_GET["action"] === "logout") {
    unset($_SESSION["authenticated"]);
    session_destroy();
    header("Location: " . $_SERVER["PHP_SELF"]);
    exit;
}

$isAuthenticated = isset($_SESSION["authenticated"]) && $_SESSION["authenticated"] === true;

$baseDir = realpath(__DIR__);
$excludeFiles = ["index.php", "index.php.bak", ".htaccess", ".DS_Store", ".git", ".env"];

// Support sous-dossier & protection Path Traversal stricte
$rawDir = $_POST["folder"] ?? $_GET["dir"] ?? "";
$cleanSubDir = trim(str_replace(["..", "\\"], ["", "/"], $rawDir), "/");
$targetCandidate = $baseDir . ($cleanSubDir !== "" ? "/" . $cleanSubDir : "");
if (!is_dir($targetCandidate) && $cleanSubDir !== "") {
    @mkdir($targetCandidate, 0755, true);
}
$targetPath = realpath($targetCandidate);
if (!$targetPath || strpos($targetPath, $baseDir) !== 0 || !is_dir($targetPath)) {
    $currentDir = "";
    $targetPath = $baseDir;
} else {
    $currentDir = $cleanSubDir;
}

// ------------------------------------------
// API & ACTIONS (Upload, Delete, New Dir)
// ------------------------------------------

// 1. Upload de fichier (Web Admin ou API Machine)
if ((isset($_POST["action"]) && $_POST["action"] === "upload") || isset($_GET["api_upload"])) {
    if (!$isAuthenticated && !$isApiAuth) {
        if ($isApiAuth || isset($_GET["api_upload"])) {
            http_response_code(401);
            header("Content-Type: application/json");
            echo json_encode(["success" => false, "error" => "Non autorisé (Token Bearer invalide)"]);
            exit;
        }
        $uploadError = "Authentification requise pour téléverser.";
    } elseif (!empty($_FILES["file"])) {
        $file = $_FILES["file"];
        $origName = basename($file["name"]);
        $ext = strtolower(pathinfo($origName, PATHINFO_EXTENSION));

        // Blocage absolu des extensions exécutables (Anti-RCE)
        $forbiddenExts = ["php", "phtml", "php3", "php4", "php5", "php7", "php8", "phps", "cgi", "pl", "py", "sh", "bash", "exe", "phar"];
        if (in_array($ext, $forbiddenExts)) {
            if ($isApiAuth || isset($_GET["api_upload"])) {
                http_response_code(400);
                header("Content-Type: application/json");
                echo json_encode(["success" => false, "error" => "Extension interdite par mesure de sécurité."]);
                exit;
            }
            $uploadError = "Extension non autorisée par mesure de sécurité.";
        } else {
            // Nettoyage du nom de fichier
            $safeName = preg_replace("/[^a-zA-Z0-9_\.-]/", "_", $origName);
            $destination = $targetPath . "/" . $safeName;

            if (move_uploaded_file($file["tmp_name"], $destination)) {
                if ($isApiAuth || isset($_GET["api_upload"])) {
                    header("Content-Type: application/json");
                    echo json_encode([
                        "success" => true,
                        "filename" => $safeName,
                        "path" => $currentDir ? $currentDir . "/" . $safeName : $safeName,
                        "size" => filesize($destination)
                    ]);
                    exit;
                }
                header("Location: ?dir=" . urlencode($currentDir));
                exit;
            } else {
                $uploadError = "Erreur lors de l enregistrement du fichier.";
            }
        }
    }
}

// 2. Création de dossier
if (isset($_POST["action"]) && $_POST["action"] === "create_dir" && $isAuthenticated) {
    $folderName = trim($_POST["folder_name"] ?? "");
    $safeFolderName = preg_replace("/[^a-zA-Z0-9_-]/", "_", $folderName);
    if (!empty($safeFolderName)) {
        $newDirPath = $targetPath . "/" . $safeFolderName;
        if (!file_exists($newDirPath)) {
            mkdir($newDirPath, 0775, true);
        }
    }
    header("Location: ?dir=" . urlencode($currentDir));
    exit;
}

// 3. Suppression de fichier
if (isset($_POST["action"]) && $_POST["action"] === "delete" && $isAuthenticated) {
    $itemToDelete = trim($_POST["item_path"] ?? "", "/\\");
    $fullPathToDelete = realpath($baseDir . "/" . $itemToDelete);
    if ($fullPathToDelete && strpos($fullPathToDelete, $baseDir) === 0 && !in_array(basename($fullPathToDelete), $excludeFiles)) {
        if (is_file($fullPathToDelete)) {
            unlink($fullPathToDelete);
        }
    }
    header("Location: ?dir=" . urlencode($currentDir));
    exit;
}

// Téléchargement sécurisé
if (isset($_GET["download"])) {
    $fileToDownload = trim($_GET["download"], "/\\");
    $filePath = realpath($baseDir . "/" . $fileToDownload);

    if ($filePath && strpos($filePath, $baseDir) === 0 && is_file($filePath)) {
        $fileName = basename($filePath);
        if (!in_array($fileName, $excludeFiles)) {
            header("Content-Description: File Transfer");
            header("Content-Type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"" . $fileName . "\"");
            header("Expires: 0");
            header("Cache-Control: must-revalidate");
            header("Pragma: public");
            header("Content-Length: " . filesize($filePath));
            readfile($filePath);
            exit;
        }
    }
    die("Fichier non trouvé ou accès refusé.");
}

function listDirectory($dir, $baseDir, $excludeFiles) {
    $items = [];
    if (is_dir($dir)) {
        $files = scandir($dir);
        foreach ($files as $file) {
            if ($file === "." || $file === ".." || in_array($file, $excludeFiles)) continue;
            $path = $dir . "/" . $file;
            $relativePath = ltrim(str_replace($baseDir, "", $path), "/\\");
            $items[] = [
                "name" => $file,
                "path" => $relativePath,
                "is_dir" => is_dir($path),
                "size" => is_file($path) ? formatSize(filesize($path)) : "--",
                "modified" => date("d/m/Y H:i", filemtime($path))
            ];
        }
        usort($items, function($a, $b) {
            if ($a["is_dir"] === $b["is_dir"]) return strcasecmp($a["name"], $b["name"]);
            return $a["is_dir"] ? -1 : 1;
        });
    }
    return $items;
}

function formatSize($bytes) {
    if ($bytes <= 0) return "0 B";
    $sizes = ["B", "KB", "MB", "GB", "TB"];
    $i = floor(log($bytes, 1024));
    return round($bytes / pow(1024, $i), 2) . " " . $sizes[$i];
}

function getIcon($filename, $isDir) {
    if ($isDir) return "📁";
    $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    $icons = [
        "jpg" => "🖼️", "jpeg" => "🖼️", "png" => "🖼️", "gif" => "🖼️", "svg" => "🖼️",
        "mp4" => "🎬", "avi" => "🎬", "mov" => "🎬", "webm" => "🎬",
        "pdf" => "📕", "txt" => "📝", "doc" => "📘", "docx" => "📘",
        "zip" => "📦", "rar" => "📦", "tar" => "📦", "gz" => "📦", "enc" => "🔒",
        "sql" => "🗄️", "db" => "🗄️", "json" => "📋", "csv" => "📊", "apk" => "📱"
    ];
    return $icons[$ext] ?? "📄";
}

$items = listDirectory($targetPath, $baseDir, $excludeFiles);
$isRoot = empty($currentDir);

$breadcrumbs = [];
if ($currentDir) {
    $parts = explode("/", $currentDir);
    $acc = "";
    foreach ($parts as $p) {
        $acc .= ($acc ? "/" : "") . $p;
        $breadcrumbs[] = ["name" => $p, "path" => $acc];
    }
}
?>
<!DOCTYPE html>
<html lang="fr" class="dark">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= htmlspecialchars($appName) ?> - MajOrWare IT Solutions</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script>
        tailwind.config = {
            darkMode: "class",
            theme: {
                extend: {
                    colors: {
                        brand: {
                            red: "#dc2626",
                            redHover: "#b91c1c",
                            dark: "#0f0f11",
                            card: "#18181b",
                            border: "#27272a"
                        }
                    }
                }
            }
        }
    </script>
</head>
<body class="bg-brand-dark text-zinc-100 min-h-screen font-sans antialiased flex flex-col justify-between">

    <!-- Header Principal MajOrWare -->
    <header class="border-b border-brand-border bg-zinc-950/80 backdrop-blur sticky top-0 z-50">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between">
            <div class="flex items-center space-x-3">
                <div class="bg-brand-red/10 p-2 rounded-xl border border-brand-red/30 text-brand-red font-black text-xl tracking-wider">
                    MW
                </div>
                <div>
                    <h1 class="text-xl font-bold text-white tracking-tight flex items-center gap-2">
                        <?= htmlspecialchars($appName) ?>
                        <span class="text-xs bg-brand-red/20 text-brand-red px-2 py-0.5 rounded border border-brand-red/30">IT Solutions</span>
                    </h1>
                    <div class="flex items-center gap-2 text-xs text-zinc-400 mt-0.5">
                        <span>Bucket: <strong class="font-mono text-zinc-300"><?= htmlspecialchars($bucketName) ?></strong></span>
                        <span>•</span>
                        <span class="inline-flex items-center gap-1 text-emerald-400">
                            <span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
                            Moteur S3 : <?= htmlspecialchars($s3Engine) ?>
                        </span>
                    </div>
                </div>
            </div>
            
            <div class="flex items-center space-x-3">
                <?php if ($isAuthenticated): ?>
                    <button onclick="document.getElementById(uploadModal).classList.remove(hidden)" class="bg-brand-red hover:bg-brand-redHover text-white text-xs font-semibold px-3.5 py-2 rounded-lg shadow-lg shadow-brand-red/20 transition flex items-center gap-1.5">
                        <span>⬆️</span> Téléverser
                    </button>
                    <button onclick="document.getElementById(newFolderModal).classList.remove(hidden)" class="bg-zinc-800 hover:bg-zinc-700 border border-zinc-700 text-zinc-300 text-xs px-3.5 py-2 rounded-lg font-medium transition flex items-center gap-1.5">
                        <span>📁</span> Nouveau dossier
                    </button>
                    <a href="?action=logout" class="bg-zinc-900 hover:bg-zinc-800 border border-zinc-700 text-zinc-400 hover:text-white text-xs px-3 py-2 rounded-lg transition">Déconnexion</a>
                <?php else: ?>
                    <button onclick="document.getElementById(loginModal).classList.remove(hidden)" class="bg-brand-red hover:bg-brand-redHover text-white text-xs font-semibold px-4 py-2 rounded-lg shadow-lg shadow-brand-red/20 transition">
                        Connexion Admin
                    </button>
                <?php endif; ?>
            </div>
        </div>
    </header>

    <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 w-full flex-1">

        <!-- Message d erreur Upload si existant -->
        <?php if (isset($uploadError)): ?>
            <div class="bg-brand-red/10 border border-brand-red/50 text-brand-red text-xs p-3 rounded-xl mb-6">
                <?= htmlspecialchars($uploadError) ?>
            </div>
        <?php endif; ?>

        <!-- Modal de Connexion -->
        <div id="loginModal" class="<?= isset($loginError) ? "" : "hidden" ?> fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4">
            <div class="bg-brand-card p-8 rounded-2xl border border-brand-border max-w-md w-full relative shadow-2xl">
                <button onclick="document.getElementById(loginModal).classList.add(hidden)" class="absolute top-4 right-4 text-zinc-400 hover:text-white">✕</button>
                <div class="text-center mb-6">
                    <span class="text-4xl block mb-2">🔐</span>
                    <h2 class="text-xl font-bold text-white">Administration <?= htmlspecialchars($appName) ?></h2>
                    <p class="text-xs text-zinc-400 mt-1">Saisissez le mot de passe d administration</p>
                </div>

                <?php if (isset($loginError)): ?>
                    <div class="bg-brand-red/10 border border-brand-red/50 text-brand-red text-xs p-3 rounded-lg mb-4 text-center">
                        <?= htmlspecialchars($loginError) ?>
                    </div>
                <?php endif; ?>

                <form method="POST" class="space-y-4">
                    <input type="hidden" name="action" value="login">
                    <div>
                        <input type="password" name="password" placeholder="Mot de passe d accès" required autofocus class="w-full bg-zinc-900 border border-zinc-700 rounded-xl px-4 py-3 text-white focus:outline-none focus:border-brand-red transition text-sm">
                    </div>
                    <button type="submit" class="w-full bg-brand-red hover:bg-brand-redHover text-white font-semibold py-3 rounded-xl transition shadow-lg shadow-brand-red/20 text-sm">
                        Se connecter
                    </button>
                </form>
            </div>
        </div>

        <?php if ($isAuthenticated): ?>
            <!-- Modal Upload / Drag & Drop -->
            <div id="uploadModal" class="hidden fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4">
                <div class="bg-brand-card p-6 rounded-2xl border border-brand-border max-w-lg w-full relative shadow-2xl">
                    <button onclick="document.getElementById(uploadModal).classList.add(hidden)" class="absolute top-4 right-4 text-zinc-400 hover:text-white">✕</button>
                    <h2 class="text-lg font-bold text-white mb-2">Téléverser dans : <span class="font-mono text-xs text-brand-red"><?= $currentDir ?: "root" ?></span></h2>
                    
                    <form method="POST" enctype="multipart/form-data" class="space-y-4 mt-4">
                        <input type="hidden" name="action" value="upload">
                        <div class="border-2 border-dashed border-zinc-700 hover:border-brand-red/60 rounded-2xl p-8 text-center transition cursor-pointer bg-zinc-900/50" onclick="document.getElementById(fileInput).click()">
                            <span class="text-4xl block mb-2">📤</span>
                            <p class="text-sm font-medium text-zinc-300">Cliquez ou glissez un fichier ici</p>
                            <p class="text-xs text-zinc-500 mt-1">Dumps SQL chiffrés, sauvegardes, médias (Jusqu à 2 Go)</p>
                            <input type="file" id="fileInput" name="file" class="hidden" onchange="document.getElementById(selectedFileName).innerText = this.files[0]?.name || ">
                            <p id="selectedFileName" class="text-xs font-mono text-brand-red mt-2"></p>
                        </div>
                        <button type="submit" class="w-full bg-brand-red hover:bg-brand-redHover text-white font-semibold py-2.5 rounded-xl transition text-sm">
                            Confirmer l envoi
                        </button>
                    </form>
                </div>
            </div>

            <!-- Modal Nouveau Dossier -->
            <div id="newFolderModal" class="hidden fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4">
                <div class="bg-brand-card p-6 rounded-2xl border border-brand-border max-w-sm w-full relative shadow-2xl">
                    <button onclick="document.getElementById(newFolderModal).classList.add(hidden)" class="absolute top-4 right-4 text-zinc-400 hover:text-white">✕</button>
                    <h2 class="text-base font-bold text-white mb-4">Créer un nouveau dossier</h2>
                    <form method="POST" class="space-y-3">
                        <input type="hidden" name="action" value="create_dir">
                        <input type="text" name="folder_name" placeholder="ex: backups_hopital_pasteur" required class="w-full bg-zinc-900 border border-zinc-700 rounded-xl px-3.5 py-2.5 text-white focus:outline-none focus:border-brand-red transition text-sm">
                        <button type="submit" class="w-full bg-zinc-800 hover:bg-zinc-700 text-white font-semibold py-2.5 rounded-xl transition text-sm">
                            Créer le dossier
                        </button>
                    </form>
                </div>
            </div>
        <?php endif; ?>

        <!-- Navigation & Recherche -->
        <div class="flex flex-col md:flex-row items-center justify-between gap-4 mb-6">
            <nav class="flex items-center space-x-2 bg-brand-card border border-brand-border px-4 py-2.5 rounded-xl text-sm w-full md:w-auto overflow-x-auto">
                <a href="?dir=" class="text-brand-red hover:underline font-medium">root</a>
                <?php foreach ($breadcrumbs as $crumb): ?>
                    <span class="text-zinc-600">/</span>
                    <a href="?dir=<?= urlencode($crumb["path"]) ?>" class="text-zinc-300 hover:text-white font-medium"><?= htmlspecialchars($crumb["name"]) ?></a>
                <?php endforeach; ?>
            </nav>

            <div class="w-full md:w-72 relative">
                <input type="text" id="searchInput" onkeyup="filterItems()" placeholder="Filtrer les fichiers..." class="w-full bg-brand-card border border-brand-border rounded-xl pl-10 pr-4 py-2.5 text-sm text-zinc-200 placeholder-zinc-500 focus:outline-none focus:border-brand-red transition">
                <span class="absolute left-3 top-3 text-zinc-500 text-sm">🔍</span>
            </div>
        </div>

        <?php if (!$isRoot): ?>
            <div class="mb-4">
                <a href="?dir=<?= urlencode(dirname($currentDir) === "." ? "" : dirname($currentDir)) ?>" class="inline-flex items-center space-x-2 text-xs text-zinc-400 hover:text-white bg-brand-card px-3 py-1.5 rounded-lg border border-brand-border transition">
                    <span>⬅️ Dossier parent</span>
                </a>
            </div>
        <?php endif; ?>

        <!-- Grille des fichiers -->
        <?php if (empty($items)): ?>
            <div class="bg-brand-card/50 border border-brand-border rounded-2xl p-12 text-center">
                <span class="text-5xl block mb-3">📭</span>
                <h3 class="text-base font-semibold text-zinc-300">Dossier vide</h3>
                <p class="text-zinc-500 text-xs mt-1">Aucun objet détecté dans ce répertoire.</p>
            </div>
        <?php else: ?>
            <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4" id="itemsGrid">
                <?php foreach ($items as $item): ?>
                    <div class="item-card bg-brand-card hover:border-brand-red/50 border border-brand-border rounded-2xl p-4 transition duration-200 flex flex-col justify-between group" data-name="<?= strtolower(htmlspecialchars($item["name"])) ?>">
                        <div>
                            <div class="flex items-start justify-between mb-3">
                                <span class="text-3xl p-2 bg-zinc-900 rounded-xl border border-zinc-800"><?= getIcon($item["name"], $item["is_dir"]) ?></span>
                                <span class="text-xs font-mono text-zinc-400 bg-zinc-900 px-2.5 py-1 rounded-md border border-zinc-800"><?= $item["size"] ?></span>
                            </div>
                            <h3 class="font-medium text-sm text-zinc-200 group-hover:text-brand-red transition truncate" title="<?= htmlspecialchars($item["name"]) ?>">
                                <?= htmlspecialchars($item["name"]) ?>
                            </h3>
                            <p class="text-[11px] text-zinc-500 mt-1">Modifié le <?= $item["modified"] ?></p>
                        </div>

                        <div class="mt-4 pt-3 border-t border-zinc-800/80 flex items-center gap-2">
                            <?php if ($item["is_dir"]): ?>
                                <a href="?dir=<?= urlencode($item["path"]) ?>" class="w-full text-center bg-zinc-900 hover:bg-zinc-800 text-zinc-300 text-xs font-medium py-2 rounded-lg border border-zinc-800 transition">Explorer</a>
                            <?php else: ?>
                                <a href="?download=<?= urlencode($item["path"]) ?>" class="flex-1 text-center bg-brand-red/10 hover:bg-brand-red text-brand-red hover:text-white text-xs font-medium py-2 rounded-lg border border-brand-red/30 transition flex items-center justify-center space-x-1">
                                    <span>Télécharger</span>
                                    <span>⬇️</span>
                                </a>
                                <?php if ($isAuthenticated): ?>
                                    <form method="POST" onsubmit="return confirm(\"Supprimer définitivement ce fichier ?\")" class="inline">
                                        <input type="hidden" name="action" value="delete">
                                        <input type="hidden" name="item_path" value="<?= htmlspecialchars($item["path"]) ?>">
                                        <button type="submit" class="bg-zinc-900 hover:bg-red-900/50 text-zinc-500 hover:text-red-300 p-2 rounded-lg border border-zinc-800 transition text-xs" title="Supprimer">
                                            🗑️
                                        </button>
                                    </form>
                                <?php endif; ?>
                            <?php endif; ?>
                        </div>
                    </div>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>

    </main>

    <footer class="mt-12 border-t border-brand-border py-6 text-center text-xs text-zinc-500">
        <?= htmlspecialchars($appName) ?> • Propulsé par <strong class="text-zinc-400">MajOrWare IT Solutions</strong>
    </footer>

    <script>
        function filterItems() {
            const input = document.getElementById("searchInput").value.toLowerCase();
            const cards = document.querySelectorAll(".item-card");
            cards.forEach(card => {
                const name = card.getAttribute("data-name");
                card.style.display = name.includes(input) ? "flex" : "none";
            });
        }
    </script>
</body>
</html>
