<!DOCTYPE html>
<html lang="zh-TW">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>VvvebJS 網頁管理器</title>
  <meta name="description" content="使用 VvvebJS 管理您的靜態網站專案">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="/static/css/my-style.css">
</head>
<body>

<!-- ── 頂部導覽 ────────────────────────────────────────────────── -->
<header class="topbar">
  <div class="topbar-brand">
    <svg class="brand-icon" viewBox="0 0 32 32" fill="none">
      <rect width="32" height="32" rx="8" fill="url(#grad)"/>
      <path d="M8 10h16M8 16h10M8 22h13" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/>
      <defs>
        <linearGradient id="grad" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
          <stop stop-color="#6366f1"/>
          <stop offset="1" stop-color="#8b5cf6"/>
        </linearGradient>
      </defs>
    </svg>
    <span class="brand-name">VvvebJS <em>Manager</em></span>
  </div>
  <div class="topbar-actions">
    <span class="site-count" id="site-count">— 個專案</span>
    <button class="btn btn-primary" id="new-project-btn">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
        <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
      </svg>
      新增專案
    </button>
  </div>
</header>

<!-- ── 主內容 ─────────────────────────────────────────────────── -->
<main class="main-content">

  <!-- 搜尋列 -->
  <div class="search-bar-wrap">
    <div class="search-bar">
      <svg class="search-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
      </svg>
      <input type="text" id="search-input" placeholder="搜尋專案名稱…" autocomplete="off">
    </div>
  </div>

  <!-- 卡片網格 -->
  <div class="projects-grid" id="projects-grid">
    <!-- 由 JS 動態填入 -->
  </div>

  <!-- 空狀態 -->
  <div class="empty-state" id="empty-state" style="display:none">
    <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2">
      <rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/>
      <line x1="12" y1="17" x2="12" y2="21"/>
    </svg>
    <h2>尚無專案</h2>
    <p>點擊右上角「新增專案」開始建立您的第一個網站</p>
    <button class="btn btn-primary" id="empty-new-btn">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
        <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
      </svg>
      建立第一個專案
    </button>
  </div>

</main>

<!-- ── 新增專案 Modal ──────────────────────────────────────────── -->
<div class="modal-backdrop" id="create-modal-backdrop">
  <div class="modal-box" id="create-modal" role="dialog" aria-labelledby="create-modal-title" aria-modal="true">
    <div class="modal-header">
      <h2 id="create-modal-title">新增專案</h2>
      <button class="modal-close" id="create-modal-close" aria-label="關閉">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
        </svg>
      </button>
    </div>
    <div class="modal-body">
      <div class="form-group">
        <label for="new-project-name">專案名稱 <span class="required">*</span></label>
        <input type="text" id="new-project-name" placeholder="例如：我的公司網站" autocomplete="off">
        <span class="slug-preview" id="slug-preview"></span>
      </div>
      <div class="form-group">
        <label for="new-project-desc">描述（選填）</label>
        <textarea id="new-project-desc" rows="3" placeholder="簡短說明這個網站的用途…"></textarea>
      </div>
    </div>
    <div class="modal-footer">
      <button class="btn btn-ghost" id="create-cancel-btn">取消</button>
      <button class="btn btn-primary" id="create-confirm-btn">建立專案</button>
    </div>
  </div>
</div>

<!-- ── 設定 Offcanvas ─────────────────────────────────────────── -->
<div class="offcanvas-backdrop" id="settings-backdrop">
  <div class="offcanvas" id="settings-panel" role="dialog" aria-labelledby="settings-title">
    <div class="offcanvas-header">
      <h2 id="settings-title">專案設定</h2>
      <button class="modal-close" id="settings-close" aria-label="關閉">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
        </svg>
      </button>
    </div>
    <div class="offcanvas-body">
      <input type="hidden" id="settings-slug">
      <div class="form-group">
        <label for="settings-name">專案名稱</label>
        <input type="text" id="settings-name" placeholder="專案名稱">
      </div>
      <div class="form-group">
        <label for="settings-desc">描述</label>
        <textarea id="settings-desc" rows="4"></textarea>
      </div>
      <div class="form-group">
        <label>Slug（資料夾名稱）</label>
        <input type="text" id="settings-slug-display" disabled class="input-disabled">
        <p class="hint-text">Slug 為唯一識別碼，建立後無法更改</p>
      </div>

      <div class="divider"></div>

      <h3 class="section-label">頁面清單</h3>
      <ul class="pages-list" id="settings-pages-list">
        <li class="pages-loading">載入中…</li>
      </ul>
      <button class="btn btn-ghost btn-sm" id="add-page-btn" style="margin-top:0.75rem; width:100%">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
          <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
        </svg>
        新增頁面
      </button>

      <div class="divider"></div>

      <div class="danger-zone">
        <h3 class="section-label danger">危險操作</h3>
        <button class="btn btn-danger" id="delete-project-btn">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14H6L5 6"/>
            <path d="M10 11v6M14 11v6"/><path d="M9 6V4h6v2"/>
          </svg>
          刪除此專案
        </button>
        <p class="hint-text danger">此操作不可復原，將刪除所有頁面檔案</p>
      </div>
    </div>
    <div class="offcanvas-footer">
      <button class="btn btn-ghost" id="settings-cancel-btn">取消</button>
      <button class="btn btn-primary" id="settings-save-btn">儲存設定</button>
    </div>
  </div>
</div>

<!-- ── 刪除確認 Modal ──────────────────────────────────────────── -->
<div class="modal-backdrop" id="delete-modal-backdrop">
  <div class="modal-box modal-sm" role="dialog" aria-modal="true">
    <div class="modal-header">
      <h2>確認刪除</h2>
    </div>
    <div class="modal-body">
      <p>確定要刪除專案 <strong id="delete-project-name"></strong> 嗎？<br>
      此操作不可復原，所有頁面檔案都將被刪除。</p>
    </div>
    <div class="modal-footer">
      <button class="btn btn-ghost" id="delete-cancel-btn">取消</button>
      <button class="btn btn-danger" id="delete-confirm-btn">確認刪除</button>
    </div>
  </div>
</div>

<!-- ── Toast 通知 ─────────────────────────────────────────────── -->
<div class="toast-container" id="toast-container"></div>

<script>
// ── 狀態 ─────────────────────────────────────────────────────────
let allProjects = [];
let settingsCurrentSlug = '';
let deleteTargetSlug = '';

// ── API 輔助 ─────────────────────────────────────────────────────
async function apiFetch(url, opts = {}) {
  const res = await fetch(url, {
    headers: { 'Content-Type': 'application/json' },
    ...opts,
  });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data.error || `HTTP ${res.status}`);
  return data;
}

// ── Toast ─────────────────────────────────────────────────────────
function showToast(msg, type = 'success') {
  const tc = document.getElementById('toast-container');
  const t = document.createElement('div');
  t.className = `toast toast-${type}`;
  t.textContent = msg;
  tc.appendChild(t);
  requestAnimationFrame(() => t.classList.add('show'));
  setTimeout(() => {
    t.classList.remove('show');
    setTimeout(() => t.remove(), 400);
  }, 3000);
}

// ── Slug 預覽 ─────────────────────────────────────────────────────
function toSlug(s) {
  return s.toLowerCase()
    .replace(/[^\w\s-]/g, '')
    .replace(/[\s_-]+/g, '-')
    .replace(/^-+|-+$/g, '') || 'untitled';
}

// ── 渲染卡片 ─────────────────────────────────────────────────────
function renderProjects(projects) {
  const grid = document.getElementById('projects-grid');
  const empty = document.getElementById('empty-state');
  const count = document.getElementById('site-count');
  count.textContent = `${projects.length} 個專案`;

  if (projects.length === 0) {
    grid.innerHTML = '';
    empty.style.display = 'flex';
    return;
  }
  empty.style.display = 'none';

  grid.innerHTML = projects.map(p => {
    const mod = p.last_modified ? p.last_modified.slice(0, 10) : '—';
    const pages = p.page_count ?? 0;
    return `
    <div class="project-card" data-slug="${p.slug}">
      <div class="card-glow"></div>
      <div class="card-header-row">
        <div class="card-icon">
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
            <rect x="2" y="3" width="20" height="14" rx="2"/>
            <line x1="8" y1="21" x2="16" y2="21"/>
            <line x1="12" y1="17" x2="12" y2="21"/>
          </svg>
        </div>
        <div class="card-menu">
          <button class="icon-btn settings-btn" data-slug="${p.slug}" title="設定">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <circle cx="12" cy="12" r="3"/>
              <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
            </svg>
          </button>
        </div>
      </div>
      <div class="card-body">
        <h3 class="card-title">${escHtml(p.name)}</h3>
        <p class="card-desc">${escHtml(p.description || '—')}</p>
      </div>
      <div class="card-meta">
        <span class="meta-item">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
            <polyline points="14 2 14 8 20 8"/>
          </svg>
          ${pages} 頁
        </span>
        <span class="meta-item">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <rect x="3" y="4" width="18" height="18" rx="2" ry="2"/>
            <line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/>
            <line x1="3" y1="10" x2="21" y2="10"/>
          </svg>
          ${mod}
        </span>
      </div>
      <div class="card-actions">
        <a href="/dashboard/project/${encodeURIComponent(p.slug)}" class="btn btn-secondary btn-sm" id="dashboard-btn-${p.slug}" style="margin-right:0.5rem;">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
            <path d="M3 13h8V3H3v10z"/>
            <path d="M13 21h8V11h-8v10z"/>
            <path d="M3 21h8v-6H3v6z"/>
          </svg>
          專案儀表板
        </a>
        <a href="/editor/${p.slug}" class="btn btn-primary btn-sm" id="edit-btn-${p.slug}">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
            <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
            <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
          </svg>
          開啟編輯器
        </a>
      </div>
    </div>`;
  }).join('');

  // 綁定設定按鈕
  grid.querySelectorAll('.settings-btn').forEach(btn => {
    btn.addEventListener('click', e => {
      e.stopPropagation();
      openSettings(btn.dataset.slug);
    });
  });
}

function escHtml(s) {
  return String(s)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}

// ── 載入專案 ─────────────────────────────────────────────────────
async function loadProjects() {
  try {
    allProjects = await apiFetch('/api/projects');
    renderProjects(allProjects);
  } catch (e) {
    showToast('載入專案失敗：' + e.message, 'error');
  }
}

// ── 搜尋 ─────────────────────────────────────────────────────────
document.getElementById('search-input').addEventListener('input', function() {
  const q = this.value.toLowerCase();
  const filtered = allProjects.filter(p =>
    p.name.toLowerCase().includes(q) ||
    (p.description || '').toLowerCase().includes(q)
  );
  renderProjects(filtered);
});

// ── 新增專案 Modal ────────────────────────────────────────────────
function openCreateModal() {
  document.getElementById('new-project-name').value = '';
  document.getElementById('new-project-desc').value = '';
  document.getElementById('slug-preview').textContent = '';
  document.getElementById('create-modal-backdrop').classList.add('active');
  setTimeout(() => document.getElementById('new-project-name').focus(), 50);
}
function closeCreateModal() {
  document.getElementById('create-modal-backdrop').classList.remove('active');
}

document.getElementById('new-project-btn').addEventListener('click', openCreateModal);
document.getElementById('empty-new-btn').addEventListener('click', openCreateModal);
document.getElementById('create-modal-close').addEventListener('click', closeCreateModal);
document.getElementById('create-cancel-btn').addEventListener('click', closeCreateModal);
document.getElementById('create-modal-backdrop').addEventListener('click', e => {
  if (e.target.id === 'create-modal-backdrop') closeCreateModal();
});

document.getElementById('new-project-name').addEventListener('input', function() {
  const slug = toSlug(this.value);
  const preview = document.getElementById('slug-preview');
  preview.textContent = this.value ? `資料夾名稱：${slug}` : '';
});

document.getElementById('create-confirm-btn').addEventListener('click', async () => {
  const name = document.getElementById('new-project-name').value.trim();
  const desc = document.getElementById('new-project-desc').value.trim();
  if (!name) {
    showToast('請輸入專案名稱', 'error');
    document.getElementById('new-project-name').focus();
    return;
  }
  try {
    const btn = document.getElementById('create-confirm-btn');
    btn.disabled = true;
    btn.textContent = '建立中…';
    await apiFetch('/api/projects', {
      method: 'POST',
      body: JSON.stringify({ name, description: desc }),
    });
    closeCreateModal();
    showToast(`專案「${name}」建立成功！`);
    await loadProjects();
  } catch(e) {
    showToast('建立失敗：' + e.message, 'error');
  } finally {
    const btn = document.getElementById('create-confirm-btn');
    btn.disabled = false;
    btn.textContent = '建立專案';
  }
});

// ── 設定 Offcanvas ────────────────────────────────────────────────
async function openSettings(slug) {
  settingsCurrentSlug = slug;
  document.getElementById('settings-backdrop').classList.add('active');
  document.getElementById('settings-slug').value = slug;
  document.getElementById('settings-slug-display').value = slug;
  document.getElementById('settings-pages-list').innerHTML = '<li class="pages-loading">載入中…</li>';

  try {
    const proj = await apiFetch(`/api/projects/${slug}`);
    document.getElementById('settings-name').value = proj.name;
    document.getElementById('settings-desc').value = proj.description || '';

    const pages = proj.pages || [];
    const listEl = document.getElementById('settings-pages-list');
    if (pages.length === 0) {
      listEl.innerHTML = '<li class="no-pages">尚無頁面</li>';
    } else {
      listEl.innerHTML = pages.map(p => `
        <li class="page-item" style="justify-content: space-between; display: flex; align-items: center; margin-bottom: 0.4rem;">
          <div style="display: flex; align-items: center; gap: 0.5rem;">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="color: var(--accent);">
              <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
              <polyline points="14 2 14 8 20 8"/>
            </svg>
            <span>${escHtml(p)}</span>
          </div>
          <a href="/editor/${slug}?page=${escHtml(p)}" class="btn btn-primary btn-sm" style="padding: 0.2rem 0.6rem; font-size: 0.75rem; gap: 0.25rem; border-radius: var(--radius-sm);">
            <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
              <path d="M11 4H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
              <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
            </svg>
            編輯
          </a>
        </li>`).join('');
    }
  } catch(e) {
    showToast('載入設定失敗：' + e.message, 'error');
  }
}

function closeSettings() {
  document.getElementById('settings-backdrop').classList.remove('active');
}

document.getElementById('settings-close').addEventListener('click', closeSettings);
document.getElementById('settings-cancel-btn').addEventListener('click', closeSettings);
document.getElementById('settings-backdrop').addEventListener('click', e => {
  if (e.target.id === 'settings-backdrop') closeSettings();
});

document.getElementById('settings-save-btn').addEventListener('click', async () => {
  const name = document.getElementById('settings-name').value.trim();
  const desc = document.getElementById('settings-desc').value.trim();
  if (!name) {
    showToast('名稱不能為空', 'error');
    return;
  }
  try {
    await apiFetch(`/api/projects/${settingsCurrentSlug}`, {
      method: 'PUT',
      body: JSON.stringify({ name, description: desc }),
    });
    closeSettings();
    showToast('設定已儲存');
    await loadProjects();
  } catch(e) {
    showToast('儲存失敗：' + e.message, 'error');
  }
});

// 新增頁面
document.getElementById('add-page-btn').addEventListener('click', async () => {
  const name = prompt('請輸入新頁面名稱（例如：about）：');
  if (!name) return;
  try {
    await apiFetch(`/api/projects/${settingsCurrentSlug}/pages`, {
      method: 'POST',
      body: JSON.stringify({ name }),
    });
    showToast(`頁面「${name}」建立成功`);
    openSettings(settingsCurrentSlug);  // 重新整理面板
  } catch(e) {
    showToast('建立頁面失敗：' + e.message, 'error');
  }
});

// ── 刪除 ─────────────────────────────────────────────────────────
document.getElementById('delete-project-btn').addEventListener('click', () => {
  deleteTargetSlug = settingsCurrentSlug;
  const proj = allProjects.find(p => p.slug === settingsCurrentSlug);
  document.getElementById('delete-project-name').textContent = proj ? proj.name : deleteTargetSlug;
  document.getElementById('delete-modal-backdrop').classList.add('active');
});

document.getElementById('delete-cancel-btn').addEventListener('click', () => {
  document.getElementById('delete-modal-backdrop').classList.remove('active');
});

document.getElementById('delete-confirm-btn').addEventListener('click', async () => {
  try {
    await apiFetch(`/api/projects/${deleteTargetSlug}`, { method: 'DELETE' });
    document.getElementById('delete-modal-backdrop').classList.remove('active');
    closeSettings();
    showToast('專案已刪除');
    await loadProjects();
  } catch(e) {
    showToast('刪除失敗：' + e.message, 'error');
  }
});

document.getElementById('delete-modal-backdrop').addEventListener('click', e => {
  if (e.target.id === 'delete-modal-backdrop')
    document.getElementById('delete-modal-backdrop').classList.remove('active');
});

// ── Enter 鍵快速提交 ─────────────────────────────────────────────
document.getElementById('new-project-name').addEventListener('keydown', e => {
  if (e.key === 'Enter') document.getElementById('create-confirm-btn').click();
});

// ── 初始化 ────────────────────────────────────────────────────────
loadProjects();
</script>
</body>
</html>
