"use strict";
const fs = require("fs");
const path = require("path");

const iconsDir = path.resolve(__dirname, "svg");
const outFile = path.resolve(__dirname, "gallery.html");

if (!fs.existsSync(iconsDir)) {
  console.error(`SVG directory not found: ${iconsDir}`);
  process.exit(1);
}

const entries = fs.readdirSync(iconsDir, { withFileTypes: true })
  .filter(d => d.isFile() && d.name.toLowerCase().endsWith(".svg"))
  .map(d => ({ name: d.name, size: fs.statSync(path.join(iconsDir, d.name)).size }))
  .sort((a, b) => a.name.localeCompare(b.name, "zh", { sensitivity: "base", numeric: true }));

const empty = entries.filter(e => e.size === 0);
const nonEmpty = entries.filter(e => e.size > 0);

const escapeHtml = (s) => String(s)
  .replace(/&/g, "&amp;")
  .replace(/</g, "&lt;")
  .replace(/>/g, "&gt;")
  .replace(/\"/g, "&quot;")
  .replace(/'/g, "&#39;");

function renderCard(file, kind) {
  const display = file.name.replace(/\.svg$/i, "");
  const safe = escapeHtml(display);
  const dataName = display.toLowerCase();
  const src = "svg/" + encodeURIComponent(file.name);
  if (kind === 'empty') {
    return `\n      <div class="card empty" data-name="${escapeHtml(dataName)}">\n        <div class="preview placeholder"></div>\n        <div class="name" title="${safe}">${safe}</div>\n      </div>`;
  }
  return `\n      <div class="card" data-name="${escapeHtml(dataName)}">\n        <div class="preview"><img loading="lazy" src="${src}" alt="${safe}" onerror="this.closest('div.card').classList.add('error')"></div>\n        <div class="name" title="${safe}">${safe}</div>\n      </div>`;
}

const rowsNonEmpty = nonEmpty.map(f => renderCard(f, 'icon')).join("");
const rowsEmpty = empty.map(f => renderCard(f, 'empty')).join("");

const html = `<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>SVG 图标预览</title>
  <style>
    :root { --gap: 12px; --size: 64px; --border: #e5e7eb; --text: #111827; --muted: #6b7280; --error: #ef4444; --checker-a:#e5e7eb; --checker-b:#ffffff; }
    * { box-sizing: border-box; }
    body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, "Noto Sans", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; color: var(--text); }
    header { position: sticky; top: 0; background: #fff; border-bottom: 1px solid var(--border); padding: 14px 16px; display: flex; align-items: center; gap: 12px; z-index: 10; }
    h1 { margin: 0; font-size: 16px; font-weight: 600; }
    .search { flex: 1; }
    .search input { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; font-size: 14px; }
    .count { font-size: 12px; color: var(--muted); white-space: nowrap; }
    main { padding: 16px; }
    .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--gap); }
    .card { border: 1px solid var(--border); border-radius: 12px; padding: 12px; display: flex; flex-direction: column; align-items: center; gap: 10px; background: #fff; }
    .preview { width: var(--size); height: var(--size); border-radius: 10px; display: flex; align-items: center; justify-content: center; background: repeating-conic-gradient(var(--checker-a) 0 25%, var(--checker-b) 0 50%) 50% / 12px 12px; }
    .preview img { max-width: 100%; max-height: 100%; filter: drop-shadow(0 0 1px rgba(0,0,0,.45)) drop-shadow(0 0 2px rgba(0,0,0,.25)); }
    .name { text-align: center; font-size: 12px; color: var(--muted); width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .card.error { border-color: var(--error); }
    .card.error .name { color: var(--error); }
    .card.empty { border-color: #f59e0b; }
    .card.empty .preview { background: repeating-conic-gradient(#fef3c7 0 25%, #fff7ed 0 50%) 50% / 12px 12px; }
    footer { padding: 16px; color: var(--muted); text-align: center; font-size: 12px; }
    .toolbar { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 12px; }
    .size-input { width: 120px; }
    select, button, label.switch { border: 1px solid var(--border); background: #fff; padding: 6px 8px; border-radius: 6px; }
    label.switch { display: inline-flex; align-items: center; gap: 6px; }
  </style>
</head>
<body>
  <header>
    <h1>SVG 图标预览</h1>
    <div class="toolbar">
      <label>大小: <input class="size-input" type="range" min="24" max="160" value="64"></label>
      <label>背景: 
        <select id="bg">
          <option value="checker" selected>棋盘</option>
          <option value="white">白色</option>
          <option value="gray">浅灰</option>
          <option value="dark">深色</option>
        </select>
      </label>
      <label class="switch"><input id="toggleEmpty" type="checkbox"> 显示空文件(${empty.length})</label>
    </div>
    <div class="search"><input id="q" type="search" placeholder="搜索图标名称...（支持中英文）" autofocus></div>
    <div class="count"><span id="shown"></span>/<span id="total"></span></div>
  </header>
  <main>
    <div id="grid" class="grid">${rowsNonEmpty}${rowsEmpty}\n    </div>
  </main>
  <footer>共 ${nonEmpty.length} 个有效图标，${empty.length} 个空文件。默认隐藏空文件，你可在工具栏勾选显示。</footer>
  <script>
    const q = document.getElementById('q');
    const grid = document.getElementById('grid');
    const cards = Array.from(grid.querySelectorAll('.card'));
    const total = document.getElementById('total');
    const shown = document.getElementById('shown');
    const bg = document.getElementById('bg');
    const toggleEmpty = document.getElementById('toggleEmpty');
    total.textContent = String(cards.length);

    function applyFilter() {
      const term = q.value.trim().toLowerCase();
      let visible = 0;
      for (const el of cards) {
        const isEmpty = el.classList.contains('empty');
        const matches = !term || el.dataset.name.includes(term);
        const show = matches && (toggleEmpty.checked || !isEmpty);
        el.style.display = show ? '' : 'none';
        if (show) visible++;
      }
      shown.textContent = String(visible);
    }
    q.addEventListener('input', applyFilter);
    toggleEmpty.addEventListener('change', applyFilter);
    applyFilter();

    const sizeInput = document.querySelector('.size-input');
    function applySize() { document.documentElement.style.setProperty('--size', sizeInput.value + 'px'); }
    sizeInput.addEventListener('input', applySize);
    applySize();

    function applyBg() {
      const v = bg.value;
      if (v === 'checker') {
        document.documentElement.style.setProperty('--checker-a', '#e5e7eb');
        document.documentElement.style.setProperty('--checker-b', '#ffffff');
      } else if (v === 'white') {
        document.documentElement.style.setProperty('--checker-a', '#ffffff');
        document.documentElement.style.setProperty('--checker-b', '#ffffff');
      } else if (v === 'gray') {
        document.documentElement.style.setProperty('--checker-a', '#e5e7eb');
        document.documentElement.style.setProperty('--checker-b', '#e5e7eb');
      } else if (v === 'dark') {
        document.documentElement.style.setProperty('--checker-a', '#111827');
        document.documentElement.style.setProperty('--checker-b', '#1f2937');
      }
    }
    bg.addEventListener('change', applyBg);
    applyBg();
  </script>
</body>
</html>`;

const utf8NoBom = new (require('util').TextEncoder)();
fs.writeFileSync(outFile, html, { encoding: "utf8" });
console.log(`Generated: ${outFile} with ${nonEmpty.length} icons and ${empty.length} empty files`);