<?php
session_start();

define('PASSWORD',   'fuhack2024');
define('ROOT_DIR',   __DIR__ . '/uploads/');
define('MAX_SIZE',   500 * 1024 * 1024);

$error = $success = '';

if (isset($_POST['password'])) {
    if ($_POST['password'] === PASSWORD) $_SESSION['files_auth'] = true;
    else $error = 'Wrong password.';
}
if (isset($_GET['logout'])) { session_destroy(); header('Location: /files/'); exit; }

$authed = !empty($_SESSION['files_auth']);

// Resolve current path (relative to ROOT_DIR, no traversal)
$rel = isset($_GET['path']) ? trim($_GET['path'], '/') : '';
$rel = str_replace(['..', "\0"], '', $rel);
$cwd = rtrim(ROOT_DIR . $rel, '/') . '/';
if (!is_dir($cwd)) { $rel = ''; $cwd = ROOT_DIR; }

// Create folder
if ($authed && isset($_POST['mkdir'])) {
    $dname = preg_replace('/[^a-zA-Z0-9_\-]/', '', trim($_POST['mkdir']));
    if ($dname) {
        $newdir = $cwd . $dname;
        if (!file_exists($newdir)) { mkdir($newdir, 0755); $success = "Folder '$dname' created."; }
        else $error = 'Folder already exists.';
    }
}

// Upload
if ($authed && isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
    $f = $_FILES['file'];
    if ($f['size'] > MAX_SIZE) { $error = 'Too large.'; }
    else {
        $name = preg_replace('/[^a-zA-Z0-9._\-]/', '_', basename($f['name']));
        $dest = $cwd . $name;
        if (file_exists($dest)) { $pi = pathinfo($name); $name = $pi['filename'].'_'.time().(isset($pi['extension'])? '.'.$pi['extension']:''); $dest = $cwd.$name; }
        move_uploaded_file($f['tmp_name'], $dest) ? $success = "Uploaded: $name" : $error = 'Upload failed.';
    }
}

// Delete file
if ($authed && isset($_GET['delete'])) {
    $t = $cwd . basename($_GET['delete']);
    if (is_file($t)) { unlink($t); $success = 'Deleted.'; }
    header('Location: /files/?path='.urlencode($rel)); exit;
}

// Delete folder
if ($authed && isset($_GET['rmdir'])) {
    $t = $cwd . basename($_GET['rmdir']);
    if (is_dir($t) && $t !== ROOT_DIR) {
        // only if empty
        $contents = array_diff(scandir($t), ['.','..']);
        if (empty($contents)) { rmdir($t); $success = 'Removed.'; }
        else $error = 'Folder not empty.';
    }
    header('Location: /files/?path='.urlencode($rel)); exit;
}

// Download
if ($authed && isset($_GET['dl'])) {
    $t = $cwd . basename($_GET['dl']);
    if (is_file($t)) {
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.basename($t).'"');
        header('Content-Length: '.filesize($t));
        readfile($t); exit;
    }
}

// List contents
$dirs = $files = [];
if ($authed && is_dir($cwd)) {
    foreach (scandir($cwd) as $item) {
        if ($item === '.' || $item === '..') continue;
        $full = $cwd . $item;
        if (is_dir($full)) $dirs[] = $item;
        elseif (is_file($full)) $files[] = ['name'=>$item,'size'=>filesize($full),'time'=>filemtime($full)];
    }
    sort($dirs);
    usort($files, fn($a,$b) => $b['time'] - $a['time']);
}

// Breadcrumb parts
function breadcrumb($rel) {
    $parts = $rel ? explode('/', $rel) : [];
    $crumbs = [['label'=>'/files','path'=>'']];
    $acc = '';
    foreach ($parts as $p) {
        $acc = trim($acc.'/'.$p, '/');
        $crumbs[] = ['label'=>$p,'path'=>$acc];
    }
    return $crumbs;
}

// Folder icons
function folder_icon($name) {
    $icons = ['hacker'=>'💀','fpv'=>'🚁','school'=>'📚','škola'=>'📚','music'=>'🎵','projects'=>'📁','docs'=>'📄'];
    return $icons[strtolower($name)] ?? '📁';
}

function fmt($b) {
    if ($b>=1073741824) return round($b/1073741824,1).' GB';
    if ($b>=1048576)    return round($b/1048576,1).' MB';
    if ($b>=1024)       return round($b/1024,1).' KB';
    return $b.' B';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>🌑 Files — fushift.fun</title>
<style>
  :root {
    --bg:#0a0a0f; --surface:#111118; --surface2:#16161f;
    --border:#1e1e2e; --border2:#2a2a3e;
    --accent:#7c3aed; --accent2:#a78bfa; --accent3:#6d28d9;
    --text:#e2e8f0; --muted:#64748b; --muted2:#475569;
    --red:#ef4444; --green:#22c55e; --yellow:#eab308;
    --font:'JetBrains Mono','Fira Code',monospace;
  }
  *{box-sizing:border-box;margin:0;padding:0;}
  body{background:var(--bg);color:var(--text);font-family:var(--font);min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:2rem 1rem;}
  .container{width:100%;max-width:860px;}

  /* Login */
  .login-box{background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:2.5rem 2rem;max-width:380px;margin:5rem auto;text-align:center;}
  .login-box .logo{font-size:2rem;margin-bottom:0.5rem;}
  .login-box h2{color:var(--accent2);font-size:1rem;margin-bottom:0.3rem;}
  .login-box p{color:var(--muted);font-size:0.75rem;margin-bottom:1.5rem;}
  .login-box input[type=password]{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-family:var(--font);font-size:0.9rem;padding:0.65rem 0.9rem;margin-bottom:0.8rem;outline:none;}
  .login-box input:focus{border-color:var(--accent);}

  /* Header */
  .topbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem;padding-bottom:0.8rem;border-bottom:1px solid var(--border);}
  .topbar-left{display:flex;align-items:center;gap:0.8rem;}
  .topbar h1{font-size:0.95rem;color:var(--accent2);letter-spacing:0.05em;}
  .badge{background:var(--surface);border:1px solid var(--border);border-radius:4px;padding:0.2rem 0.5rem;font-size:0.65rem;color:var(--muted);}
  .logout{font-size:0.72rem;color:var(--muted);text-decoration:none;}
  .logout:hover{color:var(--red);}

  /* Breadcrumb */
  .breadcrumb{display:flex;align-items:center;gap:0.3rem;font-size:0.78rem;margin-bottom:1.2rem;flex-wrap:wrap;}
  .breadcrumb a{color:var(--muted);text-decoration:none;}
  .breadcrumb a:hover{color:var(--accent2);}
  .breadcrumb .sep{color:var(--muted2);}
  .breadcrumb .cur{color:var(--accent2);}

  /* Toolbar */
  .toolbar{display:flex;gap:0.6rem;align-items:center;margin-bottom:1rem;flex-wrap:wrap;}
  .toolbar form{display:flex;gap:0.5rem;align-items:center;}
  .toolbar input[type=file]{background:var(--surface);border:1px solid var(--border);border-radius:6px;color:var(--muted);font-family:var(--font);font-size:0.72rem;padding:0.35rem 0.5rem;cursor:pointer;max-width:200px;}
  .toolbar input[type=text]{background:var(--surface);border:1px solid var(--border);border-radius:6px;color:var(--text);font-family:var(--font);font-size:0.78rem;padding:0.35rem 0.7rem;outline:none;width:140px;}
  .toolbar input[type=text]:focus{border-color:var(--accent);}
  .toolbar-sep{width:1px;height:24px;background:var(--border);margin:0 0.2rem;}

  /* Buttons */
  .btn{display:inline-flex;align-items:center;gap:0.3rem;background:var(--accent);color:#fff;border:none;border-radius:6px;padding:0.38rem 0.9rem;font-family:var(--font);font-size:0.78rem;cursor:pointer;text-decoration:none;transition:opacity .15s;white-space:nowrap;}
  .btn:hover{opacity:.85;}
  .btn.ghost{background:transparent;border:1px solid var(--border);color:var(--muted);}
  .btn.ghost:hover{border-color:var(--accent2);color:var(--accent2);}
  .btn.danger{background:transparent;border:1px solid #3a1111;color:var(--red);}
  .btn.danger:hover{border-color:var(--red);background:rgba(239,68,68,.05);}
  .btn.sm{padding:.2rem .55rem;font-size:.7rem;}

  /* Explorer */
  .explorer{background:var(--surface);border:1px solid var(--border);border-radius:8px;overflow:hidden;}
  .explorer-header{display:grid;grid-template-columns:1fr 80px 130px 90px;gap:0.5rem;padding:.4rem 1rem;background:var(--surface2);border-bottom:1px solid var(--border);font-size:.7rem;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;}

  /* Folder rows */
  .folder-row{display:grid;grid-template-columns:1fr 80px 130px 90px;gap:.5rem;align-items:center;padding:.5rem 1rem;border-bottom:1px solid var(--border);cursor:pointer;transition:background .1s;}
  .folder-row:hover{background:rgba(124,58,237,.06);}
  .folder-row a{text-decoration:none;display:contents;}
  .folder-name{display:flex;align-items:center;gap:.6rem;color:var(--accent2);font-size:.82rem;}
  .folder-icon{font-size:1rem;}
  .folder-meta{color:var(--muted);font-size:.72rem;}

  /* File rows */
  .file-row{display:grid;grid-template-columns:1fr 80px 130px 90px;gap:.5rem;align-items:center;padding:.45rem 1rem;border-bottom:1px solid var(--border);transition:background .1s;}
  .file-row:last-child{border-bottom:none;}
  .file-row:hover{background:rgba(124,58,237,.04);}
  .file-name{display:flex;align-items:center;gap:.6rem;color:var(--text);font-size:.8rem;word-break:break-all;}
  .file-ext{background:var(--surface2);border:1px solid var(--border);border-radius:3px;padding:.1rem .35rem;font-size:.6rem;color:var(--muted);text-transform:uppercase;white-space:nowrap;flex-shrink:0;}
  .file-size{color:var(--muted);font-size:.72rem;}
  .file-date{color:var(--muted2);font-size:.68rem;}
  .file-actions{display:flex;gap:.3rem;justify-content:flex-end;}

  .empty{padding:2.5rem;text-align:center;color:var(--muted);font-size:.82rem;}

  /* Alert */
  .alert{border-radius:6px;padding:.5rem .9rem;font-size:.75rem;margin-bottom:.8rem;border-left:2px solid;}
  .alert.error{border-color:var(--red);color:var(--red);background:rgba(239,68,68,.05);}
  .alert.success{border-color:var(--green);color:var(--green);background:rgba(34,197,94,.05);}

  footer{margin-top:1.5rem;font-size:.65rem;color:var(--muted2);text-align:center;}

  @media(max-width:600px){
    .explorer-header,.folder-row,.file-row{grid-template-columns:1fr 70px 80px;}
    .explorer-header>*:nth-child(3),.folder-row>*:nth-child(3),.file-row .file-date{display:none;}
  }
</style>
</head>
<body>
<div class="container">

<?php if (!$authed): ?>
<div class="login-box">
  <div class="logo">🌑</div>
  <h2>fushift.fun / files</h2>
  <p>Private file vault</p>
  <?php if ($error): ?><div class="alert error"><?= htmlspecialchars($error) ?></div><?php endif; ?>
  <form method="POST">
    <input type="password" name="password" placeholder="password" autofocus>
    <button class="btn" type="submit" style="width:100%">Unlock</button>
  </form>
</div>

<?php else:
$crumbs = breadcrumb($rel);
$parentPath = count($crumbs) > 1 ? $crumbs[count($crumbs)-2]['path'] : null;
$totalFiles = count($files); $totalDirs = count($dirs);
?>

<div class="topbar">
  <div class="topbar-left">
    <h1>🌑 Files</h1>
    <span class="badge"><?= $totalDirs ?> folder<?= $totalDirs!==1?'s':'' ?> · <?= $totalFiles ?> file<?= $totalFiles!==1?'s':'' ?></span>
  </div>
  <div style="display:flex;align-items:center;gap:1rem;">
    <a class="logout" href="?logout">logout</a>
  </div>
</div>

<!-- Breadcrumb -->
<div class="breadcrumb">
  <?php foreach ($crumbs as $i => $c): ?>
    <?php if ($i > 0): ?><span class="sep">/</span><?php endif; ?>
    <?php if ($i < count($crumbs)-1): ?>
      <a href="/files/?path=<?= urlencode($c['path']) ?>"><?= htmlspecialchars($c['label']) ?></a>
    <?php else: ?>
      <span class="cur"><?= htmlspecialchars($c['label']) ?></span>
    <?php endif; ?>
  <?php endforeach; ?>
</div>

<?php if ($error): ?><div class="alert error"><?= htmlspecialchars($error) ?></div><?php endif; ?>
<?php if ($success): ?><div class="alert success"><?= htmlspecialchars($success) ?></div><?php endif; ?>

<!-- Toolbar -->
<div class="toolbar">
  <form method="POST" enctype="multipart/form-data">
    <input type="hidden" name="path" value="<?= htmlspecialchars($rel) ?>">
    <input type="file" name="file">
    <button class="btn" type="submit">⬆ Upload</button>
  </form>
  <div class="toolbar-sep"></div>
  <form method="POST">
    <input type="hidden" name="path" value="<?= htmlspecialchars($rel) ?>">
    <input type="text" name="mkdir" placeholder="New folder...">
    <button class="btn ghost" type="submit">+ Folder</button>
  </form>
  <?php if ($parentPath !== null): ?>
  <div class="toolbar-sep"></div>
  <a class="btn ghost" href="/files/?path=<?= urlencode($parentPath) ?>">← Back</a>
  <?php endif; ?>
</div>

<!-- Explorer -->
<div class="explorer">
  <div class="explorer-header">
    <div>Name</div>
    <div>Size</div>
    <div>Modified</div>
    <div></div>
  </div>

  <?php if (empty($dirs) && empty($files)): ?>
    <div class="empty">Empty folder. Upload something or create a subfolder.</div>
  <?php endif; ?>

  <?php foreach ($dirs as $d):
    $dpath = trim($rel.'/'.$d, '/');
    $dsize = iterator_count(new FilesystemIterator($cwd.$d));
  ?>
  <div class="folder-row">
    <a href="/files/?path=<?= urlencode($dpath) ?>">
      <div class="folder-name">
        <span class="folder-icon"><?= folder_icon($d) ?></span>
        <?= htmlspecialchars($d) ?>
      </div>
      <div class="folder-meta"><?= $dsize ?> item<?= $dsize!==1?'s':'' ?></div>
      <div class="folder-meta"><?= date('Y-m-d H:i', filemtime($cwd.$d)) ?></div>
    </a>
    <div class="file-actions">
      <a class="btn sm danger" href="?path=<?= urlencode($rel) ?>&rmdir=<?= urlencode($d) ?>"
         onclick="return confirm('Remove folder <?= htmlspecialchars($d,ENT_QUOTES) ?>?')">✕</a>
    </div>
  </div>
  <?php endforeach; ?>

  <?php foreach ($files as $f):
    $ext = strtolower(pathinfo($f['name'], PATHINFO_EXTENSION));
  ?>
  <div class="file-row">
    <div class="file-name">
      <?php if ($ext): ?><span class="file-ext"><?= $ext ?></span><?php endif; ?>
      <?= htmlspecialchars($f['name']) ?>
    </div>
    <div class="file-size"><?= fmt($f['size']) ?></div>
    <div class="file-date"><?= date('Y-m-d H:i', $f['time']) ?></div>
    <div class="file-actions">
      <a class="btn sm ghost" href="?path=<?= urlencode($rel) ?>&dl=<?= urlencode($f['name']) ?>">⬇</a>
      <a class="btn sm danger" href="?path=<?= urlencode($rel) ?>&delete=<?= urlencode($f['name']) ?>"
         onclick="return confirm('Delete <?= htmlspecialchars($f['name'],ENT_QUOTES) ?>?')">✕</a>
    </div>
  </div>
  <?php endforeach; ?>
</div>

<?php endif; ?>
<footer>fushift.fun/files · Nox 🌑</footer>
</div>
</body>
</html>
