<?php
ini_set('memory_limit', '512M');
set_time_limit(0);

$deletePasswordHash = '$2y$12$fjYjVk2978AkiQOVF.8S/uBC43twCIvehbKd5.5JMjH0OdCZL9DkO';
$protectedExtensions = ['php', 'html', 'css', 'js'];
$protectedNames = ['archive.zip', '.htaccess'];
$flash = ['type' => '', 'text' => ''];

function h(string $s): string {
    return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function is_visible_download_file(string $file, array $protectedExtensions, array $protectedNames): bool {
    if ($file === '' || $file === '.' || $file === '..') return false;
    if (str_contains($file, '/') || str_contains($file, '\\')) return false;
    if (in_array($file, $protectedNames, true)) return false;
    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
    if (in_array($ext, $protectedExtensions, true)) return false;
    return is_file(__DIR__ . '/' . $file);
}

if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && (string)($_POST['action'] ?? '') === 'delete_files') {
    $password = (string)($_POST['delete_password'] ?? '');
    $selected = $_POST['delete_files'] ?? [];
    if (!is_array($selected)) $selected = [];

    if (!password_verify($password, $deletePasswordHash)) {
        $flash = ['type' => 'bad', 'text' => 'Wrong delete password.'];
    } elseif (count($selected) === 0) {
        $flash = ['type' => 'bad', 'text' => 'No files selected.'];
    } else {
        $deleted = [];
        $skipped = [];
        foreach ($selected as $file) {
            $file = (string)$file;
            if (!is_visible_download_file($file, $protectedExtensions, $protectedNames)) {
                $skipped[] = $file . ' (protected or not found)';
                continue;
            }
            $path = __DIR__ . '/' . $file;
            if (@unlink($path)) {
                $deleted[] = $file;
            } else {
                $skipped[] = $file . ' (permission denied)';
            }
        }
        $parts = [];
        if (count($deleted) > 0) $parts[] = 'Deleted ' . count($deleted) . ' file(s).';
        if (count($skipped) > 0) $parts[] = 'Skipped ' . count($skipped) . ' file(s): ' . implode(', ', array_map(fn($s) => mb_strimwidth((string)$s, 0, 120, '...', 'UTF-8'), $skipped)) . '.';
        $flash = ['type' => count($deleted) > 0 ? 'ok' : 'bad', 'text' => implode(' ', $parts)];
    }
}

if (isset($_GET['download_all'])) {
    $rootPath = realpath('.');
    $zip = new ZipArchive();
    $zipFile = 'archive.zip';
    if ($zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
        $filesIterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($rootPath, FilesystemIterator::SKIP_DOTS),
            RecursiveIteratorIterator::LEAVES_ONLY
        );
        foreach ($filesIterator as $name => $file) {
            if (!$file->isDir()) {
                $filePath = $file->getRealPath();
                $relativePath = substr($filePath, strlen($rootPath) + 1);
                if ($relativePath !== $zipFile) {
                    $zip->addFile($filePath, $relativePath);
                }
            }
        }
        $zip->close();
        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename="' . $zipFile . '"');
        header('Content-Length: ' . filesize($zipFile));
        readfile($zipFile);
        unlink($zipFile);
        exit;
    }
}

// NY iterator för listan i HTML
$fileList = array_values(array_filter(scandir('.'), fn($file) => is_visible_download_file((string)$file, $protectedExtensions, $protectedNames)));
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Index of /</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="shell">
    <section class="hero">
      <div>
        <p class="eyebrow">dela.jdc.se</p>
        <h1>File Drop</h1>
        <p class="lede">Public files, quick downloads, and password protected cleanup.</p>
      </div>
      <div class="hero-actions">
        <a class="download-link" href="?download_all=1" aria-label="Download all visible files as one ZIP archive">Download ZIP</a>
        <a class="download-link secondary" href="systeminfo.php" aria-label="Show CPU, GPU, RAM and other server details">Systeminfo</a>
      </div>
    </section>

    <?php if ($flash['text'] !== ''): ?>
      <div class="flash <?= h($flash['type']) ?>"><?= h($flash['text']) ?></div>
    <?php endif; ?>

    <form method="post" class="file-panel" data-delete-form>
      <input type="hidden" name="action" value="delete_files">
      <div class="admin-bar">
        <div>
          <strong>Cleanup</strong>
          <span>Select files, enter password, delete.</span>
        </div>
        <label class="password-field">
          <span>Password</span>
          <input type="password" name="delete_password" autocomplete="current-password" placeholder="Delete password">
        </label>
        <button class="danger-btn" type="submit">Delete selected</button>
      </div>

      <div class="table-wrap">
        <table>
          <thead>
            <tr><th class="select-col"><input type="checkbox" data-select-all aria-label="Select all files"></th><th>File Name</th><th>File Size</th><th>Date</th></tr>
          </thead>
          <tbody>
<?php foreach ($fileList as $file): ?>
            <tr>
              <td class="select-col" data-label="Delete"><input type="checkbox" name="delete_files[]" value="<?= h($file) ?>" aria-label="Select <?= h($file) ?>"></td>
              <td data-label="File Name"><a href="<?= rawurlencode($file) ?>"><?= h($file) ?></a></td>
              <td data-label="File Size"><?= number_format(filesize($file), 0, '.', ' ') ?> B</td>
              <td data-label="Date"><?= date("Y-m-d H:i:s", filemtime($file)) ?></td>
            </tr>
<?php endforeach; ?>
<?php if (count($fileList) === 0): ?>
            <tr><td colspan="4" class="empty">No downloadable files found.</td></tr>
<?php endif; ?>
          </tbody>
        </table>
      </div>
    </form>
  </main>
  <script>
    (() => {
      const form = document.querySelector('[data-delete-form]');
      const selectAll = document.querySelector('[data-select-all]');
      if (!form || !selectAll) return;
      const boxes = () => Array.from(form.querySelectorAll('input[name="delete_files[]"]'));
      selectAll.addEventListener('change', () => {
        boxes().forEach(box => { box.checked = selectAll.checked; });
      });
      form.addEventListener('submit', event => {
        const selected = boxes().filter(box => box.checked).length;
        if (selected === 0) {
          event.preventDefault();
          alert('Select at least one file first.');
          return;
        }
        if (!confirm('Delete ' + selected + ' selected file(s)?')) {
          event.preventDefault();
        }
      });
    })();
  </script>
</body>
</html>
