<?php
/*******************************************************
 * property_documents.php
 * - Shows documents for ?filenumber=...
 * - PDO include path per request: ../../includes/connect.php
 * - Files render on initial load (no need for action=list)
 *******************************************************/
declare(strict_types=1);
session_start();
header_remove('X-Powered-By');

require_once __DIR__ . '/../../includes/connect.php'; // MUST define $pdo (PDO)

if (!isset($_GET['filenumber']) || trim($_GET['filenumber']) === '') {
    http_response_code(400);
    echo "Missing ?filenumber parameter.";
    exit;
}
$filenumber = trim($_GET['filenumber']);

/* ----------------------- Helpers ----------------------- */
function json_response(array $payload, int $code = 200): void {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($payload);
    exit;
}
function ensure_dir(string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0775, true); }
function mime_from_ext(string $path): string {
    $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
    return match ($ext) {
        'jpg','jpeg' => 'image/jpeg',
        'png'        => 'image/png',
        'gif'        => 'image/gif',
        'webp'       => 'image/webp',
        'pdf'        => 'application/pdf',
        default      => 'application/octet-stream',
    };
}
function generate_thumbnail(string $absolutePath, string $thumbPath, string $mime, int $maxW=360, int $maxH=360): bool {
    if (is_file($thumbPath)) return true;

    if (str_starts_with($mime, 'image/')) {
        $img = null;
        switch ($mime) {
            case 'image/jpeg': $img=@imagecreatefromjpeg($absolutePath); break;
            case 'image/png' : $img=@imagecreatefrompng($absolutePath);  break;
            case 'image/gif' : $img=@imagecreatefromgif($absolutePath);  break;
            case 'image/webp': $img=function_exists('imagecreatefromwebp')?@imagecreatefromwebp($absolutePath):null; break;
        }
        if (!$img) return false;
        $w=imagesx($img); $h=imagesy($img);
        $scale=min($maxW/max(1,$w), $maxH/max(1,$h), 1.0);
        $nw=max(1,(int)floor($w*$scale)); $nh=max(1,(int)floor($h*$scale));
        $dst=imagecreatetruecolor($nw,$nh);
        imagecopyresampled($dst,$img,0,0,0,0,$nw,$nh,$w,$h);
        ensure_dir(dirname($thumbPath));
        $ok=imagejpeg($dst,$thumbPath,82);
        imagedestroy($img); imagedestroy($dst);
        return $ok;
    }

    if ($mime==='application/pdf' && class_exists('Imagick')) {
        try {
            $im=new Imagick(); $im->setResolution(140,140);
            $im->readImage($absolutePath."[0]");
            $im->setImageFormat('jpg'); $im->thumbnailImage(360,360,true);
            ensure_dir(dirname($thumbPath));
            $ok=$im->writeImage($thumbPath);
            $im->clear(); $im->destroy(); return $ok;
        } catch (Throwable $e) { /* fallback below */ }
    }

    // Fallback generic icon
    try {
        $c=imagecreatetruecolor(320,200);
        $bg=imagecolorallocate($c,245,245,245);
        $fg=imagecolorallocate($c,70,70,70);
        imagefilledrectangle($c,0,0,320,200,$bg);
        imagerectangle($c,60,30,260,170,$fg);
        imageline($c,60,60,260,60,$fg);
        imageline($c,60,90,260,90,$fg);
        imageline($c,60,120,260,120,$fg);
        imageline($c,60,150,260,150,$fg);
        ensure_dir(dirname($thumbPath));
        imagejpeg($c,$thumbPath,82);
        imagedestroy($c);
        return true;
    } catch (Throwable $e) { return false; }
}
function storage_paths(string $filenumber, string $originalName): array {
    $safeBase = preg_replace('/[^\w\-.]+/', '_', $originalName);
    $root     = __DIR__ . "/uploads/properties/{$filenumber}";
    $thumbDir = $root . "/thumbnails";
    ensure_dir($root); ensure_dir($thumbDir);

    $target = $root . '/' . $safeBase; $i=1;
    while (file_exists($target)) {
        $pi=pathinfo($safeBase);
        $base=$pi['filename']??'file';
        $ext =isset($pi['extension'])?('.'.$pi['extension']):'';
        $target=$root.'/'.$base."_{$i}{$ext}";
        $i++;
    }
    $thumb = $thumbDir . '/' . pathinfo($target, PATHINFO_FILENAME) . ".jpg";

    $relFile  = ltrim(str_replace(['\\',__DIR__], ['/', ''], $target), '/');
    $relThumb = ltrim(str_replace(['\\',__DIR__], ['/', ''], $thumb), '/');
    return [$target, $thumb, $relFile, $relThumb];
}

/* ----------------------- AJAX (kept for post-upload refresh) ----------------------- */
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$action = $_REQUEST['action'] ?? null;

if ($method === 'GET' && $action === 'list') {
    // still available, but initial page doesn’t depend on it
    $stmt = $pdo->prepare("
        SELECT id, filename, filepath, title, doc_type, created_at, updated_at
        FROM documents
        WHERE (filenumber = :fn OR title = :fn) AND (status IS NULL OR status <> 'deleted')
        ORDER BY COALESCE(updated_at, created_at) DESC
    ");
    $stmt->execute([':fn' => $filenumber]);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
    foreach ($rows as &$r) {
        $abs = __DIR__ . '/' . ltrim($r['filepath'], '/');
        $mime = mime_from_ext($abs);
        $pi   = pathinfo($abs);
        $thumbAbs = __DIR__."/uploads/properties/{$filenumber}/thumbnails/".($pi['filename'] ?? 'file').".jpg";
        $thumbRel = "uploads/properties/{$filenumber}/thumbnails/".($pi['filename'] ?? 'file').".jpg";
        if (is_file($abs)) @generate_thumbnail($abs, $thumbAbs, $mime);
        $r['thumbnail'] = is_file($thumbAbs) ? $thumbRel : null;
    }
    unset($r);
    json_response(['ok' => true, 'documents' => $rows]);
}

if ($method === 'POST' && $action === 'upload') {
    if (!isset($_FILES['files'])) json_response(['ok'=>false,'error'=>'No files uploaded'], 400);
    $docType = $_POST['doc_type'] ?? null;
    $titleFromForm = trim($_POST['title'] ?? '');

    $saved = [];
    foreach ($_FILES['files']['error'] as $i=>$err) {
        if ($err !== UPLOAD_ERR_OK) continue;
        $tmp  = $_FILES['files']['tmp_name'][$i];
        $name = $_FILES['files']['name'][$i];

        [$absT, $absTh, $relFile, $relTh] = storage_paths($filenumber, $name);
        if (!@move_uploaded_file($tmp, $absT)) {
            if (!@copy($tmp, $absT)) continue;
        }

        $mime = mime_from_ext($absT);
        @generate_thumbnail($absT, $absTh, $mime);

        $stmt = $pdo->prepare("
            INSERT INTO documents (filename, filepath, title, doc_type, filesize, status, created_at, updated_at, filenumber)
            VALUES (:filename, :filepath, :title, :doc_type, :filesize, 'active', NOW(), NOW(), :filenumber)
        ");
        $filesize = filesize($absT) ?: null;
        $stmt->execute([
            ':filename'   => basename($absT),
            ':filepath'   => $relFile,
            ':title'      => ($titleFromForm !== '' ? $titleFromForm : $filenumber),
            ':doc_type'   => $docType,
            ':filesize'   => $filesize,
            ':filenumber' => $filenumber
        ]);

        $saved[] = ['filename'=>basename($absT),'filepath'=>$relFile,'thumbnail'=>is_file($absTh)?$relTh:null];
    }

    json_response(['ok'=>true,'saved'=>$saved]);
}

/* ----------------------- Header + INITIAL DOCS (server-side render) ----------------------- */
$header = [
    'filenumber'   => $filenumber,
    'fileid'       => null,
    'propertydesc' => null,
    'lgacode'      => null,
    'propertyid'   => null,
];

try {
    $stmt = $pdo->prepare("
        SELECT f.fileid, f.filenumber, p.propertydesc, p.lgacode, p.propertyid
        FROM file f
        LEFT JOIN property p ON p.fileid = f.fileid
        WHERE f.filenumber = :fn
        LIMIT 1
    ");
    $stmt->execute([':fn' => $filenumber]);
    if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $header = array_merge($header, $row);
} catch (Throwable $e) {}

/* Fetch documents NOW so page shows them on first paint */
$initialDocs = [];
try {
    $stmt = $pdo->prepare("
        SELECT id, filename, filepath, title, doc_type, created_at, updated_at
        FROM documents
        WHERE (filenumber = :fn ) 
        ORDER BY COALESCE(updated_at, created_at) DESC
    ");
    $stmt->execute([':fn' => $filenumber]);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

    foreach ($rows as $r) {
        $abs = __DIR__ . '/' . ltrim($r['filepath'], '/');
        $mime = mime_from_ext($abs);
        $pi   = pathinfo($abs);
        $thumbAbs = __DIR__."/uploads/properties/{$filenumber}/thumbnails/".($pi['filename'] ?? 'file').".jpg";
        $thumbRel = "uploads/properties/{$filenumber}/thumbnails/".($pi['filename'] ?? 'file').".jpg";
        if (is_file($abs)) @generate_thumbnail($abs, $thumbAbs, $mime);
        $r['thumbnail'] = is_file($thumbAbs) ? $thumbRel : null;

        $initialDocs[] = $r;
    }
} catch (Throwable $e) {
    $initialDocs = [];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>Property Documents — <?= htmlspecialchars($filenumber) ?></title>
<style>
:root{ --bg:#0b1220; --fg:#e5e7eb; --muted:#94a3b8; --card:#0f172a; --border:#1f2937; --chip:#1f2937; --accent:#22c55e; --accent2:#06b6d4; --overlay:rgba(15,23,42,.85); --shadow:0 10px 30px rgba(0,0,0,.35);}
:root.light{ --bg:#f8fafc; --fg:#0f172a; --muted:#475569; --card:#ffffff; --border:#e2e8f0; --chip:#eef2f7; --accent:#16a34a; --accent2:#0891b2; --overlay:rgba(0,0,0,.5); --shadow:0 8px 20px rgba(0,0,0,.08);}
*{box-sizing:border-box}
body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,'Helvetica Neue',Arial;background:var(--bg);color:var(--fg);}
.container{max-width:1200px;margin:24px auto;padding:0 16px;}
.header{background:linear-gradient(180deg, rgba(34,197,94,.10), transparent 70%),linear-gradient(180deg, rgba(6,182,212,.10), transparent 30%);border:1px solid var(--border);border-radius:16px;padding:18px 20px;box-shadow:var(--shadow);}
.header h1{margin:0 0 6px;font-size:22px;}
.header .sub{color:var(--muted);font-size:14px}
.chips{margin-top:12px;display:flex;gap:8px;flex-wrap:wrap}
.chip{background:var(--chip);color:var(--muted);border:1px solid var(--border);padding:6px 10px;border-radius:999px;font-size:12px;}
.toolbar{display:flex;align-items:center;gap:12px;margin:18px 0;}
.btn{appearance:none;border:1px solid var(--border);color:var(--fg);background:var(--bg);padding:8px 12px;border-radius:10px;cursor:pointer;}
.btn.primary{background:var(--accent);border-color:transparent;color:#052e16;font-weight:600;}
.btn.ghost{background:var(--bg);}
.view-toggle{display:flex;gap:8px}
.searchbox{flex:1;position:relative;}
.searchbox input{width:100%;padding:10px 14px 10px 36px;border-radius:10px;border:1px solid var(--border);background:var(--bg);color:var(--fg);}
.searchbox .icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);font-size:14px;color:var(--muted);}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:14px;}
.card{background:var(--card);border:1px solid var(--border);border-radius:14px;overflow:hidden;transition:transform .15s, box-shadow .15s;cursor:pointer;}
.card:hover{transform:translateY(-2px);box-shadow:var(--shadow);}
.thumb{width:100%;height:140px;background:var(--bg);display:flex;align-items:center;justify-content:center;overflow:hidden;}
.thumb img{width:100%;height:100%;object-fit:cover;display:block;}
.meta{padding:10px 12px;}
.meta .name{font-size:14px;font-weight:600;color:var(--fg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.meta .sub{font-size:12px;color:var(--muted);display:flex;gap:8px;flex-wrap:wrap;margin-top:6px;}
.tablewrap{overflow:auto;border:1px solid var(--border);border-radius:12px;}
table{width:100%;border-collapse:collapse;background:var(--card);}
th,td{border-bottom:1px solid var(--border);padding:10px 12px;font-size:14px;color:var(--fg);}
th{font-weight:600;color:var(--muted);background:var(--card);position:sticky;top:0;}
.row-actions{display:flex;gap:8px;align-items:center;}
.hidden{display:none!important;}
.empty{border:1px dashed var(--border);border-radius:14px;padding:26px;text-align:center;color:var(--muted);}
.empty .btn{margin-top:10px;}
/* Viewer Modal */
.modal-overlay{position:fixed;inset:0;background:var(--overlay);display:none;align-items:center;justify-content:center;z-index:9999;}
.modal{width:min(92vw,1000px);height:min(90vh,720px);background:var(--bg);border:1px solid var(--border);border-radius:16px;display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--shadow);}
.modal-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--border);background:var(--card);}
.modal-body{flex:1}
.modal-body embed,.modal-body img{width:100%;height:100%;display:block;border:0;background:var(--bg);}
/* Upload Modal */
.up-overlay{position:fixed;inset:0;background:var(--overlay);display:none;align-items:center;justify-content:center;z-index:10000;}
.up-modal{width:min(92vw,860px);background:var(--bg);border:1px solid var(--border);border-radius:16px;box-shadow:var(--shadow);overflow:hidden;display:flex;flex-direction:column;}
.up-head{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--border);background:var(--card);}
.up-body{padding:14px;display:grid;grid-template-columns:1fr 1fr;gap:12px;}
@media(max-width:700px){.up-body{grid-template-columns:1fr}}
.input,select{width:100%;padding:10px 12px;border-radius:10px;border:1px solid var(--border);background:var(--bg);color:var(--fg);}
.drop{min-height:180px;display:flex;align-items:center;justify-content:center;border:2px dashed var(--border);border-radius:12px;color:var(--muted);padding:16px;}
.preview{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px;margin-top:10px;}
.pthumb{border:1px solid var(--border);border-radius:10px;overflow:hidden;background:var(--card);}
.pthumb img{width:100%;height:90px;object-fit:cover;display:block;}
.pthumb .ptitle{font-size:12px;padding:6px 8px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pdfthumb{display:flex;align-items:center;justify-content:center;height:90px;font-weight:700;color:var(--fg);background:linear-gradient(135deg, rgba(6,182,212,.2), rgba(34,197,94,.2));}
.up-actions{display:flex;justify-content:flex-end;gap:10px;padding:12px 14px;border-top:1px solid var(--border);background:var(--card);}
.toast{position:fixed;top:14px;left:50%;transform:translateX(-50%);background:#16a34a;color:#052e16;font-weight:600;padding:10px 14px;border-radius:10px;z-index:11000;display:none;}
.toast.error{background:#dc2626;color:#450a0a;}
</style>
</head>
<body>
<div class="container">
  <!-- Header -->
  <div class="header">
    <h1>Documents for <span style="color:var(--accent)"><?= htmlspecialchars($header['filenumber'] ?? $filenumber) ?></span></h1>
    <div class="sub">
      <?php if (!empty($header['propertydesc'])): ?>
        <?= htmlspecialchars($header['propertydesc']) ?><?= !empty($header['lgacode']) ? ' · LGA: '.htmlspecialchars($header['lgacode']) : '' ?>
      <?php else: ?>
        Linked to file: <span class="chip">#<?= htmlspecialchars((string)($header['fileid'] ?? '—')) ?></span>
      <?php endif; ?>
    </div>
    <div class="chips">
      <div class="chip">File ID: <?= htmlspecialchars((string)($header['fileid'] ?? '—')) ?></div>
      <div class="chip">Property ID: <?= htmlspecialchars((string)($header['propertyid'] ?? '—')) ?></div>
    </div>
  </div>

  <!-- Toolbar -->
  <div class="toolbar">
    <div class="view-toggle">
      <button id="gridBtn" class="btn ghost">Grid View</button>
      <button id="tableBtn" class="btn ghost">Table View</button>
    </div>
    <div class="searchbox"><span class="icon">🔎</span><input id="searchInput" placeholder="Search by filename, title, or type…"/></div>
    <button id="openUpload" class="btn primary" type="button">Upload New</button>
    <button id="themeToggle" class="btn" type="button">Theme</button>
  </div>

  <!-- Grid (default) -->
  <div id="gridView" class="grid"></div>
  <div id="gridEmpty" class="empty"><div>No documents yet.</div><button id="gridUploadBtn" class="btn primary" type="button">Upload Documents</button></div>

  <!-- Table -->
  <div id="tableView" class="tablewrap hidden">
    <table>
      <thead>
        <tr>
          <th style="width:56px">Preview</th>
          <th>Filename</th>
          <th>Title</th>
          <th>Doc Type</th>
          <th>Created</th>
          <th>Updated</th>
          <th style="width:80px">Action</th>
        </tr>
      </thead>
      <tbody id="tableBody"></tbody>
    </table>
  </div>
  <div id="tableEmpty" class="empty hidden"><div>No documents yet.</div><button id="tableUploadBtn" class="btn primary" type="button">Upload Documents</button></div>
</div>

<!-- Viewer Modal -->
<div id="modalOverlay" class="modal-overlay">
  <div class="modal">
    <div class="modal-header">
      <div class="title" id="modalTitle">Preview</div>
      <div>
        <a id="downloadBtn" class="btn" href="#" download>Download</a>
        <button id="closeModal" class="btn">Close</button>
      </div>
    </div>
    <div class="modal-body" id="modalBody"></div>
  </div>
</div>

<!-- Upload Modal -->
<div id="uploadOverlay" class="up-overlay">
  <div class="up-modal">
    <div class="up-head">
      <div class="up-title">Upload Documents</div>
      <button id="closeUpload" class="btn">Close</button>
    </div>
    <div class="up-body">
      <div style="grid-column:1/-1">
        <label>Title
          <input id="titleInput" class="input" type="text" placeholder="e.g., Survey Plan for Plot 42"/>
        </label>
      </div>
      <div>
        <div id="dropArea" class="drop">
          <div>
            <strong>Drag & drop files</strong> here or
            <label class="btn" style="margin-left:6px;cursor:pointer;">
              Browse<input id="fileInput" type="file" multiple style="display:none"/>
            </label>
            <div class="empty-hint" style="margin-top:8px;color:var(--muted);font-size:12px;">Images & PDFs supported. Thumbnails auto-generated after upload; quick previews appear below.</div>
          </div>
        </div>
        <div id="previewArea" class="preview"></div>
      </div>
      <div>
        <label>Document Type
          <select id="docType">
            <option value="">— Select —</option>
            <option value="Survey Plan">Survey Plan</option>
            <option value="C of O">C of O</option>
            <option value="Receipt">Receipt</option>
            <option value="Deed">Deed</option>
            <option value="Other">Other</option>
          </select>
        </label>
      </div>
    </div>
    <div class="up-actions">
      <button id="uploadBtn" class="btn primary" type="button">Upload</button>
    </div>
  </div>
</div>

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

<script>
/* ====== PHP → JS boot data (files shown on initial load) ====== */
const initialDocs = <?= json_encode($initialDocs, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>;
const filenumber  = <?= json_encode($filenumber) ?>;

/* Theme */
(function initTheme(){
  const root=document.documentElement, saved=localStorage.getItem('theme');
  if (saved==='light') root.classList.add('light'); else root.classList.remove('light');
})();
document.getElementById('themeToggle').addEventListener('click',()=>{
  const root=document.documentElement; const toLight=!root.classList.contains('light');
  root.classList.toggle('light', toLight); localStorage.setItem('theme', toLight?'light':'dark');
});

/* Elements */
const gridBtn=document.getElementById('gridBtn'), tableBtn=document.getElementById('tableBtn');
const gridView=document.getElementById('gridView'), tableView=document.getElementById('tableView');
const gridEmpty=document.getElementById('gridEmpty'), tableEmpty=document.getElementById('tableEmpty');
const tableBody=document.getElementById('tableBody');
const searchInput=document.getElementById('searchInput');
const openUpload=document.getElementById('openUpload');
const gridUploadBtn=document.getElementById('gridUploadBtn'), tableUploadBtn=document.getElementById('tableUploadBtn');
const uploadOverlay=document.getElementById('uploadOverlay'), closeUpload=document.getElementById('closeUpload');
const dropArea=document.getElementById('dropArea'), fileInput=document.getElementById('fileInput');
const previewArea=document.getElementById('previewArea');
const docType=document.getElementById('docType'), titleInput=document.getElementById('titleInput');
const uploadBtn=document.getElementById('uploadBtn');
const modalOverlay=document.getElementById('modalOverlay'), closeModal=document.getElementById('closeModal');
const modalTitle=document.getElementById('modalTitle'), modalBody=document.getElementById('modalBody'), downloadBtn=document.getElementById('downloadBtn');
const toastEl=document.getElementById('toast');

/* State */
let allDocs = Array.isArray(initialDocs) ? initialDocs : [];
let pendingFiles = [];

/* Utils */
function showToast(msg, err=false){ toastEl.textContent=msg; toastEl.classList.toggle('error',!!err); toastEl.style.display='block'; setTimeout(()=>toastEl.style.display='none',2600); }
function esc(s){return (s??'').toString().replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;')}
const isPdf = p => /\.pdf(\?.*)?$/i.test(p);
const isImg = p => /\.(png|jpe?g|gif|webp)(\?.*)?$/i.test(p);

/* Default: Grid is active; show empty state immediately if no docs */
function syncEmptyStates(filteredCount){
  if (filteredCount === 0) {
    if (!gridView.classList.contains('hidden')) gridEmpty.classList.remove('hidden');
    if (!tableView.classList.contains('hidden')) tableEmpty.classList.remove('hidden');
  } else {
    gridEmpty.classList.add('hidden'); tableEmpty.classList.add('hidden');
  }
}

/* Render */
function render(){
  const q=(searchInput.value||'').trim().toLowerCase();
  const filtered=allDocs.filter(d=>{
    if(!q) return true;
    return (d.filename||'').toLowerCase().includes(q)
        || (d.title||'').toLowerCase().includes(q)
        || (d.doc_type||'').toLowerCase().includes(q);
  });

  // GRID
  if (!gridView.classList.contains('hidden')) {
    if (filtered.length===0){
      gridView.innerHTML=''; gridEmpty.classList.remove('hidden');
    } else {
      gridEmpty.classList.add('hidden');
      gridView.innerHTML=filtered.map(d=>{
        const t=d.thumbnail?`<img src="${esc(d.thumbnail)}" alt="thumb">`:`<div class="pdfthumb">PREVIEW</div>`;
        return `<div class="card" data-path="${esc(d.filepath)}" data-name="${esc(d.filename)}">
          <div class="thumb">${t}</div>
          <div class="meta">
            <div class="name" title="${esc(d.filename)}">${esc(d.filename)}</div>
            <div class="sub"><span class="chip">${esc(d.doc_type||'—')}</span><span>Title: ${esc(d.title||'—')}</span><span>Created: ${esc(d.created_at||'—')}</span></div>
          </div>
        </div>`;
      }).join('');
      gridView.querySelectorAll('.card').forEach(el=>el.addEventListener('click',()=>openViewer(el.dataset.path, el.dataset.name)));
    }
  }

  // TABLE
  if (!tableView.classList.contains('hidden')) {
    if (filtered.length===0){
      tableBody.innerHTML=''; tableEmpty.classList.remove('hidden');
    } else {
      tableEmpty.classList.add('hidden');
      tableBody.innerHTML=filtered.map(d=>`
        <tr data-path="${esc(d.filepath)}" data-name="${esc(d.filename)}">
          <td>${ d.thumbnail?`<img src="${esc(d.thumbnail)}" style="width:48px;height:36px;object-fit:cover;border-radius:6px;border:1px solid var(--border);">`:`<span style="color:var(--muted)">—</span>`}</td>
          <td>${esc(d.filename)}</td>
          <td>${esc(d.title||'')}</td>
          <td><span class="chip">${esc(d.doc_type||'—')}</span></td>
          <td>${esc(d.created_at||'—')}</td>
          <td>${esc(d.updated_at||'—')}</td>
          <td class="row-actions">
            <button class="btn" data-action="view">View</button>
            <a class="btn" href="${esc(d.filepath)}" download>Download</a>
          </td>
        </tr>`).join('');
      tableBody.querySelectorAll('tr').forEach(tr=>{
        tr.addEventListener('click',e=>{
          if (e.target instanceof HTMLElement && e.target.tagName==='A') return;
          openViewer(tr.dataset.path,tr.dataset.name);
        });
      });
    }
  }

  syncEmptyStates(filtered.length);
}

/* Viewer */
function openViewer(path,name){
  modalTitle.textContent=name||'Preview'; downloadBtn.href=path; downloadBtn.setAttribute('download', name||'');
  const safe=esc(path);
  if (isImg(path)) modalBody.innerHTML=`<img src="${safe}" alt="${esc(name||'image')}">`;
  else if (isPdf(path)) modalBody.innerHTML=`<embed src="${safe}#toolbar=1&navpanes=0&scrollbar=1" type="application/pdf">`;
  else modalBody.innerHTML=`<div style="padding:16px;">Cannot preview this type. Use Download.</div>`;
  modalOverlay.style.display='flex';
}
closeModal.addEventListener('click',()=>modalOverlay.style.display='none');
modalOverlay.addEventListener('click',e=>{ if(e.target===modalOverlay) modalOverlay.style.display='none'; });

/* View toggle */
gridBtn.addEventListener('click',()=>{
  gridView.classList.remove('hidden'); gridEmpty.classList.toggle('hidden', allDocs.length>0);
  tableView.classList.add('hidden');   tableEmpty.classList.add('hidden');
  render();
});
tableBtn.addEventListener('click',()=>{
  tableView.classList.remove('hidden'); tableEmpty.classList.toggle('hidden', allDocs.length>0);
  gridView.classList.add('hidden');     gridEmpty.classList.add('hidden');
  render();
});
searchInput.addEventListener('input', render);

/* Upload modal */
function openUploadModal(){ uploadOverlay.style.display='flex'; }
function closeUploadModal(){ uploadOverlay.style.display='none'; }
openUpload.addEventListener('click', openUploadModal);
gridUploadBtn.addEventListener('click', openUploadModal);
tableUploadBtn.addEventListener('click', openUploadModal);
closeUpload.addEventListener('click', closeUploadModal);
uploadOverlay.addEventListener('click',e=>{ if(e.target===uploadOverlay) closeUploadModal(); });

/* Pending previews */
function resetPending(){
  pendingFiles=[]; previewArea.innerHTML=''; fileInput.value='';
}
function addPreviewItem(file, dataURL){
  const div=document.createElement('div'); div.className='pthumb';
  div.innerHTML = dataURL
    ? `<img src="${dataURL}"><div class="ptitle" title="${file.name}">${esc(file.name)}</div>`
    : `<div class="pdfthumb">${file.type?.toUpperCase().includes('PDF')?'PDF':'FILE'}</div><div class="ptitle" title="${file.name}">${esc(file.name)}</div>`;
  previewArea.appendChild(div);
}
async function handleFiles(files){
  resetPending();
  pendingFiles=[...files];
  for (const f of pendingFiles){
    if (f.type.startsWith('image/')){
      const url=await new Promise(res=>{ const r=new FileReader(); r.onload=()=>res(r.result); r.readAsDataURL(f); });
      addPreviewItem(f, url);
    } else {
      addPreviewItem(f, null);
    }
  }
}

/* Drag & drop */
dropArea.addEventListener('dragover',e=>{ e.preventDefault(); dropArea.style.borderColor='var(--accent)'; });
dropArea.addEventListener('dragleave',()=>{ dropArea.style.borderColor='var(--border)'; });
dropArea.addEventListener('drop',e=>{
  e.preventDefault(); dropArea.style.borderColor='var(--border)';
  if (e.dataTransfer?.files?.length){ handleFiles(e.dataTransfer.files); }
});
fileInput.addEventListener('change',()=>{ if (fileInput.files?.length) handleFiles(fileInput.files); });

/* Upload */
uploadBtn.addEventListener('click', async ()=>{
  if (!pendingFiles.length){ showToast('Choose or drop at least one file', true); return; }
  const fd=new FormData();
  for (const f of pendingFiles) fd.append('files[]', f);
  fd.append('action','upload');
  fd.append('filenumber', filenumber);
  fd.append('doc_type', docType.value || '');
  fd.append('title', titleInput.value || '');

  try {
    const res=await fetch(location.pathname+'?filenumber='+encodeURIComponent(filenumber), {
      method:'POST', body:fd, credentials:'same-origin'
    });
    const data=await res.json();
    if (!data.ok) throw new Error(data.error||'Upload failed');

    // After upload, refresh list with the lightweight endpoint (optional, but handy)
    const r2=await fetch(location.pathname+'?action=list&filenumber='+encodeURIComponent(filenumber), {credentials:'same-origin'});
    const d2=await r2.json();
    if (d2.ok && Array.isArray(d2.documents)) allDocs=d2.documents;

    closeUploadModal();
    showToast('Upload complete');
    resetPending(); titleInput.value=''; docType.value='';
    render();
  } catch (e) {
    showToast(e.message||'Upload failed', true);
  }
});

/* ====== Initial paint ====== */
(function init(){
  // Grid is default
  gridView.classList.remove('hidden');
  tableView.classList.add('hidden');
  // Render from server-sent docs immediately
  render();
})();
</script>
</body>
</html>
