/* ============================================================
   流·Studio · Shell renderer V2.1
   渲染 sidebar / topbar / 网格背景装饰 / Toast / Modal helpers
   每个页面调用 Shell.render({ active, crumbs, balance, topActions })

   V2.1 变化:
   - sidebar 搜索 ⌘K → "Ctrl K" Inter Bold 平铺(无 kbd 边框)
   ============================================================ */

const NAV = [
  {
    id: 'dashboard', label: '工作台', href: 'index.html',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M3 12 12 3l9 9"/><path d="M5 10v10h14V10"/></svg>'
  },
  {
    id: 'products', label: '商品库', href: 'products.html', badge: '7',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="m3 7 9-4 9 4-9 4-9-4z"/><path d="m3 12 9 4 9-4M3 17l9 4 9-4"/></svg>'
  },
  {
    id: 'projects', label: '视频项目', href: 'projects.html', badge: '8',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="4" width="18" height="16"/><path d="M7 4v16M16 4v16M3 9h18M3 15h18"/></svg>'
  },
  {
    id: 'asset-factory', label: '图片生成', href: 'asset-factory.html',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l1.7 4.6L18 9l-4.3 1.4L12 15l-1.7-4.6L6 9l4.3-1.4L12 3z"/><path d="M19 16l.85 2.3L22 19l-2.15.7L19 22l-.85-2.3L16 19l2.15-.7L19 16z"/></svg>'
  },
  {
    id: 'library', label: '资产库', href: 'library.html',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="4" width="6" height="16"/><rect x="11" y="4" width="4" height="16"/><rect x="17" y="6" width="4" height="14"/></svg>'
  },
  {
    id: 'team', label: '团队', href: 'team.html',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="9" cy="8" r="3"/><circle cx="17" cy="9" r="2.5"/><path d="M3 19c0-3 2.7-5 6-5s6 2 6 5M14 19c.5-2.4 2.4-4 5-4 .8 0 1.5.2 2 .5"/></svg>'
  },
  {
    id: 'account', label: '消费', href: 'account.html',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18M16 14h2"/></svg>'
  },
  {
    id: 'settings', label: '设置', href: 'settings.html',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8 2 2 0 0 1-2.8 2.8 1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5 2 2 0 0 1-4 0 1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3 2 2 0 0 1-2.8-2.8 1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1 2 2 0 0 1 0-4 1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8 2 2 0 0 1 2.8-2.8 1.7 1.7 0 0 0 1.8.3 1.7 1.7 0 0 0 1-1.5 2 2 0 0 1 4 0 1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3 2 2 0 0 1 2.8 2.8 1.7 1.7 0 0 0-.3 1.8 1.7 1.7 0 0 0 1.5 1 2 2 0 0 1 0 4 1.7 1.7 0 0 0-1.5 1.1Z"/></svg>'
  }
];

window.Shell = {
  render({ active = '', crumbs = [], balance = '¥327.40', topActions = '' } = {}) {
    const navHtml = NAV.map(n => `
      <a href="${n.href}" class="${active === n.id ? 'active' : ''}">
        ${n.icon}
        <span>${n.label}</span>
        ${n.badge ? `<span class="pill-mini">${n.badge}</span>` : ''}
      </a>
    `).join('');

    const sidebar = `
      <aside class="sidebar">
        <div class="brand">
          <div class="flame"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2c1 3 4 5 4 9a4 4 0 0 1-4 4 4 4 0 0 1-4-4 5 5 0 0 1 1.5-3.5C10.5 6 11.5 4 12 2zm-1 13c0 2 1 3 1 5 1-1 3-2 3-5 0-1.5-1-2-2-3-1 1-2 2-2 3z"/></svg></div>
          <div><div class="name">流·Studio</div></div>
        </div>
        <div class="search-box" onclick="document.getElementById('global-search').focus()">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
          <input id="global-search" placeholder="搜索"/>
          <span class="kbd">Ctrl K</span>
        </div>
        <div class="nav-section">主要</div>
        <nav>${navHtml}</nav>
        <div class="aside-foot">
          <div class="user" onclick="Shell.toast('账户菜单', 'li@shop.com')">
            <div class="av">李</div>
            <div class="em">小李的店</div>
          </div>
        </div>
      </aside>
    `;

    const crumbHtml = crumbs.length ? `
      <div class="crumbs">
        ${crumbs.map((c, i) => {
          const last = i === crumbs.length - 1;
          const sep = i > 0 ? '<span class="sep">/</span>' : '';
          if (last) return `${sep}<span class="here">${c.label}</span>`;
          return `${sep}<a href="${c.href || '#'}">${c.label}</a>`;
        }).join('')}
      </div>
    ` : '';

    const topbar = `
      <header class="topbar">
        ${crumbHtml}
        <div class="right">
          <span class="balance-chip" onclick="location.href='account.html'">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="9"/><path d="M12 7v10M9 10h4a1.5 1.5 0 0 1 0 3h-3a1.5 1.5 0 0 0 0 3h4"/></svg>
            余额 <strong>${balance}</strong>
          </span>
          <button class="queue-chip" onclick="Shell.toast('任务队列', '3 个进行中')" hidden>
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
            任务队列
            <span class="count">3</span>
          </button>
          <button class="icon-btn" onclick="location.href='messages.html'" title="消息中心">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9M10 21a2 2 0 0 0 4 0"/></svg>
            <span class="count-noti">12</span>
          </button>
          <div class="topbar-avatar" onclick="Shell.toast('账户菜单', '李 · li@shop.com')" title="账户">
            <span>李</span>
          </div>
          ${topActions}
        </div>
      </header>
    `;

    const decorations = `
      <div class="grid-bg"></div>
      <span class="sq-mark" style="top:238px;left:478px"></span>
      <span class="sq-mark" style="top:478px;left:1198px"></span>
      <span class="sq-mark" style="bottom:300px;left:238px"></span>
      <span class="sq-mark" style="top:718px;right:240px"></span>
    `;

    const toastHtml = `
      <div class="toast" id="__toast">
        <div class="ic-t"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg></div>
        <div class="txt" id="__toast-txt">操作成功<span class="mono">[ 200 OK ]</span></div>
      </div>
    `;

    // ─── 全局 Lightbox · 任意页面可用 Shell._openLightbox(src, name) ──
    const lightboxHtml = `
      <div class="np-lightbox" id="np-lightbox" onclick="Shell._closeLightbox()">
        <button class="lb-x" type="button" onclick="event.stopPropagation();Shell._closeLightbox()">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
        </button>
        <img id="np-lightbox-img" alt="">
        <span class="lb-name" id="np-lightbox-name"></span>
      </div>
    `;

    // [DEPRECATED · 弹窗已废弃,创建商品直接进 product-create.html]
    const _deprecatedModalHtml = `
      <div class="modal-bg" id="new-product-bg" onclick="if(event.target===this)Shell.closeModal('new-product-bg')">
        <div class="modal new-product-modal">
          <span class="corner-tr"></span>
          <span class="corner-bl"></span>

          <div class="np-header">
            <div class="np-title-ic">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m3 7 9-4 9 4-9 4-9-4z"/><path d="m3 12 9 4 9-4M3 17l9 4 9-4"/></svg>
            </div>
            <h2>新建商品</h2>
            <span class="np-mode-pill">[ UPLOAD MODE ]</span>
            <button class="np-x" type="button" onclick="Shell.closeModal('new-product-bg')">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
            </button>
          </div>

          <div class="np-body">
            <div class="np-body-grid">

              <!-- 左栏: 图片 -->
              <div class="np-left">
                <!-- AI CTA: 独立全宽区域,放在 商品图册 上方 -->
                <a class="np-ai-cta primary" id="np-ai-cta" title="不上传也能用 AI 生成图">
                  <span class="ai-icon">
                    <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l1.5 4.5L18 8l-4.5 1.5L12 14l-1.5-4.5L6 8l4.5-1.5L12 2zM19 14l.9 2.7 2.6.8-2.6.8L19 21l-.9-2.7-2.6-.8 2.6-.8L19 14zM5 14l.7 2.1L7.8 17l-2.1.7L5 20l-.7-2.3-2.1-.7 2.1-.7L5 14z"/></svg>
                  </span>
                  <span class="ai-label" id="np-ai-label">没有图? 让 AI 帮我生成</span>
                  <span class="ai-arrow">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
                  </span>
                </a>

                <div class="field" style="margin-bottom: 12px;">
                  <label class="field-label">商品图册<span class="req">*</span></label>
                  <input type="file" id="np-file" accept="image/*" multiple hidden>

                  <!-- 图片案例 (静态示例) -->
                  <div class="np-section-h">
                    <span class="check-ic"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 8 7 12 13 4"/></svg></span>
                    图片案例
                  </div>
                  <div class="np-section-sub">上传您的商品的多角度白底图和使用图</div>
                  <div class="np-examples">
                    <div class="ex"><span>白底主图</span><span class="ex-badge"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M2 21h4V9H2v12zM23 10c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z"/></svg></span></div>
                    <div class="ex"><span>多角度</span><span class="ex-badge"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M2 21h4V9H2v12zM23 10c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z"/></svg></span></div>
                    <div class="ex"><span>细节图</span><span class="ex-badge"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M2 21h4V9H2v12zM23 10c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z"/></svg></span></div>
                    <div class="ex"><span>使用图</span><span class="ex-badge"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M2 21h4V9H2v12zM23 10c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z"/></svg></span></div>
                    <div class="ex"><span>包装图</span><span class="ex-badge"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M2 21h4V9H2v12zM23 10c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z"/></svg></span></div>
                  </div>

                  <!-- 我的上传 (动态 5 槽) -->
                  <div class="np-section-h">
                    我的上传
                    <span class="counter">( <span class="num" id="np-upload-count">0</span> / 5 )</span>
                  </div>
                  <div class="upload-grid" id="np-grid"></div>

                  <!-- Dropzone (放在 grid 之后, 满 5 张时禁用) -->
                  <div class="upload-zone" id="np-zone" style="margin-top: 10px;">
                    <span class="uz-ic">
                      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12"/></svg>
                    </span>
                    <span id="np-zone-text">点击或拖拽上传图片</span>
                    <span class="uz-hint">// 支持多选 · 最多 5 张 · JPG / PNG / WEBP</span>
                  </div>
                </div>
              </div>

              <!-- 右栏: 文案 -->
              <div class="np-right">
                <div class="field">
                  <label class="field-label">商品名称<span class="req">*</span></label>
                  <input class="input" id="np-name" placeholder="例: 透真玻尿酸补水面膜">
                </div>
                <div class="field">
                  <label class="field-label">品类</label>
                  <select class="select" id="np-cat">
                    <option>美妆个护</option>
                    <option>服饰内衣</option>
                    <option>食品饮料</option>
                    <option>家居家电</option>
                    <option>数码 3C</option>
                    <option>个护清洁</option>
                    <option>运动户外</option>
                    <option>母婴亲子</option>
                  </select>
                </div>
                <div class="field">
                  <label class="field-label">核心卖点<span class="req">*</span></label>
                  <ul class="bullet-list" id="np-bullets" data-bl>
                    <li class="bl-add"><span class="num">+</span><input class="bl-input" placeholder="添加新卖点 · 回车确认"></li>
                  </ul>
                </div>
                <div class="field" style="margin-bottom:0;">
                  <label class="field-label">目标人群</label>
                  <input class="input" id="np-target" placeholder="例: 22-32 岁女性、敏感肌、办公室通勤">
                </div>
              </div>

            </div>
          </div>

          <div class="np-footer">
            <span class="np-meta">// 上传模式 · <span class="accent">不消耗 token</span> · 一次性创建</span>
            <button class="btn" type="button" onclick="Shell.closeModal('new-product-bg')">取消</button>
            <button class="btn btn-primary" type="button" id="np-create" disabled style="opacity:.5;cursor:not-allowed;">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg>
              创建商品
            </button>
          </div>
        </div>
      </div>

      <!-- Lightbox · 缩略图全屏预览 -->
      <div class="np-lightbox" id="np-lightbox" onclick="Shell._closeLightbox()">
        <button class="lb-x" type="button" onclick="event.stopPropagation();Shell._closeLightbox()">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
        </button>
        <img id="np-lightbox-img" alt="">
        <span class="lb-name" id="np-lightbox-name"></span>
      </div>
    `;

    // 装订线 SVG 准星 · V2.1 签名元素(圆弧内凹的"+")
    const cornerSvg = `<path d="M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z" fill="currentColor"/>`;
    const cornerMarks = `
      <span class="corner-mark tl"><svg viewBox="0 0 22 21" fill="none">${cornerSvg}</svg></span>
      <span class="corner-mark tr"><svg viewBox="0 0 22 21" fill="none">${cornerSvg}</svg></span>
      <span class="corner-mark bl"><svg viewBox="0 0 22 21" fill="none">${cornerSvg}</svg></span>
      <span class="corner-mark br"><svg viewBox="0 0 22 21" fill="none">${cornerSvg}</svg></span>
    `;

    const app = document.createElement('div');
    app.className = 'app';
    app.innerHTML = sidebar + `<main>${decorations}${topbar}<div class="content" id="page-content">${cornerMarks}</div></main>`;

    const src = document.getElementById('page');
    document.body.prepend(app);
    if (src) {
      // 把页面 body 内容追加到 .content,保留 4 个 corner-mark SVG
      document.getElementById('page-content').insertAdjacentHTML('beforeend', src.innerHTML);
      src.remove();
    }
    document.body.insertAdjacentHTML('beforeend', toastHtml);
    document.body.insertAdjacentHTML('beforeend', lightboxHtml);

    document.addEventListener('keydown', e => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
        e.preventDefault();
        document.getElementById('global-search')?.focus();
      }
    });
  },

  // [DEPRECATED] 新建商品弹窗 · 已废弃,创建商品改为直跳 product-create.html
  _bindNewProductModal_DEPRECATED() {
    const modal = document.getElementById('new-product-bg');
    if (!modal) return;

    // 上传图册的内存状态 (供 collect 和 AI CTA 用)
    const uploads = []; // { id, dataUrl, name, type, size }

    // 收集表单状态(供 AI CTA 和创建按钮用)
    const collect = () => {
      const get = (id) => document.getElementById(id)?.value?.trim() || '';
      return {
        name: get('np-name'),
        cat: get('np-cat'),
        target: get('np-target'),
        bullets: [...document.querySelectorAll('#np-bullets .bl-item .bl-text')].map(el => el.textContent),
        uploadedCount: uploads.length,
        uploads: uploads.map(u => ({ name: u.name, type: u.type })),
      };
    };

    const MAX_UPLOADS = 5;

    // 创建按钮: 商品名 + 至少 1 张图
    const nameInput = document.getElementById('np-name');
    const createBtn = document.getElementById('np-create');
    const updateCreateBtn = () => {
      const nameOk = (nameInput.value || '').trim().length > 0;
      const uploadOk = uploads.length >= 1;
      const ok = nameOk && uploadOk;
      createBtn.disabled = !ok;
      createBtn.style.opacity = ok ? '' : '.5';
      createBtn.style.cursor = ok ? '' : 'not-allowed';
      // 提示用户缺什么
      if (!nameOk) createBtn.title = '请填写商品名称';
      else if (!uploadOk) createBtn.title = '请至少上传 1 张商品图';
      else createBtn.title = '';
    };
    nameInput.addEventListener('input', updateCreateBtn);
    createBtn.addEventListener('click', () => {
      if (createBtn.disabled) return;
      const s = collect();
      Shell.toast('商品已创建', `+ ${s.name}`);
      Shell.closeModal('new-product-bg');
    });

    // 核心卖点: bullet-list
    const list = document.getElementById('np-bullets');
    const addInput = list.querySelector('.bl-add .bl-input');
    const xSvg = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 4l8 8M12 4l-8 8"/></svg>';
    const renumber = () => {
      [...list.querySelectorAll('.bl-item')].forEach((li, i) => {
        li.querySelector('.num').textContent = i + 1;
      });
    };
    const bindX = (x) => {
      x.addEventListener('click', () => {
        const li = x.closest('li');
        li.style.transition = 'opacity .15s, transform .15s';
        li.style.opacity = 0;
        li.style.transform = 'translateX(-8px)';
        setTimeout(() => { li.remove(); renumber(); }, 150);
      });
    };
    const addBullet = (text) => {
      const t = (text || '').trim();
      if (!t) return;
      const li = document.createElement('li');
      li.className = 'bl-item';
      li.innerHTML = `<span class="num">0</span><span class="bl-text">${t.replace(/[<>&]/g, c => ({ '<':'&lt;','>':'&gt;','&':'&amp;' })[c])}</span><span class="bl-x" title="删除">${xSvg}</span>`;
      list.querySelector('.bl-add').before(li);
      bindX(li.querySelector('.bl-x'));
      renumber();
    };
    addInput?.addEventListener('keydown', e => {
      if (e.key === 'Enter') {
        e.preventDefault();
        addBullet(addInput.value);
        addInput.value = '';
      }
    });

    // 上传组件: 批量上传(MAX 5) + 5 固定槽 + 预览/删除 + AI CTA 联动
    const zone = document.getElementById('np-zone');
    const zoneText = document.getElementById('np-zone-text');
    const grid = document.getElementById('np-grid');
    const fileInput = document.getElementById('np-file');
    const aiCtaEl = document.getElementById('np-ai-cta');
    const aiLabel = document.getElementById('np-ai-label');
    const uploadCount = document.getElementById('np-upload-count');

    const syncAiCta = () => {
      if (uploads.length === 0) {
        aiCtaEl.classList.add('primary');
        aiLabel.textContent = '没有图? 让 AI 帮我生成';
      } else {
        aiCtaEl.classList.remove('primary');
        aiLabel.textContent = '用 AI 加工 / 生成模特上身图';
      }
    };

    const syncZone = () => {
      const full = uploads.length >= MAX_UPLOADS;
      zone.classList.toggle('full', full);
      zoneText.textContent = full ? `已达上限 (${MAX_UPLOADS} / ${MAX_UPLOADS})` : '点击或拖拽上传图片';
    };

    const syncCounter = () => {
      uploadCount.textContent = uploads.length;
    };

    const thumbXSvg = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 4l8 8M12 4l-8 8"/></svg>';
    const esc = (s) => s.replace(/[<>&"]/g, c => ({ '<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;' })[c]);

    const renderGrid = () => {
      const filledHtml = uploads.map(u => `
        <div class="up-thumb" data-id="${u.id}">
          <img src="${u.dataUrl}" alt="${esc(u.name)}">
          <button class="slot-x" type="button" title="删除">${thumbXSvg}</button>
        </div>
      `).join('');
      const emptyCount = MAX_UPLOADS - uploads.length;
      const emptyHtml = Array.from({ length: emptyCount }, () => `<div class="up-slot-empty" data-action="add">无预览</div>`).join('');
      grid.innerHTML = filledHtml + emptyHtml;

      // 已填充槽: 点击预览 + X 删除
      grid.querySelectorAll('.up-thumb').forEach(thumb => {
        const id = thumb.dataset.id;
        thumb.querySelector('.slot-x').addEventListener('click', (e) => {
          e.stopPropagation();
          const idx = uploads.findIndex(u => u.id === id);
          if (idx >= 0) {
            const removed = uploads.splice(idx, 1)[0];
            Shell.toast('已删除', removed.name);
            refreshAll();
          }
        });
        thumb.addEventListener('click', () => {
          const u = uploads.find(x => x.id === id);
          if (u) Shell._openLightbox(u.dataUrl, u.name);
        });
      });
      // 空槽: 点击触发上传
      grid.querySelectorAll('[data-action="add"]').forEach(slot => {
        slot.addEventListener('click', () => fileInput.click());
      });
    };

    const refreshAll = () => {
      renderGrid();
      syncAiCta();
      syncZone();
      syncCounter();
      updateCreateBtn();
    };

    const addFiles = (fileList) => {
      const remaining = MAX_UPLOADS - uploads.length;
      if (remaining <= 0) {
        Shell.toast('已达上传上限', `${MAX_UPLOADS} / ${MAX_UPLOADS} 张`);
        return;
      }
      const incoming = [...fileList].filter(f => f.type.startsWith('image/'));
      if (!incoming.length) return;
      const accepted = incoming.slice(0, remaining);
      const overflow = incoming.length - accepted.length;
      let added = 0;
      accepted.forEach(f => {
        const reader = new FileReader();
        reader.onload = (e) => {
          uploads.push({
            id: Date.now().toString(36) + Math.random().toString(36).slice(2, 6),
            dataUrl: e.target.result,
            name: f.name,
            type: f.type,
            size: f.size,
          });
          added++;
          if (added === accepted.length) {
            refreshAll();
            const msg = overflow > 0
              ? `+ ${added} 张 · 超出 ${overflow} 张已忽略`
              : `+ ${added} 张 · 共 ${uploads.length} / ${MAX_UPLOADS}`;
            Shell.toast('图片已上传', msg);
          }
        };
        reader.readAsDataURL(f);
      });
    };

    fileInput.addEventListener('change', (e) => {
      addFiles(e.target.files);
      e.target.value = '';
    });
    zone.addEventListener('click', () => {
      if (uploads.length < MAX_UPLOADS) fileInput.click();
    });
    zone.addEventListener('dragover', e => {
      e.preventDefault();
      if (uploads.length < MAX_UPLOADS) zone.style.borderColor = 'var(--heat)';
    });
    zone.addEventListener('dragleave', () => { zone.style.borderColor = ''; });
    zone.addEventListener('drop', e => {
      e.preventDefault();
      zone.style.borderColor = '';
      if (e.dataTransfer?.files?.length) addFiles(e.dataTransfer.files);
    });

    refreshAll();

    // AI CTA: 把已填表单 + 上传图册存到 sessionStorage,跳到 AI 工作台
    const aiCta = document.getElementById('np-ai-cta');
    aiCta.addEventListener('click', (e) => {
      e.preventDefault();
      const s = collect();
      sessionStorage.setItem('pending-product', JSON.stringify(s));
      Shell.toast('正在跳转 AI 工作台', `带入 ${s.uploadedCount} 张图`);
      setTimeout(() => { location.href = 'product-create.html'; }, 350);
    });

    updateCreateBtn();
  },

  _openLightbox(src, name) {
    const lb = document.getElementById('np-lightbox');
    const img = document.getElementById('np-lightbox-img');
    const nm = document.getElementById('np-lightbox-name');
    if (!lb || !img || lb.classList.contains('show')) return;
    img.src = src;
    if (nm) nm.textContent = name || '';
    lb.classList.add('show');
    this.lockScroll();
  },

  _closeLightbox() {
    const lb = document.getElementById('np-lightbox');
    if (!lb || !lb.classList.contains('show')) return;
    lb.classList.remove('show');
    this.unlockScroll();
  },

  toast(text, mono) {
    const t = document.getElementById('__toast');
    const txt = document.getElementById('__toast-txt');
    if (!t || !txt) return;
    txt.innerHTML = text + (mono ? `<span class="mono">[ ${mono} ]</span>` : '');
    t.classList.add('show');
    clearTimeout(this._tt);
    this._tt = setTimeout(() => t.classList.remove('show'), 2400);
  },

  /* ─── Body scroll lock (引用计数 · 多 overlay 叠加安全) ─── */
  _scrollLockCount: 0,
  _scrollLockSnapshot: null,
  lockScroll() {
    if (++this._scrollLockCount > 1) return;
    const docEl = document.documentElement;
    const sbw = window.innerWidth - docEl.clientWidth;
    this._scrollLockSnapshot = {
      bodyOverflow: document.body.style.overflow,
      bodyPaddingRight: document.body.style.paddingRight,
      htmlOverflow: docEl.style.overflow,
    };
    document.body.style.overflow = 'hidden';
    docEl.style.overflow = 'hidden';
    if (sbw > 0) document.body.style.paddingRight = sbw + 'px';
  },
  unlockScroll() {
    if (--this._scrollLockCount > 0) return;
    this._scrollLockCount = 0;
    const s = this._scrollLockSnapshot;
    if (s) {
      document.body.style.overflow = s.bodyOverflow;
      document.body.style.paddingRight = s.bodyPaddingRight;
      document.documentElement.style.overflow = s.htmlOverflow;
      this._scrollLockSnapshot = null;
    }
  },

  openModal(id) {
    const el = document.getElementById(id);
    if (!el || el.classList.contains('show')) return;
    // 把 modal-bg 挪到 body 直接子节点,绕开 .content 的层叠上下文(z-index:1)困住模态、让 topbar 漏出来的问题
    if (el.parentNode !== document.body) document.body.appendChild(el);
    el.classList.add('show');
    this.lockScroll();
    if (!this._modalEsc) {
      this._modalEsc = (e) => {
        if (e.key !== 'Escape') return;
        const open = document.querySelector('.modal-bg.show');
        if (open) this.closeModal(open.id);
      };
      document.addEventListener('keydown', this._modalEsc);
    }
  },
  closeModal(id) {
    const el = document.getElementById(id);
    if (!el || !el.classList.contains('show')) return;
    el.classList.remove('show');
    this.unlockScroll();
  },
  openDrawer(id) {
    const el = document.getElementById(id);
    const bg = document.getElementById(id + '-bg');
    if (!el || el.classList.contains('show')) return;
    el.classList.add('show');
    if (bg) bg.classList.add('show');
    this.lockScroll();
  },
  closeDrawer(id) {
    const el = document.getElementById(id);
    const bg = document.getElementById(id + '-bg');
    if (!el || !el.classList.contains('show')) return;
    el.classList.remove('show');
    if (bg) bg.classList.remove('show');
    this.unlockScroll();
  }
};
