<?php
require __DIR__ . '/config.php';

$dir = isset($_GET['dir']) ? trim($_GET['dir']) : '';
$dir = ltrim(str_replace('\\', '/', $dir), '/');

$current = zerg_safe_path($dir);

if ($current === false || !is_dir($current)) {
    http_response_code(403);
    die('Access denied.');
}

// Guard against browsing into a hidden segment via a crafted URL.
foreach (explode('/', $dir) as $segment) {
    if ($segment !== '' && zerg_is_hidden($segment)) {
        http_response_code(403);
        die('Access denied.');
    }
}

$sort  = in_array($_GET['sort']  ?? '', ['name', 'size', 'date', 'downloads'], true) ? $_GET['sort']  : 'name';
$order = ($_GET['order'] ?? '') === 'desc' ? 'desc' : 'asc';

$counts = zerg_read_counts();

$rawItems = scandir($current);
$folders  = [];
$files    = [];
$totalSizeBytes = 0;

foreach ($rawItems as $item) {
    if (zerg_is_hidden($item)) continue;

    $full = $current . '/' . $item;
    $relative = ltrim(($dir === '' ? $item : $dir . '/' . $item), '/');
    $mtime = @filemtime($full) ?: 0;

    if (is_dir($full)) {
        $folders[] = [
            'name' => $item,
            'relative' => $relative,
            'mtime' => $mtime,
        ];
    } else {
        $size = @filesize($full) ?: 0;
        $totalSizeBytes += $size;
        [$icon, $kind] = zerg_file_kind($item);
        $files[] = [
            'name' => $item,
            'relative' => $relative,
            'size' => $size,
            'mtime' => $mtime,
            'downloads' => (int) ($counts[$relative] ?? 0),
            'icon' => $icon,
            'kind' => $kind,
        ];
    }
}

$dir_mult = ($order === 'desc') ? -1 : 1;

$sortFn = function ($a, $b) use ($sort, $dir_mult) {
    switch ($sort) {
        case 'size':      $cmp = $a['size']      <=> $b['size'];      break;
        case 'date':      $cmp = $a['mtime']     <=> $b['mtime'];     break;
        case 'downloads': $cmp = $a['downloads'] <=> $b['downloads']; break;
        default:          $cmp = strcasecmp($a['name'], $b['name']);
    }
    return $cmp * $dir_mult;
};

usort($folders, function ($a, $b) use ($sort, $dir_mult) {
    if ($sort === 'name') return strcasecmp($a['name'], $b['name']) * $dir_mult;
    if ($sort === 'date') return ($a['mtime'] <=> $b['mtime']) * $dir_mult;
    return strcasecmp($a['name'], $b['name']);
});
usort($files, $sortFn);

$topDownload = 0;
foreach ($files as $f) $topDownload = max($topDownload, $f['downloads']);

// Breadcrumb
$crumbs = [];
if ($dir !== '') {
    $parts = explode('/', $dir);
    $accum = '';
    foreach ($parts as $p) {
        $accum = ltrim($accum . '/' . $p, '/');
        $crumbs[] = ['name' => $p, 'path' => $accum];
    }
}
$parent = $dir !== '' ? implode('/', array_slice(explode('/', $dir), 0, -1)) : null;

function sort_link($label, $key, $sort, $order, $dir) {
    $nextOrder = ($sort === $key && $order === 'asc') ? 'desc' : 'asc';
    $arrow = '';
    if ($sort === $key) $arrow = $order === 'asc' ? ' ▲' : ' ▼';
    $url = '?dir=' . urlencode($dir) . '&sort=' . $key . '&order=' . $nextOrder;
    return '<a href="' . htmlspecialchars($url) . '" class="th-link">[' . $label . $arrow . ']</a>';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ZeRg // <?php echo htmlspecialchars($dir ?: '~'); ?></title>
<style>
@font-face {
  font-family: 'PixelTerm';
  src: local('Press Start 2P');
}

:root{
  --bg: #060a08;
  --panel: #0c1410;
  --panel-2: #0f1a14;
  --line: rgba(120, 255, 170, .16);
  --text: #b9f5c9;
  --text-dim: #5f8f74;
  --accent: #6dffb0;
  --accent-2: #ff2e63;
  --amber: #ffd166;
  --shadow: 0 0 20px rgba(0,0,0,.5);
}

*{ box-sizing: border-box; }

@media (prefers-reduced-motion: reduce){
  *{ animation: none !important; transition: none !important; }
}

html,body{ height:100%; }

body{
  margin:0;
  background: var(--bg);
  color: var(--text);
  font-family: 'JetBrains Mono','Fira Code','SFMono-Regular',Consolas,monospace;
  font-size: 14px;
  line-height:1.5;
  padding: 28px 16px 60px;
  position: relative;
  overflow-x:hidden;
}

canvas#rain{
  position:fixed; inset:0; z-index:0;
  opacity:.06; pointer-events:none;
}

.wrap{
  position:relative; z-index:1;
  max-width: 1100px;
  margin: 0 auto;
}

/* ---- terminal window chrome ---- */
.term{
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow);
  overflow:hidden;
}

.term-bar{
  display:flex; align-items:center; gap:8px;
  padding:10px 14px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  color: var(--text-dim);
  font-size:12px;
}

.dot{ width:11px; height:11px; border-radius:50%; background:#264a37; }
.term-bar .path{ margin-left:10px; opacity:.8; }

.term-body{ padding: 22px 22px 8px; }

/* ---- logo / boot ---- */
.logo{
  font-family:'PixelTerm','JetBrains Mono',monospace;
  font-size: clamp(15px, 3vw, 22px);
  letter-spacing: 1px;
  color: var(--accent);
  text-shadow: 0 0 6px rgba(109,255,176,.55), 0 0 18px rgba(109,255,176,.25);
  white-space: pre;
  overflow:hidden;
  border-right: 2px solid var(--accent);
  width: fit-content;
  animation: caret .9s steps(1) infinite;
}
@keyframes caret{ 50%{ border-color: transparent; } }

.boot{
  color: var(--text-dim);
  font-size:12px;
  margin: 10px 0 18px;
  min-height: 90px;
}
.boot div{ opacity:0; animation: fadein .25s forwards; }
.boot .ok{ color: var(--accent); }

@keyframes fadein{ to{ opacity:1; } }

.tagline{
  color: var(--text-dim);
  font-size:12px;
  margin: 2px 0 20px;
}

/* ---- breadcrumb ---- */
.crumbs{
  margin: 4px 0 18px;
  color: var(--text-dim);
  word-break: break-all;
}
.crumbs a{ color: var(--accent); }
.crumbs .sep{ color: var(--text-dim); margin: 0 3px; }

/* ---- controls ---- */
.controls{
  display:flex; gap:12px; flex-wrap:wrap;
  align-items:center;
  margin-bottom: 18px;
}

.search-box{
  flex:1; min-width:220px;
  display:flex; align-items:center;
  background: var(--bg);
  border:1px solid var(--line);
  border-radius:6px;
  padding: 8px 10px;
}
.search-box span{ color:var(--accent); margin-right:6px; }
.search-box input{
  flex:1; background:transparent; border:none; outline:none;
  color: var(--text); font-family:inherit; font-size:13px;
}
.search-box input::placeholder{ color: var(--text-dim); }

.stats{
  color: var(--text-dim); font-size:12px;
  display:flex; gap:14px; flex-wrap:wrap;
}
.stats b{ color: var(--accent); font-weight:600; }

/* ---- link back ---- */
.parent-row a{
  color: var(--amber);
}

/* ---- table ---- */
.table-wrap{ overflow-x:auto; border:1px solid var(--line); border-radius:8px; }

table{ width:100%; border-collapse:collapse; min-width: 560px; }

thead th{
  text-align:left;
  padding: 10px 14px;
  background: var(--panel-2);
  color: var(--text-dim);
  font-weight:600;
  font-size:12px;
  letter-spacing:.5px;
  border-bottom: 1px solid var(--line);
  white-space:nowrap;
}

.th-link{ color: var(--text-dim); }
.th-link:hover{ color: var(--accent); }

tbody td{
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

tbody tr{ transition: background .12s ease; }
tbody tr:hover{ background: rgba(109,255,176,.05); }
tbody tr:last-child td{ border-bottom:none; }

.name-cell{ display:flex; align-items:center; gap:10px; min-width:0; }
.name-cell a{ color: var(--text); }
.name-cell a:hover{ color: var(--accent); }
.icon{ font-size:16px; flex-shrink:0; }
.folder-name a{ color: var(--amber) !important; font-weight:600; }

.mono-num{ color: var(--text-dim); font-variant-numeric: tabular-nums; }
.hot{ color: var(--accent-2); }

.copy-btn{
  background:none; border:1px solid var(--line); color:var(--text-dim);
  border-radius:5px; padding:3px 7px; font-size:11px; cursor:pointer;
  font-family:inherit;
}
.copy-btn:hover{ border-color: var(--accent); color: var(--accent); }

.dl-btn{
  color: var(--bg); background: var(--accent);
  padding: 4px 9px; border-radius: 5px; font-size:11px; font-weight:700;
  text-decoration:none !important; white-space:nowrap;
}
.dl-btn:hover{ opacity:.85; }

.actions-cell{ display:flex; gap:6px; align-items:center; }

.empty{ padding: 40px 14px; text-align:center; color: var(--text-dim); }

.footer{
  margin-top: 16px;
  color: var(--text-dim);
  font-size: 11px;
  display:flex; justify-content:space-between; flex-wrap:wrap; gap:6px;
}
.footer .cursor{ animation: caret 1s steps(1) infinite; }

/* ---- responsive: stacked cards on small screens ---- */
@media (max-width: 700px){
  body{ padding: 16px 10px 50px; font-size:13px; }
  thead{ display:none; }
  table, tbody, tr, td{ display:block; width:100%; }
  .table-wrap{ border:none; }
  tbody tr{
    background: var(--panel);
    border:1px solid var(--line);
    border-radius:8px;
    margin-bottom:10px;
    padding: 8px 4px;
  }
  tbody td{ border-bottom:none; padding: 6px 12px; }
  .name-cell{ font-size:15px; }
  .meta-row{ display:flex; justify-content:space-between; color: var(--text-dim); font-size:12px; }
  td[data-label]:before{
    content: attr(data-label);
    color: var(--text-dim);
    display:inline-block; width:80px; font-size:11px;
  }
}
</style>
</head>
<body>
<canvas id="rain"></canvas>

<div class="wrap">
  <div class="term">
    <div class="term-bar">
      <span class="dot" style="background:#3a5a45"></span>
      <span class="dot" style="background:#3a5a45"></span>
      <span class="dot" style="background:#3a5a45"></span>
      <span class="path">root@zedev:~/<?php echo htmlspecialchars($dir); ?>$</span>
    </div>

    <div class="term-body">
      <div class="logo" id="logo">ZeRg // Coding_Hacking</div>

      <div class="boot" id="boot"></div>

      <div class="crumbs">
        ~/
        <?php if (empty($crumbs)): ?>
          <span style="color:var(--accent)">root</span>
        <?php else: ?>
          <a href="?dir=">root</a>
          <?php foreach ($crumbs as $i => $c): ?>
            <span class="sep">/</span>
            <?php if ($i === count($crumbs) - 1): ?>
              <span style="color:var(--accent)"><?php echo htmlspecialchars($c['name']); ?></span>
            <?php else: ?>
              <a href="?dir=<?php echo urlencode($c['path']); ?>"><?php echo htmlspecialchars($c['name']); ?></a>
            <?php endif; ?>
          <?php endforeach; ?>
        <?php endif; ?>
      </div>

      <div class="controls">
        <div class="search-box">
          <span>grep&gt;</span>
          <input type="text" id="filterInput" placeholder="filter files in this directory..." autocomplete="off">
        </div>
        <div class="stats">
          <span><b><?php echo count($folders); ?></b> dirs</span>
          <span><b><?php echo count($files); ?></b> files</span>
          <span><b><?php echo zerg_format_size($totalSizeBytes); ?></b> total</span>
        </div>
      </div>

      <div class="table-wrap">
        <table id="fileTable">
          <thead>
            <tr>
              <th><?php echo sort_link('NAME', 'name', $sort, $order, $dir); ?></th>
              <th><?php echo sort_link('SIZE', 'size', $sort, $order, $dir); ?></th>
              <th><?php echo sort_link('MODIFIED', 'date', $sort, $order, $dir); ?></th>
              <th><?php echo sort_link('DOWNLOADS', 'downloads', $sort, $order, $dir); ?></th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            <?php if ($parent !== null): ?>
            <tr class="parent-row">
              <td colspan="5">
                <a href="?dir=<?php echo urlencode($parent); ?>">⬅ ../ (parent directory)</a>
              </td>
            </tr>
            <?php endif; ?>

            <?php foreach ($folders as $f): ?>
            <tr data-name="<?php echo htmlspecialchars(strtolower($f['name'])); ?>">
              <td data-label="Name" class="folder-name">
                <div class="name-cell">
                  <span class="icon">📁</span>
                  <a href="?dir=<?php echo urlencode($f['relative']); ?>"><?php echo htmlspecialchars($f['name']); ?>/</a>
                </div>
              </td>
              <td data-label="Size" class="mono-num">—</td>
              <td data-label="Modified" class="mono-num"><?php echo date('Y-m-d H:i', $f['mtime']); ?></td>
              <td data-label="Downloads" class="mono-num">—</td>
              <td data-label=""></td>
            </tr>
            <?php endforeach; ?>

            <?php foreach ($files as $f): ?>
            <tr data-name="<?php echo htmlspecialchars(strtolower($f['name'])); ?>">
              <td data-label="Name">
                <div class="name-cell">
                  <span class="icon"><?php echo $f['icon']; ?></span>
                  <a href="download.php?file=<?php echo urlencode($f['relative']); ?>"><?php echo htmlspecialchars($f['name']); ?></a>
                </div>
              </td>
              <td data-label="Size" class="mono-num"><?php echo zerg_format_size($f['size']); ?></td>
              <td data-label="Modified" class="mono-num"><?php echo date('Y-m-d H:i', $f['mtime']); ?></td>
              <td data-label="Downloads" class="mono-num<?php echo ($f['downloads'] > 0 && $f['downloads'] === $topDownload) ? ' hot' : ''; ?>">
                <?php echo number_format($f['downloads']); ?><?php if ($f['downloads'] > 0 && $f['downloads'] === $topDownload) echo ' 🔥'; ?>
              </td>
              <td data-label="" class="actions-cell">
                <a class="dl-btn" href="download.php?file=<?php echo urlencode($f['relative']); ?>" download>GET</a>
                <button class="copy-btn" data-path="download.php?file=<?php echo urlencode($f['relative']); ?>" onclick="zergCopyLink(this)">copy</button>
              </td>
            </tr>
            <?php endforeach; ?>

            <?php if (empty($folders) && empty($files)): ?>
            <tr><td colspan="5" class="empty">// directory is empty</td></tr>
            <?php endif; ?>
          </tbody>
        </table>
      </div>

      <div class="footer">
        <span>ZeRg Coding // Hacking — file index<span class="cursor">_</span></span>
        <span>scanned <?php echo date('Y-m-d H:i:s'); ?></span>
      </div>
    </div>
  </div>
</div>

<script>
// ---- boot sequence ----
(function(){
  const lines = [
    'initializing zerg_index.sh ...',
    'mounting filesystem ......... <span class="ok">OK</span>',
    'checking permissions ........ <span class="ok">OK</span>',
    'loading download counters ... <span class="ok">OK</span>',
    'ready.'
  ];
  const boot = document.getElementById('boot');
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reduced) {
    boot.innerHTML = lines.map(l => '<div style="opacity:1">' + l + '</div>').join('');
    return;
  }
  lines.forEach((line, i) => {
    const el = document.createElement('div');
    el.innerHTML = line;
    el.style.animationDelay = (i * 0.15) + 's';
    boot.appendChild(el);
  });
})();

// ---- live filter ----
const filterInput = document.getElementById('filterInput');
filterInput.addEventListener('input', () => {
  const q = filterInput.value.trim().toLowerCase();
  document.querySelectorAll('#fileTable tbody tr[data-name]').forEach(row => {
    row.style.display = row.dataset.name.includes(q) ? '' : 'none';
  });
});

// ---- copy link ----
function zergCopyLink(btn){
  const url = new URL(btn.dataset.path, window.location.href).href;
  navigator.clipboard.writeText(url).then(() => {
    const old = btn.textContent;
    btn.textContent = 'copied';
    setTimeout(() => btn.textContent = old, 1200);
  }).catch(() => {
    prompt('Copy link:', url);
  });
}

// ---- subtle matrix rain ----
(function(){
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const canvas = document.getElementById('rain');
  if (reduced || window.innerWidth < 700) { canvas.remove(); return; }
  const ctx = canvas.getContext('2d');
  let w, h, cols, drops;

  function resize(){
    w = canvas.width = window.innerWidth;
    h = canvas.height = window.innerHeight;
    cols = Math.floor(w / 16);
    drops = new Array(cols).fill(0);
  }
  resize();
  window.addEventListener('resize', resize);

  const chars = 'アイウエオカキクケコ01ZERG';
  function draw(){
    ctx.fillStyle = 'rgba(6,10,8,0.08)';
    ctx.fillRect(0, 0, w, h);
    ctx.fillStyle = '#6dffb0';
    ctx.font = '14px monospace';
    for (let i = 0; i < drops.length; i++){
      const text = chars[Math.floor(Math.random() * chars.length)];
      ctx.fillText(text, i * 16, drops[i] * 16);
      if (drops[i] * 16 > h && Math.random() > 0.975) drops[i] = 0;
      drops[i]++;
    }
  }
  setInterval(draw, 60);
})();
</script>
</body>
</html>
