/* global React, Icon, Button, useToast,
   PRODUCT_MASTER, CellEditor, TableGroupHeader, SubmitConfirmPage,
   DeleteRowBtn, PageHead, EmptyState, SkuToolbar, ModeToggle,
   ImportBanner, EO_ALL_COLS, EO_COMPACT_KEYS, EO_GROUP_LABELS, EO_NUM_W,
   DISCOUNT_TYPE_OPTIONS, isFriday, isThursday, PortalSelect,
   ShowErrorsProvider, ErrWrap, ErrIconTip,
   EO_FLD, EO_FORM_FIELDS, useFormValidation, RowErrTip */
// Eats Offer — 新增品項（表格式建立頁，無批次 MetaCard）

// Private helpers — underscore prefix avoids const conflicts with eo-detail.jsx global scope

const _ecUid = () => "eo-c" + Math.random().toString(36).slice(2, 9);

const _ecCalcFinal = (row) => row.u1PromoPrice || row.promoPrice || null;

const _ecRecalc = (row) => {
  const finalPrice  = _ecCalcFinal(row);
  const fp   = +finalPrice, cost = +(row.cost || 0);
  const sugg = +(row.suggestPrice || 0), list = +(row.listPrice || 0);
  const marginPct   = fp ? +((fp - cost) / fp).toFixed(4) : null;
  const discountPct = fp && sugg ? +(1 - fp / sugg).toFixed(4) : null;
  const promoCheck  = fp && list ? (fp < list  ? "PASS" : "FAIL") : null;
  const promoVsList = fp && sugg ? (fp < sugg  ? "PASS" : "FAIL") : null;
  const promoDepth  = fp && list ? +((list - fp) / list).toFixed(4) : null;
  const bogoType = row.discountType === "BOGO" || row.discountType === "Volume Discount";
  const bq = +(row.buyQty || 0);
  const unitPrice = bogoType && fp && bq ? +(fp / bq).toFixed(2) : null;
  const setPrice  = bogoType && fp && bq ? +(fp * bq).toFixed(2) : null;
  return {
    ...row, finalPrice, marginPct, discountPct, promoCheck, promoVsList, promoDepth,
    unitPrice, setPrice, doEatsOffer: "YES",
    buyQty:      bogoType ? row.buyQty      : null,
    discountQty: bogoType ? row.discountQty : null,
  };
};

const _ecAutoFill = (barcode, base = {}) => {
  const master = PRODUCT_MASTER.find(p => p.barcode === barcode);
  if (!master) return null;
  return _ecRecalc({
    ...base, barcode,
    name:         master.name,
    mainCat:      master.mainCat      ?? "",
    subCat:       master.subCat       ?? "",
    cost:         master.cost         ?? null,
    listPrice:    master.listPrice    ?? null,
    suggestPrice: master.suggestPrice ?? null,
    vat:          master.taxRate      ?? "",
  });
};

const _ecNewRow = (applicant) => _ecRecalc({
  uid: _ecUid(), fillBy: applicant || "",
  barcode: "", name: "", mainCat: "", subCat: "",
  cost: null, newCost: null, promoStart: "", promoEnd: "",
  listPrice: null, suggestPrice: null,
  promoPrice: null, u1PromoPrice: null,
  discountType: "", buyQty: null, discountQty: null,
  menuPromoStart: "", menuPromoEnd: "", purchaseLimit: null,
  autoListWhitelist: false, marketPrice: null, poc: "", vat: "",
  costInErp: null, timeCheck: false,
});

const _ecSysCheck = (row) => {
  if (!row.barcode) return { pass: false, msg: "品號不可為空" };
  if (!PRODUCT_MASTER.find(p => p.barcode === row.barcode))
    return { pass: false, msg: `品號 ${row.barcode} 查無商品主檔資料` };
  if (!row.promoPrice) return { pass: false, msg: "促銷售價不可為空" };
  if (!row.discountType) return { pass: false, msg: "折扣種類不可為空" };
  if (row.promoCheck === "FAIL") return { pass: false, msg: "促銷售價需低於牌價（真促銷價檢查 FAIL）" };
  if (row.promoVsList === "FAIL") return { pass: false, msg: "促銷售價需低於建議售價（促銷<>牌價 FAIL）" };
  if (row.menuPromoStart && !isFriday(row.menuPromoStart))
    return { pass: false, msg: `菜單促銷開始（${row.menuPromoStart}）必須為週五` };
  if (row.menuPromoEnd && !isThursday(row.menuPromoEnd))
    return { pass: false, msg: `菜單促銷結束（${row.menuPromoEnd}）必須為週四` };
  return { pass: true, msg: "✓ 檢查通過" };
};

// ── EoCreatePage ──────────────────────────────────────────────────────────────
const EoCreatePage = ({ currentUser, onBack, onSave, initialItems }) => {
  const [items,          setItems]          = React.useState(() => initialItems || []);
  const [dirty,          setDirty]          = React.useState(false);
  const [colMode,        setColMode]        = React.useState("compact");
  const [pageMode,       setPageMode]       = React.useState("view"); // "view" | "doubleCheck"
  const [sysChecked,     setSysChecked]     = React.useState(false);
  const [sysCheckErrMap, setSysCheckErrMap] = React.useState(null);
  const { push: toast } = useToast();
  const fileInputRef  = React.useRef(null);
  const [importPhase, setImportPhase] = React.useState(null); // null | "parsing" | "ok" | "error"
  const [importStats, setImportStats] = React.useState({ done: 0, total: 0, errorCount: 0 });

  // ── Item mutations ─────────────────────────────────────────────────────────
  const patchItem = (uid, patch) => {
    setItems(its => its.map(it => it.uid !== uid ? it : _ecRecalc({ ...it, ...patch })));
    setDirty(true);
  };

  const handleBarcodeCommit = (uid, barcode) => {
    const existing = items.find(it => it.uid === uid) || {};
    const filled = _ecAutoFill(barcode, existing);
    if (filled) {
      setItems(its => its.map(it => it.uid === uid ? { ...it, ...filled, uid } : it));
      setDirty(true);
    } else {
      patchItem(uid, { barcode, name: "", mainCat: "", subCat: "", cost: null, listPrice: null, suggestPrice: null, vat: "" });
      if (barcode) toast({ kind: "warning", msg: `品號 ${barcode} 查無商品主檔資料` });
    }
  };

  const addRow    = () => { setItems(its => [...its, _ecNewRow(currentUser)]); setDirty(true); };
  const deleteRow = (uid) => { setItems(its => its.filter(it => it.uid !== uid)); setDirty(true); };

  // ── Excel import simulation ────────────────────────────────────────────────
  // menuPromoStart 2026-06-05 = Friday ✓; 2026-06-06 = Saturday ✗; 2026-06-07 = Sunday ✗
  // menuPromoEnd   2026-07-02 = Thursday ✓
  const _importDiscTypes  = ["DISCOUNTEDITEM","BOGO","Volume Discount","Frame","DISCOUNTEDITEM","BOGO","DISCOUNTEDITEM","Volume Discount"];
  const _importMenuStarts = ["2026-06-05","2026-06-05","2026-06-06","2026-06-05","2026-06-05","2026-06-07","2026-06-05","2026-06-05"];

  const _finishImport = (total, existingBarcodes) => {
    const candidates = PRODUCT_MASTER.filter(p => !existingBarcodes.has(p.barcode)).slice(0, total);
    const newRows = candidates.map((master, i) => {
      const promoPrice = Math.round((master.listPrice || 200) * 0.85);
      const base = {
        uid: _ecUid(),
        promoPrice,
        discountType:   _importDiscTypes[i]  || "DISCOUNTEDITEM",
        promoStart:     "2026-06-06",
        promoEnd:       "2026-06-25",
        menuPromoStart: _importMenuStarts[i] || "2026-06-05",
        menuPromoEnd:   "2026-07-02",
      };
      return _ecAutoFill(master.barcode, base) || _ecNewRow(currentUser);
    });
    const errorCount = newRows.filter(r =>
      (r.menuPromoStart && !isFriday(r.menuPromoStart)) ||
      (r.menuPromoEnd   && !isThursday(r.menuPromoEnd))
    ).length;
    setItems(prev => [...prev, ...newRows]);
    setDirty(true);
    setImportStats({ done: total, total, errorCount });
    setImportPhase(errorCount > 0 ? "error" : "ok");
    if (errorCount > 0) triggerShowErrors();
    toast({
      kind: errorCount > 0 ? "warning" : "success",
      msg:  `已匯入 ${newRows.length} 筆${errorCount > 0 ? `，${errorCount} 筆菜單促銷日期需修正` : ""}`,
    });
  };

  const _runFakeImport = () => {
    setImportPhase("parsing");
    const total = 8;
    setImportStats({ done: 0, total, errorCount: 0 });
    const existingBarcodes = new Set(items.map(it => it.barcode));
    let done = 0;
    const tick = () => {
      done += 1;
      setImportStats(s => ({ ...s, done }));
      if (done < total) setTimeout(tick, 110);
      else _finishImport(total, existingBarcodes);
    };
    setTimeout(tick, 200);
  };

  // ── Save / submit ──────────────────────────────────────────────────────────
  const { showErrors, submitGuard, triggerShowErrors } = useFormValidation(items, EO_FORM_FIELDS, "送出");

  // 新列才帶當前使用者為建立者/採購線；既有列保留原值（不覆寫他人 applicant）
  const _stamp = (it, extra) => ({
    ...it, ...extra,
    applicant: it.applicant || currentUser,
    lineOwner: it.lineOwner || currentUser,
  });

  const handleSaveDraft = () => {
    onSave(items.map(it => _stamp(it, { status: "eoDraft" })));
    setDirty(false);
    toast({ kind: "success", msg: `已儲存 ${items.length} 筆草稿` });
  };

  const handleSysCheckConfirm = () => {
    // 逐商品判斷：毛利率 < 20% → 送審；否則自動放行立即生效（eo 單位是商品，非整批）。
    // ⚠️ 「毛利率 < 20%」為 prototype 假條件，正式系統依審核流程設定模組判斷。
    const saved = items.map(it =>
      _stamp(it, { status: (it.marginPct ?? 1) < 0.20 ? "eoUnderReview" : "eoNoReview" }));
    onSave(saved);
    const reviewCount = saved.filter(it => it.status === "eoUnderReview").length;
    const passCount   = saved.length - reviewCount;
    const msg = reviewCount === 0
      ? `${passCount} 筆商品已提交，系統自動放行（毛利率 ≥ 20%）`
      : passCount === 0
        ? `${reviewCount} 筆商品已送審，待採購主管審核`
        : `${reviewCount} 筆送審、${passCount} 筆已自動放行生效`;
    toast({ kind: "success", msg });
  };

  // ── Column selection ───────────────────────────────────────────────────────
  const showCols = React.useMemo(() => (
    colMode === "compact"
      ? EO_ALL_COLS.filter(c => c.stickyNum || c.sticky2nd || c.actionCol || EO_COMPACT_KEYS.includes(c.key))
      : EO_ALL_COLS
  ), [colMode]);

  const dataCols   = showCols.filter(c => !c.stickyNum && !c.actionCol);
  const actionCol  = showCols.find(c => c.actionCol);
  const totalWidth = showCols.reduce((s, c) => s + c.w, 0);

  // ── Cell rendering (always editable) ─────────────────────────────────────
  const renderCell = (col, row, idx) => {
    const k = col.key;

    if (k === "#") return (
      <td key={k} style={{
        textAlign: "center", color: "var(--fg-3)",
        position: "sticky", left: 0, background: "var(--bg-surface)", zIndex: 1, padding: "0 4px",
      }}>
        {sysCheckErrMap?.[row.uid] && <RowErrTip msg={sysCheckErrMap[row.uid]} />}
        {idx + 1}
      </td>
    );

    if (k === "barcode") return (
      <td key={k} style={{
        position: "sticky", left: EO_NUM_W, background: "var(--bg-surface)", zIndex: 1,
        boxShadow: "2px 0 4px rgba(0,0,0,.06)",
      }}>
        <CellEditor alwaysOn
          field={EO_FLD.barcode}
          value={row.barcode} row={row}
          onCommit={val => handleBarcodeCommit(row.uid, val)} />
      </td>
    );

    if (k === "_action") return (
      <td key={k} style={{ textAlign: "center", padding: "0 4px", verticalAlign: "middle" }}>
        <DeleteRowBtn onClick={() => deleteRow(row.uid)} />
      </td>
    );

    if (k === "discountType") return (
      <td key={k}>
        <ErrWrap errMsg={showErrors ? EO_FLD.discountType.validate(row) : null}>
          <PortalSelect
            value={row.discountType}
            options={DISCOUNT_TYPE_OPTIONS}
            onChange={v => patchItem(row.uid, { discountType: v })}
            triggerClassName="cell-editor-portal-trigger"
            placeholder="選擇…"
          />
        </ErrWrap>
      </td>
    );

    if (k === "buyQty" || k === "discountQty") {
      const bogoType = row.discountType === "BOGO" || row.discountType === "Volume Discount";
      if (!bogoType) return <td key={k} className="mono" style={{ color: "var(--fg-4)", textAlign: "right" }}>—</td>;
      return (
        <td key={k}>
          <CellEditor alwaysOn
            field={{ key: k, type: "num", label: col.label }}
            value={row[k]} row={row}
            onCommit={val => patchItem(row.uid, { [k]: val ? +val : null })} />
        </td>
      );
    }

    if (k === "menuPromoStart") return (
      <td key={k}>
        <CellEditor alwaysOn
          field={EO_FLD.promoStart}
          value={row.menuPromoStart} row={row}
          onCommit={val => patchItem(row.uid, { menuPromoStart: val })} />
      </td>
    );

    if (k === "menuPromoEnd") return (
      <td key={k}>
        <CellEditor alwaysOn
          field={EO_FLD.promoEnd}
          value={row.menuPromoEnd} row={row}
          onCommit={val => patchItem(row.uid, { menuPromoEnd: val })} />
      </td>
    );

    if (k === "marginPct") {
      const v = row.marginPct;
      const warn = v != null && v < 0.20;
      return (
        <td key={k} className="mono" style={{ textAlign: "right", color: warn ? "var(--red-600, #DC2626)" : "var(--fg-2)", fontWeight: warn ? 600 : undefined }}>
          {v != null ? `${(v * 100).toFixed(1)}%` : <span style={{ color: "var(--fg-4)" }}>—</span>}
        </td>
      );
    }

    if (k === "discountPct" || k === "promoDepth" || k === "stackDepth") {
      const v = row[k];
      return (
        <td key={k} className="mono" style={{ textAlign: "right", color: "var(--fg-2)" }}>
          {v != null ? `${(v * 100).toFixed(1)}%` : <span style={{ color: "var(--fg-4)" }}>—</span>}
        </td>
      );
    }

    if (k === "autoListWhitelist") return (
      <td key={k} style={{ textAlign: "center" }}>
        <CellEditor alwaysOn
          field={{ key: k, type: "bool", label: col.label }}
          value={row.autoListWhitelist} row={row}
          onCommit={val => patchItem(row.uid, { autoListWhitelist: !!val })} />
      </td>
    );

    if (k === "costInErp" || k === "timeCheck") {
      const v = row[k];
      return <td key={k} style={{ textAlign: "center", color: v ? "var(--fg-1)" : "var(--fg-4)" }}>{v ? "✓" : "—"}</td>;
    }

    if (k === "promoPrice") return (
      <td key={k}>
        <CellEditor alwaysOn
          field={EO_FLD.promoPrice}
          value={row.promoPrice} row={row}
          onCommit={val => patchItem(row.uid, { promoPrice: val ? +val : null })} />
      </td>
    );

    if (col.editable && !["discountType","buyQty","discountQty","menuPromoStart","menuPromoEnd","autoListWhitelist","costInErp","timeCheck","promoPrice"].includes(k)) {
      const isNum  = ["newCost","promoPrice","u1PromoPrice","purchaseLimit"].includes(k);
      const isDate = k.includes("Start") || k.includes("End") || k.includes("start") || k.includes("end");
      return (
        <td key={k}>
          <CellEditor alwaysOn
            field={{ key: k, type: isNum ? "num" : (isDate ? "date" : "str"), label: col.label, mono: col.mono }}
            value={row[k]} row={row}
            onCommit={val => patchItem(row.uid, { [k]: isNum && val ? +val : val })} />
        </td>
      );
    }

    const moneyKeys = ["cost","newCost","listPrice","suggestPrice","promoPrice","u1PromoPrice","finalPrice","unitPrice","setPrice","marketPrice"];
    if (moneyKeys.includes(k)) {
      const v = row[k];
      if (v == null) return <td key={k} className="mono" style={{ color: "var(--fg-4)", textAlign: "right" }}>—</td>;
      return (
        <td key={k} className="mono" style={{ color: "var(--fg-2)", textAlign: "right" }}>
          NT${(+v).toLocaleString("zh-TW", { minimumFractionDigits: 0, maximumFractionDigits: 2 })}
        </td>
      );
    }

    if (k === "promoCheck" || k === "promoVsList" || k === "autoListAdj") {
      const v = row[k];
      const isPass = v === "PASS" || v === "NO";
      const isFail = v === "FAIL" || v === "YES";
      const failMsg = k === "promoCheck" ? "促銷售價 ≥ 牌價" : k === "promoVsList" ? "促銷售價 ≥ 建議售價" : null;
      return (
        <td key={k} style={{ textAlign: "center", fontWeight: isFail ? 600 : undefined, color: isFail ? "var(--red-600, #DC2626)" : isPass ? "var(--fg-2)" : "var(--fg-4)" }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
            {v || "—"}
            {isFail && failMsg && <ErrIconTip msg={failMsg} />}
          </span>
        </td>
      );
    }

    const v = row[k];
    if (v == null || v === "") return <td key={k} style={{ color: "var(--fg-4)" }}>—</td>;
    return <td key={k} className={col.mono ? "mono" : ""} style={{ color: "var(--fg-2)" }}>{String(v)}</td>;
  };

  // ── DoubleCheck page (with inline sysCheck) ───────────────────────────────
  if (pageMode === "doubleCheck") {
    const dcChecks     = items.map(r => _ecSysCheck(r));
    const dcErrCount   = dcChecks.filter(c => !c.pass).length;
    const dcAllPass    = items.length > 0 && dcErrCount === 0;
    const requiresReview = items.some(i => (i.marginPct ?? 1) < 0.20);

    const handleDCConfirm = () => {
      setSysChecked(true);
      if (dcAllPass) handleSysCheckConfirm();
    };

    const handleDCBack = () => {
      if (sysChecked && !dcAllPass) {
        const errMap = {};
        items.forEach((r, i) => { if (!dcChecks[i].pass) errMap[r.uid || i] = dcChecks[i].msg; });
        setSysCheckErrMap(errMap);
      }
      setPageMode("view");
    };

    return (
      <SubmitConfirmPage
        moduleName="促銷活動"
        batchName="新增品項"
        subtitle={sysChecked && !dcAllPass
          ? "系統檢查未通過，請修正後重新送出。"
          : "請確認以下品項內容無誤，確認後將進行系統檢查並送審。"
        }
        pageTitle="送審前確認"
        confirmLabel="確認送審"
        onBack={handleDCBack}
        onConfirm={handleDCConfirm}
        confirmDisabled={sysChecked && !dcAllPass}
      >
        {sysChecked && !dcAllPass && (
          <ImportBanner
            phase="error"
            titlePrefix="系統檢查："
            titleSuffix="品項需要修正"
            desc="請修正後點擊「返回修改」，重新送出。"
            errorCount={dcErrCount}
          />
        )}
        {sysChecked && dcAllPass && (
          <div style={{
            background: "var(--blue-50, #EFF6FF)", border: "1px solid var(--blue-200, #BFDBFE)",
            borderRadius: 4, padding: "10px 16px", marginBottom: 12,
            fontSize: 13, color: "var(--blue-700, #1D4ED8)", display: "flex", gap: 8, alignItems: "center",
          }}>
            <Icon name="info" size={16} />
            {requiresReview
              ? `${items.filter(i => (i.marginPct ?? 1) < 0.20).length} 筆商品毛利率 < 20%，送出後將進入採購主管人工審核。`
              : "所有商品毛利率 ≥ 20%，送出後系統自動放行，無需人工審核。"
            }
          </div>
        )}
        <div className="card">
          <div style={{ padding: "10px 16px", borderBottom: "1px solid var(--border)", fontSize: 13, color: "var(--fg-2)" }}>
            共 <b style={{ color: "var(--fg-1)" }}>{items.length}</b> 筆商品
          </div>
          <div className="tbl-wrap">
            <table className="tbl">
              <thead>
                <tr>
                  <th style={{ width: 32, textAlign: "center" }}>#</th>
                  <th style={{ width: 160 }}>品號</th>
                  <th>品名</th>
                  <th style={{ width: 100 }}>促銷售價</th>
                  <th style={{ width: 110 }}>最終新售價</th>
                  <th style={{ width: 85 }}>毛利率 M%</th>
                  <th style={{ width: 110 }}>折扣種類</th>
                  <th style={{ width: 115 }}>菜單促銷開始</th>
                  <th style={{ width: 115 }}>菜單促銷結束</th>
                </tr>
              </thead>
              <tbody>
                {items.length === 0 && (
                  <tr><td colSpan={9} style={{ textAlign: "center", padding: 24, color: "var(--fg-3)" }}>尚無商品</td></tr>
                )}
                {items.map((row, idx) => {
                  const m = row.marginPct;
                  const mStyle = m != null && m < 0.20 ? { fontWeight: 600, color: "var(--red-600, #DC2626)" } : {};
                  const discOpt = DISCOUNT_TYPE_OPTIONS.find(o => o.value === row.discountType);
                  return (
                    <tr key={row.uid || idx}>
                      <td style={{ textAlign: "center", color: "var(--fg-3)", position: "relative" }}>
                        {sysChecked && !dcChecks[idx].pass && <RowErrTip msg={dcChecks[idx].msg} />}
                        {idx + 1}
                      </td>
                      <td className="mono" style={{ fontSize: 12 }}>{row.barcode || "—"}</td>
                      <td>{row.name || "—"}</td>
                      <td className="mono">{row.promoPrice != null ? `NT$${row.promoPrice}` : "—"}</td>
                      <td className="mono">{row.finalPrice != null ? `NT$${row.finalPrice}` : "—"}</td>
                      <td className="mono" style={mStyle}>{m != null ? `${(m * 100).toFixed(1)}%` : "—"}</td>
                      <td>{discOpt ? discOpt.label : (row.discountType || "—")}</td>
                      <td className="mono">{row.menuPromoStart || "—"}</td>
                      <td className="mono">{row.menuPromoEnd   || "—"}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </SubmitConfirmPage>
    );
  }

  // ── Main table view ────────────────────────────────────────────────────────
  return (
    <>
      <PageHead
        crumbs={[
          { label: "促銷活動" },
          { label: "單品優惠（Eats Offer）", onClick: onBack },
          { label: "新增品項", current: true },
        ]}
        title="新增品項"
        dirty={dirty}
        actions={<>
          <Button variant="default" icon="download"
            onClick={() => toast({ kind: "success", msg: "範本下載中…" })}>
            下載匯入格式
          </Button>
          <Button variant="default" icon="upload"
            onClick={() => fileInputRef.current?.click()}>
            匯入 Excel
          </Button>
          <Button variant="default"
            disabled={items.length === 0}
            onClick={handleSaveDraft}>
            儲存草稿
          </Button>
          <Button variant="primary" icon="send"
            disabled={items.length === 0}
            onClick={() => submitGuard(() => { setSysChecked(false); setSysCheckErrMap(null); setPageMode("doubleCheck"); })}>
            送出
          </Button>
        </>}
      />

      <input
        ref={fileInputRef}
        type="file"
        accept=".xlsx,.xls,.csv"
        style={{ display: "none" }}
        onChange={(e) => {
          if (!e.target.files?.[0]) return;
          e.target.value = "";
          _runFakeImport();
        }}
      />

      {importPhase && (
        <ImportBanner
          phase={importPhase}
          total={importStats.total}
          done={importStats.done}
          errorCount={importStats.errorCount}
          onClose={() => setImportPhase(null)}
        />
      )}

      {sysCheckErrMap && Object.keys(sysCheckErrMap).length > 0 && (
        <ImportBanner
          phase="error"
          titlePrefix="系統檢查："
          titleSuffix="品項需要修正"
          desc="下方標示的列有問題，修正後請重新送出。"
          errorCount={Object.keys(sysCheckErrMap).length}
          onView={(idx) => { const inds = document.querySelectorAll('.row-err-ind'); inds[idx % (inds.length || 1)]?.closest('tr')?.scrollIntoView({ block: 'center', behavior: 'smooth' }); }}
          onClose={() => setSysCheckErrMap(null)}
        />
      )}

      <div className="card">
        <SkuToolbar>
          <ModeToggle mode={colMode} onChange={setColMode} compactLabel="精選欄位" />
          <span style={{ fontSize: 13, color: "var(--fg-2)", flexShrink: 0, marginLeft: 12 }}>
            共 <b style={{ color: "var(--fg-1)" }}>{items.length}</b> 筆
          </span>
          <Button variant="default" size="sm" icon="plus" onClick={addRow} style={{ marginLeft: "auto" }}>
            新增品項列
          </Button>
        </SkuToolbar>

        {items.length === 0 ? (
          <EmptyState icon="tag" title="尚無品項" desc="點「新增品項列」或匯入 Excel 開始作業。">
            <Button variant="primary" icon="plus" onClick={addRow}>新增品項列</Button>
          </EmptyState>
        ) : (
          <ShowErrorsProvider value={showErrors}>
          <>
            <div className="tbl-wrap">
              <table className="tbl" style={{ borderCollapse: "separate", borderSpacing: 0, minWidth: totalWidth }}>
                <thead>
                  <TableGroupHeader
                    cols={dataCols}
                    groupLabels={EO_GROUP_LABELS}
                    leadingSlot={
                      <th rowSpan={2} style={{
                        width: EO_NUM_W, minWidth: EO_NUM_W, padding: "0 4px",
                        position: "sticky", left: 0, zIndex: 3, background: "var(--gray-50)",
                      }}>#</th>
                    }
                    actionCol={actionCol}
                  />
                  <tr>
                    {dataCols.map(c => {
                      const s = { width: c.w, minWidth: c.w };
                      if (c.sticky2nd) return (
                        <th key={c.key} style={{ ...s, position: "sticky", left: EO_NUM_W, zIndex: 2, boxShadow: "2px 0 4px rgba(0,0,0,.06)" }}>
                          {c.label}
                        </th>
                      );
                      return <th key={c.key} style={s}>{c.label}</th>;
                    })}
                  </tr>
                </thead>
                <tbody>
                  {items.map((row, idx) => (
                    <tr key={row.uid}>
                      {showCols.map(c => renderCell(c, row, idx))}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <button className="tbl-add-row" onClick={addRow}>
              <Icon name="plus" size={16} /> 新增品項列
            </button>
          </>
          </ShowErrorsProvider>
        )}
      </div>
    </>
  );
};

Object.assign(window, { EoCreatePage });
