/* ============================================================
   新建商品 · 共享 Drawer 模块
   ----------------------------------------------------------
   在任意页面只需 <script src="assets/new-product-drawer.js"> 引入,
   然后调用 NewProductDrawer.open({ onSave: fn }) 即可在当前页之上
   弹出右侧 Drawer。点击遮罩 / X / 取消 / ESC 关闭后,用户停在原页面。

   提供:
     window.NewProductDrawer.open(opts?)
     window.NewProductDrawer.close()
   opts 字段:
     onSave(product)  — 保存时回调,product = { id, name, cat, target,
                        points: string[], images: { id, dataUrl, name }[] }
   ============================================================ */
(function () {
  'use strict';
  if (window.NewProductDrawer) return; // idempotent

  const DRAWER_ID    = 'npd-drawer';
  const DRAWER_BG_ID = 'npd-drawer-bg';

  /* ---------- 注入样式(独立 namespace 以免与 products.html 冲突) ---------- */

  const CSS = `
  /* drawer base (相同尺寸/动画) */
  #${DRAWER_BG_ID} {
    position: fixed; inset: 0;
    background: rgba(21, 20, 15, .32);
    display: none; z-index: 1100;
  }
  #${DRAWER_BG_ID}.show { display: block; }
  #${DRAWER_ID} {
    position: fixed; right: 0; top: 0; bottom: 0;
    width: 820px; max-width: 100vw;
    background: var(--surface);
    border-left: 1px solid var(--border-faint);
    z-index: 1101;
    transform: translateX(100%);
    transition: transform .25s cubic-bezier(.32, .72, 0, 1);
    display: flex; flex-direction: column;
    box-shadow: -4px 0 24px rgba(21, 20, 15, .04);
  }
  #${DRAWER_ID}.show { transform: translateX(0); }
  #${DRAWER_ID} .drawer-h {
    padding: 20px 24px;
    border-bottom: 1px solid var(--border-faint);
    display: flex; align-items: center;
  }
  #${DRAWER_ID} .drawer-h h3 { font-size: 16px; font-weight: 600; color: var(--accent-black); }
  #${DRAWER_ID} .drawer-h .x {
    margin-left: auto; width: 32px; height: 32px;
    border-radius: var(--r-md);
    display: grid; place-items: center;
    color: var(--black-alpha-56); cursor: pointer;
    background: transparent; border: 0;
    transition: background var(--t-base);
  }
  #${DRAWER_ID} .drawer-h .x:hover { background: var(--black-alpha-4); color: var(--accent-black); }
  #${DRAWER_ID} .drawer-b { padding: 24px 28px; overflow-y: auto; flex: 1; overscroll-behavior: contain; }
  #${DRAWER_ID} .drawer-f {
    padding: 14px 24px;
    border-top: 1px solid var(--border-faint);
    display: flex; gap: 10px; align-items: center;
    background: var(--surface);
  }
  #${DRAWER_ID} .drawer-f .btn-guide {
    margin-right: auto;
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 13px; color: var(--black-alpha-56);
    background: transparent; border: 0; cursor: pointer;
    padding: 8px 10px; border-radius: var(--r-md);
    font-family: inherit;
    transition: background var(--t-base), color var(--t-base);
  }
  #${DRAWER_ID} .drawer-f .btn-guide:hover { color: var(--accent-black); background: var(--black-alpha-4); }
  #${DRAWER_ID} .drawer-f .btn-guide svg { width: 14px; height: 14px; }

  /* form-card */
  #${DRAWER_ID} .form-h {
    font-size: 15px; font-weight: 600; color: var(--accent-black);
    margin-bottom: 18px; padding-bottom: 12px;
    border-bottom: 1px solid var(--border-faint);
  }
  #${DRAWER_ID} .field { margin-bottom: 16px; }
  #${DRAWER_ID} .field:last-child { margin-bottom: 0; }
  #${DRAWER_ID} .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 16px; }
  #${DRAWER_ID} .field-label {
    display: block; font-size: 13px; font-weight: 500;
    color: var(--accent-black); margin-bottom: 6px;
  }
  #${DRAWER_ID} .field-label .req { color: var(--heat); margin-left: 2px; }
  #${DRAWER_ID} .field-label .opt {
    color: var(--black-alpha-48); font-weight: 400; font-size: 12px; margin-left: 6px;
  }
  #${DRAWER_ID} .input,
  #${DRAWER_ID} .select {
    width: 100%; height: 38px;
    background: var(--background-lighter);
    border: 1px solid var(--black-alpha-12);
    border-radius: var(--r-md);
    padding: 0 14px;
    font-size: 13.5px; color: var(--accent-black);
    outline: none; font-family: inherit;
    transition: border-color var(--t-base);
  }
  #${DRAWER_ID} .input:focus,
  #${DRAWER_ID} .select:focus {
    border-color: var(--heat-40);
    box-shadow: inset 0 0 0 1px var(--heat-40);
  }

  /* upload */
  #${DRAWER_ID} .pf-upload-row {
    display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 16px; align-items: stretch;
  }
  #${DRAWER_ID} .pf-upload-zone {
    border: 1.5px dashed var(--black-alpha-24);
    border-radius: var(--r-md);
    padding: 28px 20px;
    background: var(--background-lighter);
    cursor: pointer; text-align: center;
    transition: border-color var(--t-base), background var(--t-base);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 180px;
  }
  #${DRAWER_ID} .pf-upload-zone:hover { border-color: var(--heat); background: var(--heat-8); }
  #${DRAWER_ID} .pf-upload-zone .uz-ic {
    width: 44px; height: 44px;
    margin: 0 auto 10px;
    background: var(--surface);
    border: 1px solid var(--heat-20);
    border-radius: var(--r-md);
    color: var(--heat);
    display: grid; place-items: center;
  }
  #${DRAWER_ID} .pf-upload-zone .uz-ic svg { width: 20px; height: 20px; }
  #${DRAWER_ID} .pf-upload-zone .uz-t { font-size: 14px; color: var(--accent-black); font-weight: 500; }
  #${DRAWER_ID} .pf-upload-zone .uz-t strong { color: var(--heat); font-weight: 600; }
  #${DRAWER_ID} .pf-upload-zone .uz-d {
    margin-top: 8px;
    font-family: var(--font-mono); font-size: 11.5px;
    color: var(--black-alpha-48); letter-spacing: .02em;
  }
  #${DRAWER_ID} .pf-example {
    background: var(--background-lighter);
    border: 1px solid var(--border-faint);
    border-radius: var(--r-md);
    padding: 16px;
    display: flex; flex-direction: column; gap: 10px;
  }
  #${DRAWER_ID} .pf-example .ex-h { font-size: 13px; font-weight: 600; color: var(--accent-black); }
  #${DRAWER_ID} .pf-example .ex-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
  #${DRAWER_ID} .pf-example .ex-grid .ex-thumb {
    aspect-ratio: 1;
    background: var(--surface);
    border: 1px solid var(--border-faint);
    border-radius: var(--r-sm);
    overflow: hidden; position: relative;
    display: grid; place-items: center;
    color: var(--black-alpha-32);
  }
  #${DRAWER_ID} .pf-example .ex-grid .ex-thumb svg { width: 22px; height: 22px; }
  #${DRAWER_ID} .pf-example .ex-grid .ex-thumb::after {
    content: ''; position: absolute; inset: 0;
    background: repeating-linear-gradient(135deg, transparent 0 6px, rgba(0,0,0,.03) 6px 7px);
    pointer-events: none;
  }
  #${DRAWER_ID} .pf-example .ex-d { font-size: 12px; color: var(--black-alpha-56); line-height: 1.5; }
  #${DRAWER_ID} .pf-grid {
    display: grid; grid-template-columns: repeat(5, 1fr);
    gap: 8px; margin-top: 12px;
  }
  #${DRAWER_ID} .pf-grid:empty { display: none; }
  #${DRAWER_ID} .pf-thumb {
    aspect-ratio: 1;
    background: var(--background-lighter);
    border: 1px solid var(--border-faint);
    border-radius: var(--r-md);
    position: relative; overflow: hidden; cursor: pointer;
  }
  #${DRAWER_ID} .pf-thumb img { width: 100%; height: 100%; object-fit: cover; }
  #${DRAWER_ID} .pf-thumb .pf-x {
    position: absolute; top: 4px; right: 4px;
    width: 22px; height: 22px;
    background: rgba(0,0,0,.7); color: var(--accent-white);
    border: 0; border-radius: 50%; cursor: pointer;
    display: grid; place-items: center;
    opacity: 0; transition: opacity var(--t-base);
  }
  #${DRAWER_ID} .pf-thumb:hover .pf-x { opacity: 1; }
  #${DRAWER_ID} .pf-thumb .pf-x svg { width: 11px; height: 11px; }

  /* bullet-list */
  #${DRAWER_ID} .bullet-list { list-style: none; padding: 0; margin: 0; }
  #${DRAWER_ID} .bullet-list .bl-item,
  #${DRAWER_ID} .bullet-list .bl-add {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px;
    background: var(--background-lighter);
    border: 1px solid var(--border-faint);
    border-radius: var(--r-md);
    margin-bottom: 6px;
    font-size: 13.5px;
  }
  #${DRAWER_ID} .bullet-list .bl-add { background: transparent; border-style: dashed; }
  #${DRAWER_ID} .bullet-list .bl-add-row {
    margin: 8px 0 0;
    display: none;
    padding: 0;
    background: transparent;
    border: 0;
  }
  #${DRAWER_ID} .bullet-list .bl-add-row.show { display: flex; justify-content: flex-start; }
  #${DRAWER_ID} .bl-add-btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 14px;
    background: var(--heat); color: #fff;
    border: 0; border-radius: var(--r-md);
    font-size: 13px; font-weight: 600;
    cursor: pointer; font-family: inherit;
    transition: filter var(--t-base);
  }
  #${DRAWER_ID} .bl-add-btn:hover { filter: brightness(.94); }
  #${DRAWER_ID} .bl-add-btn svg { width: 12px; height: 12px; }
  #${DRAWER_ID} .bullet-list .num {
    width: 22px; height: 22px;
    background: var(--surface);
    border: 1px solid var(--border-faint);
    border-radius: var(--r-sm);
    font-family: var(--font-mono);
    font-size: 11px; color: var(--heat); font-weight: 700;
    display: grid; place-items: center; flex-shrink: 0;
  }
  #${DRAWER_ID} .bullet-list .bl-text { flex: 1; color: var(--accent-black); }
  #${DRAWER_ID} .bullet-list .bl-input {
    flex: 1; background: transparent; border: 0; outline: none;
    font-size: 13.5px; color: var(--accent-black); font-family: inherit;
  }
  #${DRAWER_ID} .bullet-list .bl-x {
    width: 22px; height: 22px;
    color: var(--black-alpha-48);
    cursor: pointer; display: grid; place-items: center;
    border-radius: var(--r-sm);
    transition: color var(--t-base), background var(--t-base);
  }
  #${DRAWER_ID} .bullet-list .bl-x:hover { color: var(--accent-crimson); background: var(--crimson-bg); }
  #${DRAWER_ID} .bullet-list .bl-x svg { width: 11px; height: 11px; }

  @media (max-width: 900px) {
    #${DRAWER_ID} .pf-upload-row { grid-template-columns: 1fr; }
  }

  /* 放弃填写 · 确认弹窗 · 覆盖在 drawer 上 */
  #npd-confirm-bg {
    position: fixed; inset: 0; z-index: 1200;
    background: rgba(21, 20, 15, .42);
    display: grid; place-items: center;
    padding: 16px;
  }
  #npd-confirm-bg[hidden] { display: none; }
  .npd-confirm-modal {
    width: min(420px, 92vw);
    background: var(--surface);
    border: 1px solid var(--border-faint);
    border-radius: var(--r-md);
    box-shadow: 0 16px 48px rgba(21, 20, 15, .18);
    overflow: hidden;
  }
  .npd-confirm-modal .dh {
    display: flex; align-items: center; gap: 12px;
    padding: 18px 20px 14px;
  }
  .npd-confirm-modal .dh .ic {
    width: 36px; height: 36px; flex-shrink: 0;
    border-radius: var(--r-md);
    background: rgba(180, 30, 30, .08); color: var(--accent-crimson);
    display: grid; place-items: center;
  }
  .npd-confirm-modal .dh .ic svg { width: 18px; height: 18px; }
  .npd-confirm-modal .dh .ti { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .npd-confirm-modal .dh .ti strong { font-size: 14.5px; color: var(--accent-black); font-weight: 600; }
  .npd-confirm-modal .dh .ti .mono { font-family: var(--font-mono); font-size: 11.5px; color: var(--black-alpha-48); letter-spacing: .02em; line-height: 1.5; }
  .npd-confirm-modal .df {
    display: flex; gap: 8px;
    padding: 0 20px 18px;
    justify-content: flex-end;
  }
  .npd-confirm-modal .df button {
    height: 32px; padding: 0 14px;
    background: var(--surface);
    border: 1px solid var(--border-faint);
    border-radius: var(--r-md);
    font-size: 12.5px; color: var(--accent-black);
    font-family: inherit; cursor: pointer;
    transition: border-color var(--t-base), background var(--t-base), color var(--t-base);
  }
  .npd-confirm-modal .df button:hover { border-color: var(--heat-20); background: var(--heat-12); color: var(--heat); }
  .npd-confirm-modal .df button.danger { color: var(--accent-crimson); }
  .npd-confirm-modal .df button.danger:hover {
    background: rgba(180, 30, 30, .08);
    border-color: rgba(180, 30, 30, .35);
    color: var(--accent-crimson);
  }
  `;

  const HTML = `
  <div id="${DRAWER_BG_ID}"></div>
  <aside id="${DRAWER_ID}" role="dialog" aria-label="新建商品" aria-hidden="true">
    <div class="drawer-h">
      <h3>新建商品</h3>
      <button class="x" type="button" data-act="close" aria-label="关闭">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 6l12 12M6 18L18 6"/></svg>
      </button>
    </div>
    <div class="drawer-b">
      <div class="form-card">
        <div class="form-h">基础信息</div>

        <div class="field">
          <label class="field-label">商品名称<span class="req">*</span></label>
          <input class="input" data-f="name" placeholder="请输入商品名称(必填)" maxlength="100">
        </div>

        <div class="field-row">
          <div>
            <label class="field-label">品类<span class="req">*</span></label>
            <select class="select" data-f="cat">
              <option>美妆个护</option>
              <option>服饰内衣</option>
              <option>食品饮料</option>
              <option>家居家电</option>
              <option>数码 3C</option>
              <option>个护清洁</option>
              <option>运动户外</option>
              <option>母婴亲子</option>
            </select>
          </div>
          <div>
            <label class="field-label">目标人群<span class="opt">(选填)</span></label>
            <input class="input" data-f="target" placeholder="例: 22-32 岁女性、敏感肌、办公室通勤">
          </div>
        </div>

        <div class="field">
          <label class="field-label">商品主图<span class="req">*</span></label>
          <input type="file" data-f="file" accept="image/*" multiple hidden>
          <div class="pf-upload-row">
            <div class="pf-upload-zone" data-act="upload-zone">
              <div 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>
              </div>
              <div class="uz-t">点击上传或<strong>拖拽图片</strong>到此处</div>
              <div class="uz-d">// 支持 JPG、PNG 格式,建议尺寸 800×800 以上,大小不超过 10MB</div>
            </div>
            <div class="pf-example">
              <div class="ex-h">示例图</div>
              <div class="ex-grid">
                <div class="ex-thumb"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"><path d="M7 4h10l1 4v12H6V8l1-4z"/><path d="M9 4v3M15 4v3M9 11h6M9 14h6"/></svg></div>
                <div class="ex-thumb"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="5" width="12" height="15" rx="2"/><path d="M9 9h6M9 12h6M9 15h4"/></svg></div>
                <div class="ex-thumb"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3h8l1 5v12H7V8l1-5z"/><circle cx="12" cy="13" r="2.5"/></svg></div>
              </div>
              <div class="ex-d">优质的商品图有助于生成更好的素材效果</div>
            </div>
          </div>
          <div class="pf-grid" data-f="grid"></div>
        </div>

        <div class="field" style="margin-bottom: 0;">
          <label class="field-label">核心卖点<span class="req">*</span></label>
          <ul class="bullet-list" data-f="bullets">
            <li class="bl-add"><span class="num">+</span><input class="bl-input" placeholder="添加新卖点 · 回车或点击下方按钮"></li>
            <li class="bl-add-row" data-f="add-row">
              <button type="button" class="bl-add-btn" data-act="bl-add">
                <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M8 3v10M3 8h10"/></svg>
                添加卖点
              </button>
            </li>
          </ul>
        </div>
      </div>
    </div>

    <div class="drawer-f">
      <button class="btn-guide" type="button" data-act="guide">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9.5 9a2.5 2.5 0 015 0c0 1.5-2.5 2-2.5 4M12 17h.01"/></svg>
        使用指南
      </button>
      <button class="btn" type="button" data-act="cancel">取消</button>
      <button class="btn btn-primary" type="button" data-act="save">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l5 5L20 6"/></svg>
        创建商品
      </button>
    </div>
  </aside>

  <!-- 放弃填写 · 确认弹窗(覆盖在 drawer 之上) -->
  <div id="npd-confirm-bg" hidden>
    <div class="npd-confirm-modal" role="dialog" aria-label="放弃填写">
      <div class="dh">
        <div class="ic">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><path d="M12 9v4M12 17h.01"/></svg>
        </div>
        <div class="ti">
          <strong>放弃当前填写?</strong>
          <span class="mono">// 已填写的商品名、卖点、图片等内容将不会保留</span>
        </div>
      </div>
      <div class="df">
        <button type="button" data-act="keep">继续填写</button>
        <button type="button" class="danger" data-act="discard">放弃退出</button>
      </div>
    </div>
  </div>
  `;

  /* ---------- DOM refs (populated by ensureInjected) ---------- */
  let injected = false;
  let bg, drawer, $f, $grid, $bullets, $blInput;
  let confirmBg;
  let _forceClose = false;       // 保存成功后绕过脏检查
  let _initialCat = '';          // 打开时类目下拉的初始值,用来判断是否被改过
  let currentOpts = {};
  const PF_MAX = 5;
  let pfFiles = []; // { id, dataUrl, name }
  const blXSvg = '<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>';

  function esc(s) { return String(s == null ? '' : s).replace(/[<>&"]/g, c => ({ '<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;' })[c]); }
  function uid() { return Date.now().toString(36) + Math.random().toString(36).slice(2, 5); }
  function toast(msg, sub) {
    if (typeof Shell !== 'undefined' && Shell && Shell.toast) Shell.toast(msg, sub);
  }

  function ensureInjected() {
    if (injected) return;
    // style
    const styleEl = document.createElement('style');
    styleEl.textContent = CSS;
    document.head.appendChild(styleEl);
    // html
    const wrap = document.createElement('div');
    wrap.innerHTML = HTML;
    while (wrap.firstChild) document.body.appendChild(wrap.firstChild);

    bg        = document.getElementById(DRAWER_BG_ID);
    drawer    = document.getElementById(DRAWER_ID);
    confirmBg = document.getElementById('npd-confirm-bg');
    $f       = {
      name:   drawer.querySelector('[data-f="name"]'),
      cat:    drawer.querySelector('[data-f="cat"]'),
      target: drawer.querySelector('[data-f="target"]'),
      file:   drawer.querySelector('[data-f="file"]'),
    };
    $grid    = drawer.querySelector('[data-f="grid"]');
    $bullets = drawer.querySelector('[data-f="bullets"]');
    $blInput = $bullets.querySelector('.bl-add .bl-input');

    bindEvents();
    injected = true;
  }

  function bindEvents() {
    // 关闭交互
    bg.addEventListener('click', close);
    drawer.addEventListener('click', e => {
      const a = e.target.closest('[data-act]');
      if (!a) return;
      const act = a.dataset.act;
      if (act === 'close')  return close();
      if (act === 'cancel') return close();
      if (act === 'guide')  return toast('使用指南', '点击查看完整填写指南');
      if (act === 'save')   return save();
      if (act === 'upload-zone') return openFilePicker();
      if (act === 'bl-add') {
        blAdd($blInput.value);
        $blInput.value = '';
        $blInput.focus();
        updateBlAddBtn();
        return;
      }
    });
    document.addEventListener('keydown', e => {
      if (e.key === 'Escape' && drawer.classList.contains('show')) close();
    });

    // 上传
    $f.file.addEventListener('change', e => { addFiles(e.target.files); e.target.value = ''; });
    const zone = drawer.querySelector('[data-act="upload-zone"]');
    zone.addEventListener('dragover', e => { e.preventDefault(); zone.style.borderColor = 'var(--heat)'; });
    zone.addEventListener('dragleave', () => { zone.style.borderColor = ''; });
    zone.addEventListener('drop', e => {
      e.preventDefault(); zone.style.borderColor = '';
      if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length) addFiles(e.dataTransfer.files);
    });

    // 卖点 bullet-list
    $blInput.addEventListener('keydown', e => {
      if (e.key === 'Enter') {
        e.preventDefault();
        blAdd($blInput.value);
        $blInput.value = '';
        updateBlAddBtn();
      }
    });
    $blInput.addEventListener('input', updateBlAddBtn);
  }

  function updateBlAddBtn() {
    const row = $bullets && $bullets.querySelector('[data-f="add-row"]');
    if (!row) return;
    row.classList.toggle('show', !!($blInput.value || '').trim());
  }

  function openFilePicker() { if (pfFiles.length < PF_MAX) $f.file.click(); }

  function pfRender() {
    $grid.innerHTML = pfFiles.map(u => `
      <div class="pf-thumb" data-id="${u.id}">
        <img src="${u.dataUrl}" alt="${esc(u.name)}">
        <button class="pf-x" type="button" title="删除">
          <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>
        </button>
      </div>
    `).join('');
    $grid.querySelectorAll('.pf-thumb .pf-x').forEach(b => {
      b.onclick = e => {
        e.stopPropagation();
        const id = b.closest('.pf-thumb').dataset.id;
        const i = pfFiles.findIndex(f => f.id === id);
        if (i >= 0) { pfFiles.splice(i, 1); pfRender(); }
      };
    });
  }

  function addFiles(fileList) {
    const room = PF_MAX - pfFiles.length;
    if (room <= 0) { toast('已达上限', PF_MAX + ' / ' + PF_MAX + ' 张'); return; }
    const incoming = [...fileList].filter(f => f.type.startsWith('image/')).slice(0, room);
    let done = 0;
    incoming.forEach(f => {
      const r = new FileReader();
      r.onload = e => {
        pfFiles.push({ id: uid(), dataUrl: e.target.result, name: f.name });
        if (++done === incoming.length) {
          pfRender();
          toast('已上传', '+ ' + done + ' 张 · 共 ' + pfFiles.length + ' / ' + PF_MAX);
        }
      };
      r.readAsDataURL(f);
    });
  }

  function blRenumber() {
    [...$bullets.querySelectorAll('.bl-item')].forEach((li, i) => {
      li.querySelector('.num').textContent = i + 1;
    });
  }
  function blAdd(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">' + esc(t) + '</span><span class="bl-x" title="删除">' + blXSvg + '</span>';
    $bullets.querySelector('.bl-add').before(li);
    li.querySelector('.bl-x').addEventListener('click', () => {
      li.style.transition = 'opacity .15s, transform .15s';
      li.style.opacity = 0;
      li.style.transform = 'translateX(-8px)';
      setTimeout(() => { li.remove(); blRenumber(); }, 150);
    });
    blRenumber();
  }
  function getBullets() {
    return [...$bullets.querySelectorAll('.bl-item .bl-text')].map(t => t.textContent.trim()).filter(Boolean);
  }

  /* ---------- API ---------- */

  function resetForm() {
    $f.name.value = '';
    $f.cat.value = $f.cat.options[0].value;
    $f.target.value = '';
    pfFiles = [];
    pfRender();
    [...$bullets.querySelectorAll('.bl-item')].forEach(li => li.remove());
    $blInput.value = '';
    updateBlAddBtn();
  }

  function lockBody() {
    // 优先用 Shell 的引用计数实现(避免多 overlay 互相解锁)
    if (typeof Shell !== 'undefined' && Shell && typeof Shell.lockScroll === 'function') {
      Shell.lockScroll();
      return;
    }
    // 兜底: Shell 未加载时本地锁
    const docEl = document.documentElement;
    const sbw = window.innerWidth - docEl.clientWidth;
    drawer._lockSnap = {
      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';
  }
  function unlockBody() {
    if (typeof Shell !== 'undefined' && Shell && typeof Shell.unlockScroll === 'function') {
      Shell.unlockScroll();
      return;
    }
    const s = drawer._lockSnap;
    if (s) {
      document.body.style.overflow = s.bodyOverflow;
      document.body.style.paddingRight = s.bodyPaddingRight;
      document.documentElement.style.overflow = s.htmlOverflow;
      drawer._lockSnap = null;
    }
  }

  function open(opts) {
    ensureInjected();
    if (drawer.classList.contains('show')) return; // 已开则不重复锁
    currentOpts = opts || {};
    resetForm();
    _initialCat = $f.cat.value;  // 快照「打开时类目」用于脏检查
    bg.classList.add('show');
    drawer.classList.add('show');
    drawer.setAttribute('aria-hidden', 'false');
    lockBody();
    setTimeout(() => $f.name.focus(), 280);
  }

  /* ---------- 脏检查 + 退出确认 ---------- */
  function isDirty() {
    if (!injected) return false;
    if (($f.name.value || '').trim()) return true;
    if (($f.target.value || '').trim()) return true;
    if (($blInput.value || '').trim()) return true;
    if (pfFiles.length > 0) return true;
    if ($bullets.querySelectorAll('.bl-item').length > 0) return true;
    if ($f.cat.value !== _initialCat) return true;
    return false;
  }

  function confirmDiscard() {
    return new Promise(resolve => {
      confirmBg.hidden = false;
      const buttons = confirmBg.querySelectorAll('button[data-act]');
      function done(choice) {
        confirmBg.hidden = true;
        buttons.forEach(b => b.onclick = null);
        confirmBg.onclick = null;
        document.removeEventListener('keydown', escHandler, true);
        resolve(choice === 'discard');
      }
      function escHandler(e) {
        if (e.key === 'Escape') {
          e.stopPropagation();
          done('keep');
        }
      }
      buttons.forEach(b => b.onclick = () => done(b.dataset.act));
      confirmBg.onclick = e => { if (e.target === confirmBg) done('keep'); };
      // 用 capture · 截在外层 Esc 监听器之前
      document.addEventListener('keydown', escHandler, true);
    });
  }

  async function close() {
    if (!injected) return;
    if (!drawer.classList.contains('show')) return; // 已关则不重复解锁
    if (!_forceClose && isDirty()) {
      const ok = await confirmDiscard();
      if (!ok) return;
    }
    bg.classList.remove('show');
    drawer.classList.remove('show');
    drawer.setAttribute('aria-hidden', 'true');
    unlockBody();
    if (typeof currentOpts.onClose === 'function') currentOpts.onClose();
  }

  function closeForce() {
    _forceClose = true;
    try { close(); } finally { _forceClose = false; }
  }

  function save() {
    // 兜底:用户在卖点输入框敲了字但没回车/没点「添加卖点」就直接点创建,
    // 这里自动提交一次,避免静默丢失最后一条卖点(常见误操作)
    if ($blInput && ($blInput.value || '').trim()) {
      blAdd($blInput.value);
      $blInput.value = '';
      updateBlAddBtn();
    }

    const name   = ($f.name.value || '').trim();
    const cat    = $f.cat.value;
    const target = ($f.target.value || '').trim();
    const points = getBullets();
    const images = pfFiles.slice();

    if (!name) {
      toast('请填写商品名称');
      $f.name.focus();
      return;
    }
    if (images.length === 0) {
      toast('请上传商品主图', '至少 1 张');
      return;
    }
    if (points.length === 0) {
      toast('请添加核心卖点', '至少 1 条');
      $blInput.focus();
      return;
    }

    const product = {
      id: 'np-' + uid(),
      name, cat, target,
      points,
      images,
      imgs: images.length,
    };
    // 持久化到 sessionStorage('fs-extra-products') · 仅当前标签页生命周期内有效
    // 关闭标签页/浏览器后自动清空,不会跨会话累积演示残留
    try {
      const KEY = 'fs-extra-products';
      const list = JSON.parse(sessionStorage.getItem(KEY) || '[]');
      list.push({
        id: product.id,
        name, cat, target,
        tags: '',
        assets: 0,
        videos: 0,
        bullets: points,
        date: new Date().toISOString().slice(0, 10),
        createdAt: Date.now(),
      });
      sessionStorage.setItem(KEY, JSON.stringify(list));
    } catch (e) { /* storage 不可用降级到只跳转 */ }

    // 短期 sessionStorage 缓存完整 product(含图片 dataUrl),供 detail 页 ?id=new
    // 读出后渲染。读完即清除,避免污染后续操作。
    try {
      sessionStorage.setItem('npd-last-created', JSON.stringify(product));
    } catch (e) { /* dataUrl 可能过大 → 退化为不带图,detail 仍能渲染文本字段 */ }

    if (typeof currentOpts.onSave === 'function') {
      toast('商品已创建', '+ ' + name);
      currentOpts.onSave(product);
      closeForce();
      return;
    }
    // 默认行为: 不 close drawer · 跳转期间 drawer 仍覆盖 host 页面 → 视觉上彻底
    // 消除"闪 host"(浏览器导航开始后,整页被新页面替换,drawer 自然消失)
    toast('商品已创建', '+ ' + name);
    const url = 'product-detail.html?product=' + encodeURIComponent(name) + '&id=new';
    location.href = url;
  }

  window.NewProductDrawer = { open, close };

  /* ---------- sessionStorage 自动打开钩子 ---------- */
  // 任何页面只要在跳转前 sessionStorage.setItem('npd-auto-open','1') 即可,
  // 落地页加载完模块后,会自动 open() 一次并清掉 flag。
  // 用于:product-create.html 重定向后让落地页弹出 drawer,而不是用户重新点击。
  function checkAutoOpen() {
    try {
      if (sessionStorage.getItem('npd-auto-open') === '1') {
        sessionStorage.removeItem('npd-auto-open');
        // 延后一拍,确保宿主页面自己的 init 已经跑完
        setTimeout(() => open(), 50);
      }
    } catch (e) { /* sessionStorage 不可用就静默放弃 */ }
  }
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', checkAutoOpen);
  } else {
    checkAutoOpen();
  }
})();
