<?php
declare(strict_types=1);

require_once __DIR__ . '/_inc/ks_util.php';
require_once __DIR__ . '/_inc/ks_markdown.php';

$SITE_ROOT = realpath(__DIR__) ?: __DIR__;

// Discover
$lib = ks_discover_library($SITE_ROOT, maxDepth: 10, maxKeplerRoots: 50, maxMatchesPerBook: 200);
$projects = $lib['projects'];
$featured = $lib['featured'];

if (empty($projects)) {
  ks_abort(404, "No kepler* directories found in site root.");
}

$defaultRoot = ks_choose_default_project($projects, $featured);
if ($defaultRoot === null) {
  ks_abort(404, "No manuscripts found under kepler* directories.");
}

// Select project via pick (base64url of root folder name), else featured/default
$pick = isset($_GET['pick']) ? trim((string)$_GET['pick']) : '';
$selectedRoot = $defaultRoot;

if ($pick !== '') {
  $decoded = ks_base64url_decode($pick);
  $decoded = trim(str_replace('\\', '/', $decoded), '/');
  // We store just the root folder name in pick (e.g. "kepler_drift")
  if ($decoded !== '' && isset($projects[$decoded])) $selectedRoot = $decoded;
}

$project = $projects[$selectedRoot];

// Requested book
$requestedBook = isset($_GET['book']) ? (int)$_GET['book'] : 1;
if ($requestedBook < 1 || $requestedBook > 3) $requestedBook = 1;

$book = ks_choose_book($project, $requestedBook);
$entry = $project['best'][$book] ?? null;
if ($entry === null) {
  ks_abort(404, "Selected project has no readable Book{$book}-Full.md.");
}

$mdFile = $entry['file'];
$raw = file_get_contents($mdFile);
if ($raw === false) ks_abort(500, "Failed to read manuscript file.");
$raw = str_replace(["\r\n", "\r"], "\n", $raw);

// Render
$toc = [];
$contentHtml = ks_render_markdown($raw, $toc);

// Title from first H1
$pageTitle = "Book {$book} • Full Manuscript";
if (preg_match('/^\s*#\s+(.+)\s*$/m', $raw, $m)) $pageTitle = trim($m[1]);

$modified = @filemtime($mdFile) ?: time();
$modifiedIso = date('c', $modified);
$modifiedHuman = date('F j, Y • g:i A', $modified);

header('Content-Type: text/html; charset=utf-8');
?><!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title><?php echo ks_h($pageTitle); ?></title>
  <meta name="color-scheme" content="dark light">
  <style>
    :root{
      --bg:#0b0f14;
      --panel:rgba(255,255,255,.06);
      --panel2:rgba(255,255,255,.085);
      --text:rgba(255,255,255,.92);
      --muted:rgba(255,255,255,.66);
      --line:rgba(255,255,255,.14);
      --accent:#ffd27a;
      --accent2:#9be7ff;
      --shadow:0 22px 70px rgba(0,0,0,.50);
      --radius:20px;
      --mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
      --serif:ui-serif,Georgia,"Times New Roman",Times,serif;
      --sans:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,"Apple Color Emoji","Segoe UI Emoji";
    }
    @media (prefers-color-scheme: light){
      :root{
        --bg:#f6f7fb;
        --panel:rgba(20,26,33,.06);
        --panel2:rgba(20,26,33,.085);
        --text:rgba(10,14,20,.92);
        --muted:rgba(10,14,20,.62);
        --line:rgba(10,14,20,.12);
        --shadow:0 22px 70px rgba(0,0,0,.13);
      }
    }
    *{box-sizing:border-box}
    body{
      margin:0; font-family:var(--sans); color:var(--text); line-height:1.7;
      background:
        radial-gradient(1200px 800px at 15% -10%, rgba(255,210,122,.18), transparent 60%),
        radial-gradient(900px 600px at 90% 10%, rgba(155,231,255,.14), transparent 55%),
        radial-gradient(800px 700px at 45% 120%, rgba(255,255,255,.10), transparent 60%),
        var(--bg);
    }

    .wrap{
      display:grid;
      grid-template-columns: 340px minmax(0, 1fr);
      gap: 16px;
      max-width: 1260px;
      margin: 16px auto;
      padding: 0 16px 28px;
    }
    @media (max-width: 980px){ .wrap{grid-template-columns:1fr;} }

    .card{
      background: linear-gradient(180deg, var(--panel2), var(--panel));
      border: 1px solid var(--line);
      border-radius: var(--radius);
      box-shadow: var(--shadow);
      overflow:hidden;
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
    }

    header.hero{
      padding: 16px 16px 12px;
      border-bottom: 1px solid var(--line);
      display:flex;
      align-items:flex-start;
      justify-content:space-between;
      gap: 12px;
    }
    .hero h1{ margin:0; font-size: 16px; font-weight: 900; letter-spacing:.2px; }
    .meta{ margin-top: 4px; font-size: 12px; color: var(--muted); }

    .controls{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; justify-content:flex-end; }
    .chip,.btn{
      border:1px solid var(--line);
      background: rgba(255,255,255,.06);
      color: var(--text);
      border-radius: 999px;
      padding: 8px 10px;
      font-size: 12px;
      text-decoration:none;
      display:inline-flex;
      align-items:center;
      gap: 6px;
      user-select:none;
      cursor:pointer;
      transition: transform .08s ease, background .2s ease;
    }
    .chip:hover,.btn:hover{ background: rgba(255,255,255,.10); }
    .chip:active,.btn:active{ transform: scale(.98); }
    .chip.active{
      border-color: rgba(255,210,122,.35);
      background: rgba(255,210,122,.14);
    }
    .search{
      border:1px solid var(--line);
      background: rgba(255,255,255,.06);
      border-radius: 999px;
      padding: 8px 12px;
      font-size: 12px;
      color: var(--text);
      width: 180px;
      outline: none;
    }
    .search::placeholder{ color: var(--muted); }
    @media (max-width:520px){
      header.hero{ flex-direction: column; align-items: stretch; }
      .controls{ justify-content:flex-start; }
      .search{ width:100%; }
    }

    .tocWrap{ position: sticky; top: 16px; align-self: start; max-height: calc(100vh - 32px); overflow:auto; }
    @media (max-width:980px){ .tocWrap{ position: static; max-height:none; } }

    nav.toc{ padding: 14px; }
    .toc h2{
      margin: 0 0 10px;
      font-size: 12px;
      text-transform: uppercase;
      letter-spacing: .25px;
      color: var(--muted);
    }
    .toc a{
      display:block;
      padding: 8px 10px;
      margin: 4px 0;
      border-radius: 12px;
      text-decoration:none;
      color: var(--text);
      border:1px solid transparent;
    }
    .toc a:hover{ background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.12); }
    .toc .lvl3{ padding-left: 18px; opacity:.95; }
    .toc .lvl4{ padding-left: 28px; opacity:.9; font-size: 12px; }

    .pillpath{
      font-family: var(--mono);
      font-size: 12px;
      padding: 3px 8px;
      border-radius: 999px;
      border: 1px solid var(--line);
      background: rgba(255,255,255,.06);
      color: var(--muted);
      display:inline-flex;
      max-width: 100%;
      overflow:hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    main.reader{ padding: 18px 22px 22px; }
    @media (max-width:520px){ main.reader{ padding: 16px 16px 18px; } }

    main.reader h1, main.reader h2, main.reader h3, main.reader h4, main.reader h5, main.reader h6{
      margin: 26px 0 10px;
      line-height: 1.2;
      scroll-margin-top: 16px;
    }
    main.reader h1{ font-size: 32px; }
    main.reader h2{ font-size: 24px; border-top: 1px solid var(--line); padding-top: 18px; }
    main.reader h3{ font-size: 20px; }
    main.reader p{
      margin: 12px 0;
      font-family: var(--serif);
      font-size: 18px;
      letter-spacing: .1px;
    }
    main.reader strong{ color: var(--accent); font-weight: 850; }
    main.reader code{
      font-family: var(--mono);
      font-size: .92em;
      padding: 2px 6px;
      border-radius: 8px;
      border: 1px solid var(--line);
      background: rgba(255,255,255,.06);
    }
    main.reader pre{
      margin: 14px 0;
      padding: 14px;
      border-radius: 14px;
      border: 1px solid var(--line);
      background: rgba(0,0,0,.22);
      overflow:auto;
    }
    main.reader pre code{ border:none; background:transparent; padding:0; font-size: 13px; line-height: 1.5; }
    main.reader blockquote{
      margin: 16px 0;
      padding: 10px 14px;
      border-left: 3px solid var(--accent2);
      background: rgba(255,255,255,.06);
      border-radius: 14px;
      border: 1px solid rgba(255,255,255,.10);
    }
    main.reader blockquote p{ margin: 8px 0; font-size: 17px; color: var(--muted); font-family: var(--sans); }
    hr.scene-break{
      border:none; height:1px;
      background: linear-gradient(90deg, transparent, var(--line), transparent);
      margin: 22px 0;
      position: relative;
    }
    hr.scene-break::after{
      content:"✦";
      position:absolute;
      left:50%;
      transform: translateX(-50%);
      top: -12px;
      font-size: 14px;
      color: var(--accent2);
      background: var(--bg);
      padding: 0 10px;
    }
    mark{
      background: rgba(255,210,122,.28);
      color: inherit;
      padding: 0 .15em;
      border-radius: .25em;
      border: 1px solid rgba(255,210,122,.25);
    }
  </style>
</head>
<body>

  <div class="wrap">
    <aside class="card tocWrap">
      <header class="hero">
        <div>
          <h1>Library</h1>
          <div class="meta">Auto-discovered under <code>kepler*</code></div>
        </div>
      </header>

      <nav class="toc">
        <h2>Projects</h2>
        <?php foreach ($projects as $root => $p): ?>
          <?php
            $active = ($root === $selectedRoot);
            $pickVal = ks_base64url_encode($root);
            $q = http_build_query(['pick' => $pickVal, 'book' => $book]);
          ?>
          <a class="chip <?php echo $active ? 'active' : ''; ?>" href="read.php?<?php echo ks_h($q); ?>">
            <?php echo ks_h($root); ?>
            <?php
              $tags = [];
              for ($b=1;$b<=3;$b++) if ($p['best'][$b]) $tags[] = "B{$b}";
              echo '<span style="opacity:.7;">(' . ks_h(implode(',', $tags ?: ['none'])) . ')</span>';
            ?>
          </a>
        <?php endforeach; ?>

        <h2 style="margin-top:12px;">This file</h2>
        <div class="meta">
          <div class="pillpath"><?php echo ks_h($entry['dir']); ?></div>
          <div style="margin-top:6px;">
            Updated:
            <time datetime="<?php echo ks_h($modifiedIso); ?>"><?php echo ks_h($modifiedHuman); ?></time>
          </div>
        </div>

        <h2 style="margin-top:12px;">Contents</h2>
        <?php if (!$toc): ?>
          <div class="meta">No headings found (add ## / ### to your Markdown).</div>
        <?php else: ?>
          <?php foreach ($toc as $item): ?>
            <?php
              $lvl = (int)$item['level'];
              $cls = $lvl === 3 ? 'lvl3' : ($lvl === 4 ? 'lvl4' : '');
            ?>
            <a class="<?php echo $cls; ?>" href="#<?php echo ks_h($item['id']); ?>">
              <?php echo ks_h($item['title']); ?>
            </a>
          <?php endforeach; ?>
        <?php endif; ?>
      </nav>
    </aside>

    <section class="card">
      <header class="hero">
        <div>
          <h1><?php echo ks_h($pageTitle); ?></h1>
          <div class="meta">
            <span class="pillpath"><?php echo ks_h($selectedRoot); ?></span>
          </div>
        </div>

        <div class="controls">
          <a class="chip" href="index.php">Home</a>

          <?php
            $pickVal = ks_base64url_encode($selectedRoot);
            for ($b=1;$b<=3;$b++):
              $exists = ($project['best'][$b] !== null);
              $q = http_build_query(['pick'=>$pickVal,'book'=>$b]);
          ?>
            <a class="chip <?php echo $b===$book?'active':''; ?>"
               href="read.php?<?php echo ks_h($q); ?>"
               style="<?php echo $exists ? '' : 'opacity:.45; pointer-events:none;'; ?>">
              Book <?php echo $b; ?>
            </a>
          <?php endfor; ?>

          <input class="search" id="search" type="search" placeholder="Find text…" autocomplete="off">
          <button class="btn" id="btnTop" type="button">Top</button>
          <button class="btn" id="btnPrint" type="button">Print</button>
        </div>
      </header>

      <main class="reader" id="reader">
        <?php echo $contentHtml; ?>
      </main>
    </section>
  </div>

  <script>
    (function(){
      const reader = document.getElementById('reader');
      const search = document.getElementById('search');
      const btnTop = document.getElementById('btnTop');
      const btnPrint = document.getElementById('btnPrint');

      btnTop?.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
      btnPrint?.addEventListener('click', () => window.print());

      // Search highlighting
      function clearMarks(){
        reader.querySelectorAll('mark').forEach(m => m.replaceWith(document.createTextNode(m.textContent)));
      }
      function highlight(term){
        if (!term) return;
        const lower = term.toLowerCase();
        const walk = document.createTreeWalker(reader, NodeFilter.SHOW_TEXT, {
          acceptNode: (node) => {
            if (!node.nodeValue) return NodeFilter.FILTER_REJECT;
            const p = node.parentElement;
            if (!p) return NodeFilter.FILTER_REJECT;
            if (p.closest('script, style, pre, code')) return NodeFilter.FILTER_REJECT;
            return node.nodeValue.toLowerCase().includes(lower) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
          }
        });

        const nodes = [];
        while (walk.nextNode()) nodes.push(walk.currentNode);

        nodes.forEach(node => {
          const val = node.nodeValue;
          const idx = val.toLowerCase().indexOf(lower);
          if (idx === -1) return;

          const before = document.createTextNode(val.slice(0, idx));
          const hit = document.createElement('mark');
          hit.textContent = val.slice(idx, idx + term.length);
          const after = document.createTextNode(val.slice(idx + term.length));

          const frag = document.createDocumentFragment();
          frag.append(before, hit, after);
          node.parentNode.replaceChild(frag, node);
        });

        const first = reader.querySelector('mark');
        if (first) first.scrollIntoView({ behavior: 'smooth', block: 'center' });
      }

      let t = null;
      search?.addEventListener('input', () => {
        clearTimeout(t);
        t = setTimeout(() => {
          clearMarks();
          const term = (search.value || '').trim();
          if (term.length >= 2) highlight(term);
        }, 120);
      });

      // Smooth anchor scroll
      document.querySelectorAll('a[href^="#"]').forEach(a => {
        a.addEventListener('click', (e) => {
          const id = a.getAttribute('href').slice(1);
          const el = document.getElementById(id);
          if (!el) return;
          e.preventDefault();
          el.scrollIntoView({ behavior: 'smooth', block: 'start' });
          history.replaceState(null, '', '#' + id);
        });
      });
    })();
  </script>
</body>
</html>
