/* global React, Icon, Button, Tag, Check, useToast, Textarea, ModeToggle, ChipFilter,
   ROLES, PRODUCT_MASTER, SALE_STATUS_LABELS, computeAggStatus, AggStatusDisplay,
   CellEditor, TableGroupHeader, MetaCard, SubmitConfirmPage, BulkBar, DeleteRowBtn, InfoTip, TruncCell, PageHead, ImportBanner, SkuToolbar, EmptyState,
   ShowErrorsProvider, ErrWrap, useFormValidation, RowErrTip, ADJ_TRACKING_COLS, renderAdjTrackingCell, isPrototypeSuperUser, canActAsPurchase, canActAsJoanna */
// ADJ-C/D L2 — 商品狀態調整 批次明細（四模式：編輯 / Double Check / 系統檢查 / 唯讀審核）

const { useState, useMemo, useCallback, useEffect, useRef } = React;

const ADD_LABEL = "新增品項";

// ── adjType constants ─────────────────────────────────────────────────────────
const STATUS_ADJ_TYPES = [
  { value: "statusStopAt",     label: "商品停售（@）" },
  { value: "statusStopHash",   label: "商品停售（#）" },
  { value: "statusStopHash02", label: "商品停售（#02）" },
  { value: "statusSuspend",    label: "暫時停止供貨" },
  { value: "statusResume",     label: "恢復供貨" },
];
const INFO_ADJ_TYPES = [
  { value: "infoName",        label: "修改品名" },
  { value: "infoListPrice",   label: "修改牌價" },
  { value: "infoDescription", label: "更新商品描述" },
  { value: "infoRegion",      label: "調整販售區域" },
  { value: "infoCategory",    label: "調整大小分類" },
  { value: "infoBarcode",     label: "更新條碼" },
  { value: "infoBindBarcode", label: "綁定條碼" },
  { value: "infoSpec",        label: "修改規格" },
  { value: "infoTemp",        label: "修改溫層" },
  { value: "infoTier",        label: "修改品項分級" },
  { value: "infoReturnDays",  label: "修改可退換天數" },
  { value: "infoTaxRate",    label: "修改稅率" },
];

const ADJTYPE_LABELS = Object.fromEntries(
  [...STATUS_ADJ_TYPES, ...INFO_ADJ_TYPES].map(({ value, label }) => [value, label])
);

// ── D condition column → required adjType mapping ─────────────────────────────
const D_COND_COL_TYPES = {
  newBarcode:      ["infoBarcode", "infoBindBarcode"],
  newMainCat:      ["infoCategory"],
  newSubCat:       ["infoCategory"],
  newName:         ["infoName"],
  newDescription:  ["infoDescription"],
  newListPrice:    ["infoListPrice"],
  newSuggestPrice: ["infoListPrice"],
  newTier:         ["infoTier"],
  newRegion:       ["infoRegion"],
  newTemp:         ["infoTemp"],
  newSpec:         ["infoSpec"],
  newReturnDays:   ["infoReturnDays"],
  newTaxRate:      ["infoTaxRate"],
};

// Get D condition col keys for a batch (union of all rows' adjTypes)
function getCondColKeys(rows) {
  const types = new Set(rows.flatMap(r => Array.isArray(r.adjType) ? r.adjType : r.adjType ? [r.adjType] : []));
  const cols = [];
  if (types.has("infoBarcode") || types.has("infoBindBarcode")) cols.push("newBarcode");
  if (types.has("infoCategory"))    cols.push("newMainCat", "newSubCat");
  if (types.has("infoName"))        cols.push("newName");
  if (types.has("infoDescription")) cols.push("newDescription");
  if (types.has("infoListPrice"))   cols.push("newListPrice", "newSuggestPrice");
  if (types.has("infoTier"))        cols.push("newTier");
  if (types.has("infoRegion"))      cols.push("newRegion");
  if (types.has("infoTemp"))        cols.push("newTemp");
  if (types.has("infoSpec"))        cols.push("newSpec");
  if (types.has("infoReturnDays"))  cols.push("newReturnDays");
  if (types.has("infoTaxRate"))     cols.push("newTaxRate");
  return cols;
}

// Is a D condition cell non-applicable for this row?
function isCellNonApplicable(colKey, row) {
  const required = D_COND_COL_TYPES[colKey];
  if (!required) return false;
  const rowTypes = Array.isArray(row.adjType) ? row.adjType : row.adjType ? [row.adjType] : [];
  return !required.some(t => rowTypes.includes(t));
}

const AS_FLD_ADJ_TYPE = { key: "adjType", validate: r => {
  const types = Array.isArray(r.adjType) ? r.adjType : r.adjType ? [r.adjType] : [];
  return types.length === 0 ? "必填" : null;
}};
const AS_FORM_FIELDS = [
  AS_FLD_ADJ_TYPE,
  ...Object.keys(D_COND_COL_TYPES).map(k => ({
    key: k,
    validate: r => !isCellNonApplicable(k, r) && !r[k] ? "必填" : null,
  })),
];

// sysCheckRow
function sysCheckRow(row) {
  const types = Array.isArray(row.adjType) ? row.adjType : row.adjType ? [row.adjType] : [];
  if (row.saleStatus === "discontinued")
    return { pass: false, msg: "此品項「販售狀態：下架」，請調整重送" };
  if (types.length === 0)
    return { pass: false, msg: "申請事項必填" };
  if (types.includes("infoName") && !row.newName)
    return { pass: false, msg: "新品名必填" };
  if (types.includes("infoListPrice") && !(row.newListPrice > 0))
    return { pass: false, msg: "新牌價必填" };
  if ((types.includes("infoBarcode") || types.includes("infoBindBarcode")) && !row.newBarcode)
    return { pass: false, msg: "新品號必填" };
  if (types.includes("infoCategory") && !row.newMainCat)
    return { pass: false, msg: "新大分類必填" };
  if (types.includes("infoRegion") && !row.newRegion)
    return { pass: false, msg: "新販售區域必填" };
  return { pass: true, msg: "✓ 通過" };
}

// ── Column factory ────────────────────────────────────────────────────────────
const as = (key, label, w, group, opts = {}) => ({ key, label, w, group, ...opts });

const NUM_COL_W = 32;

const A_COLS = [
  as("#",           "#",            NUM_COL_W, null,  { stickyNum: true }),
  as("barcode",     "品號",         160, "A",  { mono: true, sticky2nd: true }),
  as("productName", "品名",         220, "A"),
  as("supplierNo",  "廠編",          80, "A",  { mono: true }),
  as("supplierName","廠商名稱",      130, "A"),
];
const B_COLS = [
  as("mainCat",     "主類別",        90, "B"),
  as("subCat",      "次類別",        90, "B"),
];
const C_COLS = [
  as("saleStatus",  "販售狀態",      80, "C"),
  as("taxType",     "應免稅",        70, "C"),
  as("tier",        "品項分級（目前）",100, "C"),
  as("region",      "販售區域（目前）",110,"C"),
  as("specSummary", "規格（目前）",  160, "C",  { formula: true }),
  as("expType",     "效期呈現方式",  110, "C"),
  as("origin",      "商品產地",       90, "C"),
];
const D_BASE_COLS = [
  as("adjType",     "申請事項",      190, "D"),
  as("adjNote",     "商品調整備註",  160, "D"),
];
const ALL_D_COND_COL_DEFS = {
  newBarcode:      as("newBarcode",      "新品號",       120, "D"),
  newMainCat:      as("newMainCat",      "新大分類",     120, "D"),
  newSubCat:       as("newSubCat",       "新小分類",     120, "D"),
  newName:         as("newName",         "新品名",       190, "D"),
  newDescription:  as("newDescription",  "新商品描述",   200, "D"),
  newListPrice:    as("newListPrice",    "新牌價",       100, "D",  { mono: true }),
  newSuggestPrice: as("newSuggestPrice", "新建議售價",   110, "D",  { mono: true }),
  newTier:         as("newTier",         "新品項分級",   100, "D"),
  newRegion:       as("newRegion",       "新販售區域",   130, "D"),
  newTemp:         as("newTemp",         "新溫層",        90, "D"),
  newSpec:         as("newSpec",         "新規格",       160, "D"),
  newReturnDays:   as("newReturnDays",   "新可退換天數", 120, "D"),
  newTaxRate:      as("newTaxRate",      "新稅率",        90, "D"),
};
const E_COLS = [
  as("approved",           "核可",           80, "E",  { formula: true }),
  as("createdAt",          "填寫日期",       110, "E",  { mono: true }),
  as("fillCheck",          "填寫檢查",       100, "E",  { formula: true }),
  as("promoCheck",         "促銷價檢查",     100, "E",  { formula: true }),
  as("dupStatusCheck",     "狀態重複檢查",   110, "E",  { formula: true }),
  as("eatOffersCheck",     "Eat Offers",     100, "E",  { formula: true }),
  as("fillDateCheck",      "填寫日期防呆",   110, "E",  { formula: true }),
  as("requiredFieldsCheck","應填寫欄位",     110, "E",  { formula: true }),
  as("rowId",              "Row ID",         100, "E",  { mono: true }),
  as("fillFieldIndex",     "填寫欄位索引",   100, "E",  { formula: true }),
  as("fillData",           "填寫資料",       120, "E",  { formula: true }),
  as("formatCheck",        "格式檢查",       100, "E",  { formula: true }),
  as("sameDayConflict",    "同天衝突檢查",   110, "E",  { formula: true }),
];
const F_COLS = [
  as("effectiveDate",      "生效日期",         110, "F",  { mono: true }),
  as("orderToolEffectDate","下單工具生效日期",  130, "F",  { mono: true }),
  as("regionChange",       "區域異動類型",      100, "F"),
];
const G_COLS = [
  ...ADJ_TRACKING_COLS({ group: "G", erpHint: "ERP 系統完成商品狀態調整後，由系統管理員手動勾選確認。" }),
];
const ACTION_COL = as("_action", "操作", 44, null, { actionCol: true });
const H_COLS = [
  as("rowStatus",    "審核狀態",  90, "H"),
  as("reviewPass",   "審核結果", 140, "H"),
  as("rejectReason", "退回原因", 200, "H"),
];

const AS_COL_GROUP_LABELS = {
  A: "A 商品識別",
  B: "B 主次類別",
  C: "C 目前狀態",
  D: "D 調整申請",
  E: "E 系統驗證",
  F: "F 生效追蹤",
  G: "G 後續處理",
  H: "H 審核",
};

// Build full column list dynamically based on batch D condition cols
function buildFullCols(batch, isReview) {
  const condKeys = getCondColKeys(batch.rows);
  const condCols = condKeys.map(k => ALL_D_COND_COL_DEFS[k]).filter(Boolean);
  const base = [...A_COLS, ...B_COLS, ...C_COLS, ...D_BASE_COLS, ...condCols, ...E_COLS, ...F_COLS, ...G_COLS];
  return isReview ? [...base, ...H_COLS] : [...base, ACTION_COL];
}

// Compact key set (dynamic based on batch D cond cols)
function getCompactKeySet(batch, isReview, role) {
  const condKeys = getCondColKeys(batch.rows);
  if (role === "samantha") {
    return new Set(["#", "barcode", "productName", "adjType", "rowStatus", "erpUpdated"]);
  }
  if (!isReview) {
    return new Set(["#", "barcode", "productName", "adjType", "adjNote", ...condKeys, "_action"]);
  }
  return new Set(["#", "barcode", "productName", "adjType", "adjNote", ...condKeys, "rowStatus", "reviewPass", "rejectReason"]);
}

// ── AdjTypeSelector — thin wrapper around PortalSelect ───────────────────────
const AdjTypeSelector = ({ value = [], onChange }) => {
  const opts = [...STATUS_ADJ_TYPES, ...INFO_ADJ_TYPES];
  const selected = Array.isArray(value) ? (value[0] || "") : (value || "");
  return (
    <PortalSelect
      value={selected}
      options={opts}
      multi={false}
      onChange={v => onChange(v ? [v] : [])}
      placeholder="選擇申請事項"
      searchPlaceholder="搜尋申請事項…"
      triggerClassName="adjtype-trigger"
    />
  );
};

// ── thLabel helper ────────────────────────────────────────────────────────────
const thLabel = (c) => c.info ? <InfoTip label={c.label} text={c.info} /> : c.label;

// ── AdjStatusMetaCard ─────────────────────────────────────────────────────────
const AdjStatusMetaCard = ({ batch }) => {
  const agg = computeAggStatus(batch);
  const statusText = agg.type === "single" ? (STATUS[agg.key]?.label || agg.key) : "混合審核狀態";
  const summary = `${batch.batchName} · ${batch.applicant} · ${batch.rows.length} 品項 · ${statusText}`;
  return (
    <MetaCard summary={summary} sectionTitle="批次資訊">
      <div className="meta-card__row"><dt>批次名稱</dt><dd>{batch.batchName}</dd></div>
      <div className="meta-card__row"><dt>申請人</dt><dd>{batch.applicant}</dd></div>
      <div className="meta-card__row"><dt>模組</dt><dd>商品狀態調整</dd></div>
      <div className="meta-card__row"><dt>品項數</dt><dd>{batch.rows.length}</dd></div>
      <div className="meta-card__row"><dt>批次狀態</dt><dd><AggStatusDisplay batch={batch} /></dd></div>
      <div className="meta-card__row"><dt>建立時間</dt><dd className="mono">{batch.createdAt}</dd></div>
      <div className="meta-card__row"><dt>更新時間</dt><dd className="mono">{batch.updatedAt}</dd></div>
    </MetaCard>
  );
};

// ── JoannaReviewConfirmView（送出審核確認頁）─────────────────────────────────
const AdjStatusJoannaConfirmView = ({ batch, reviewDrafts, onBack, onConfirm }) => {
  const draftedRows = batch.rows.filter(r => reviewDrafts[r.uid]);
  const fmtAdjType = (adjType) => {
    if (!adjType) return "—";
    if (Array.isArray(adjType)) return adjType.join("、");
    return String(adjType);
  };
  return (
    <SubmitConfirmPage
      moduleName="商品狀態調整" batchName={batch.batchName}
      pageTitle="送出審核"
      subtitle={`請確認以下 ${draftedRows.length} 筆品項的審核結果，送出後申請人將收到通知；退回的品項可重新送出。`}
      confirmLabel="確認送出"
      onBack={onBack} onConfirm={onConfirm}>
      <div className="card">
        <div className="tbl-wrap">
          <table className="tbl" style={{ borderCollapse: "separate", borderSpacing: 0 }}>
            <thead>
              <tr>
                <th style={{ width: 48, position: "sticky", left: 0, zIndex: 2 }}>#</th>
                <th style={{ width: 200, position: "sticky", left: 48, zIndex: 2, boxShadow: "2px 0 4px rgba(0,0,0,.06)" }}>品號 / 品名</th>
                <th style={{ width: 200 }}>申請事項</th>
                <th style={{ width: 100 }}>審核結果</th>
                <th style={{ width: 200 }}>退回原因</th>
              </tr>
            </thead>
            <tbody>
              {draftedRows.map((row, idx) => {
                const d = reviewDrafts[row.uid];
                const isPass = d.reviewPass === "yes";
                return (
                  <tr key={row.uid}>
                    <td style={{ textAlign: "center", color: "var(--fg-3)", position: "sticky", left: 0, background: "var(--bg-surface)", zIndex: 1 }}>{idx + 1}</td>
                    <td style={{ position: "sticky", left: 48, background: "var(--bg-surface)", zIndex: 1, boxShadow: "2px 0 4px rgba(0,0,0,.06)" }}>
                      <div className="mono" style={{ fontSize: 12 }}>{row.barcode}</div>
                      <div style={{ fontSize: 11, color: "var(--fg-3)", marginTop: 2 }}>{row.productName || row.name}</div>
                    </td>
                    <td style={{ color: "var(--fg-2)" }}>{fmtAdjType(row.adjType)}</td>
                    <td style={{ color: isPass ? "var(--tag-approved-fg)" : "var(--danger)", fontWeight: 600 }}>
                      {isPass ? "✓ 通過" : "✗ 退回"}
                    </td>
                    <td style={{ color: "var(--fg-2)" }}>{d.rejectReason || <span style={{ color: "var(--fg-4)" }}>—</span>}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </SubmitConfirmPage>
  );
};

// ── BulkApproveView ───────────────────────────────────────────────────────────
const AdjStatusBulkApproveView = ({ batch, onBack, onConfirm }) => {
  const pendingRows = batch.rows.filter(r => r.rowStatus === "adjPending");
  return (
    <SubmitConfirmPage
      moduleName="商品狀態調整" batchName={batch.batchName}
      pageTitle="批准確認"
      subtitle={`確認以下 ${pendingRows.length} 筆品項批准通過，送出後無法撤回。`}
      confirmLabel="確認批准"
      onBack={onBack} onConfirm={onConfirm}>
      <div className="card">
        <div className="tbl-wrap">
          <table className="tbl" style={{ borderCollapse: "separate", borderSpacing: 0 }}>
            <thead>
              <tr>
                <th style={{ width: 40, textAlign: "center" }}>#</th>
                <th style={{ minWidth: 160 }}>品號</th>
                <th style={{ minWidth: 200 }}>品名</th>
                <th style={{ minWidth: 180 }}>申請事項</th>
                <th style={{ width: 80 }}>審核狀態</th>
              </tr>
            </thead>
            <tbody>
              {pendingRows.map((row, idx) => (
                <tr key={row.uid}>
                  <td style={{ textAlign: "center", color: "var(--fg-3)" }}>{idx + 1}</td>
                  <td className="mono">{row.barcode}</td>
                  <td>{row.productName}</td>
                  <td>{(Array.isArray(row.adjType) ? row.adjType : [row.adjType]).map(v => ADJTYPE_LABELS[v] || v).join(" · ")}</td>
                  <td><Tag status={row.rowStatus} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </SubmitConfirmPage>
  );
};

// ── DoubleCheckView ───────────────────────────────────────────────────────────
const AdjStatusDoubleCheckView = ({ batch, condColKeys, onBack, onConfirm }) => {
  const rows = batch.rows;
  const [sysChecked, setSysChecked] = useState(false);

  const checks   = useMemo(() => rows.map(r => sysCheckRow(r)), [rows]);
  const errCount = checks.filter(c => !c.pass).length;
  const allPass  = rows.length > 0 && errCount === 0;

  const handleConfirm = () => {
    setSysChecked(true);
    if (allPass) onConfirm();
  };

  const handleBack = () => {
    if (sysChecked && !allPass) {
      const errMap = {};
      rows.forEach((r, i) => { if (!checks[i].pass) errMap[r.uid] = checks[i].msg; });
      onBack(errMap);
    } else {
      onBack(null);
    }
  };

  return (
    <SubmitConfirmPage
      moduleName="商品狀態調整" batchName={batch.batchName}
      subtitle={sysChecked && !allPass
        ? "系統檢查未通過，請修正後重新送出。"
        : "請確認以下品項的調整內容無誤，確認後將進行系統檢查並送審。"
      }
      onBack={handleBack} onConfirm={handleConfirm}
      confirmDisabled={sysChecked && !allPass}
    >
      {sysChecked && !allPass && (
        <ImportBanner
          phase="error"
          titlePrefix="系統檢查："
          titleSuffix="品項需要修正"
          desc="請修正後點擊「返回修改」，重新送出。"
          errorCount={errCount}
        />
      )}
      <div className="card">
        <div className="tbl-wrap">
          <table className="tbl" style={{ borderCollapse: "separate", borderSpacing: 0 }}>
            <thead>
              <tr>
                <th style={{ width: 40, textAlign: "center" }}>#</th>
                <th style={{ minWidth: 160 }}>品號</th>
                <th style={{ minWidth: 200 }}>品名</th>
                <th style={{ minWidth: 180 }}>申請事項</th>
                {condColKeys.map(k => (
                  <th key={k} style={{ minWidth: 120 }}>{ALL_D_COND_COL_DEFS[k]?.label || k}</th>
                ))}
                <th style={{ minWidth: 160 }}>商品調整備註</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((row, idx) => (
                <tr key={row.uid}>
                  <td style={{ textAlign: "center", color: "var(--fg-3)", position: "relative" }}>
                    {sysChecked && !checks[idx].pass && <RowErrTip msg={checks[idx].msg} />}
                    {idx + 1}
                  </td>
                  <td className="mono">{row.barcode}</td>
                  <td>{row.productName}</td>
                  <td>
                    {(Array.isArray(row.adjType) ? row.adjType : [row.adjType]).map(v => ADJTYPE_LABELS[v] || v).join(" · ")}
                  </td>
                  {condColKeys.map(k => {
                    const nonApplicable = isCellNonApplicable(k, row);
                    const v = row[k];
                    const col = ALL_D_COND_COL_DEFS[k];
                    const fmt = (col?.mono && typeof v === "number" && v > 0) ? `NT$${v.toLocaleString("zh-TW")}` : v;
                    return (
                      <td key={k} style={{ color: nonApplicable ? "var(--fg-4)" : "inherit" }}>
                        {nonApplicable ? "—" : (fmt || <span style={{ color: "var(--fg-4)" }}>—</span>)}
                      </td>
                    );
                  })}
                  <td style={{ color: "var(--fg-2)" }}>{row.adjNote || <span style={{ color: "var(--fg-4)" }}>—</span>}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </SubmitConfirmPage>
  );
};


// ── Main AdjStatusDetail ──────────────────────────────────────────────────────
const AdjStatusDetail = ({ batch, role, onBack, onPatchBatch, onSubmitBatch, onDeleteBatch, onDirtyChange }) => {
  const [tableMode, setTableMode]   = useState("compact");
  const [pageMode, setPageMode]     = useState("view");
  const [selectedRows, setSelectedRows] = useState(new Set());
  const [dirty, setDirty]           = useState(false);
  const [reviewDrafts, setReviewDrafts] = useState({});
  const [editingCell, setEditingCell] = useState(null);
  const [fAdjType, setFAdjType]     = useState([]);
  const [fRowStatus, setFRowStatus] = useState([]);
  const [fErpStatus, setFErpStatus] = useState([]);
  const { push: toast }             = useToast();

  useEffect(() => { onDirtyChange?.(dirty); }, [dirty, onDirtyChange]);
  useEffect(() => () => onDirtyChange?.(false), [onDirtyChange]);

  const isReview   = batch.submitted;
  const canEdit    = !batch.submitted || batch.rows.some(r => r.rowStatus === "adjRejected");
  const hasRejected = batch.rows.some(r => r.rowStatus === "adjRejected");

  // ── Column computation (dynamic) ─────────────────────────────────────────
  const fullCols = useMemo(() => buildFullCols(batch, isReview), [batch, isReview]);
  const condColKeys = useMemo(() => getCondColKeys(batch.rows), [batch.rows]);

  const visibleCols = useMemo(() => {
    if (tableMode === "full") return fullCols;
    const keys = getCompactKeySet(batch, isReview, role);
    return fullCols.filter(c => keys.has(c.key));
  }, [tableMode, fullCols, batch, isReview, role]);

  // ── Row selection ─────────────────────────────────────────────────────────
  const toggleRow = (uid) => setSelectedRows(s => {
    const next = new Set(s); next.has(uid) ? next.delete(uid) : next.add(uid); return next;
  });
  const toggleAll = (checked) =>
    setSelectedRows(checked ? new Set(batch.rows.map(r => r.uid)) : new Set());
  const deleteSelected = () => {
    selectedRows.forEach(uid => onPatchBatch(batch.id, uid, "_deleteRow", null));
    setSelectedRows(new Set());
    setDirty(true);
  };

  // ── Row status filter ─────────────────────────────────────────────────────
  const statusOptions = useMemo(() => {
    if (!isReview) return [];
    const seen = new Set(batch.rows.map(r => r.rowStatus).filter(Boolean));
    return [
      { value: "adjPending",  label: "待審核" },
      { value: "adjApproved", label: "審核通過" },
      { value: "adjRejected", label: "已退回" },
    ].filter(o => seen.has(o.value));
  }, [batch.rows, isReview]);

  const adjTypeChipOptions = useMemo(() => {
    const allTypes = [...new Set(batch.rows.flatMap(r =>
      Array.isArray(r.adjType) ? r.adjType : r.adjType ? [r.adjType] : []
    ))];
    return allTypes.map(t => ({ value: t, label: ADJTYPE_LABELS[t] || t }));
  }, [batch.rows]);

  const filteredRows = useMemo(() => {
    let rows = batch.rows;
    if (fAdjType.length > 0)
      rows = rows.filter(r => {
        const types = Array.isArray(r.adjType) ? r.adjType : r.adjType ? [r.adjType] : [];
        return types.some(t => fAdjType.includes(t));
      });
    if (isReview && fRowStatus.length > 0)
      rows = rows.filter(r => fRowStatus.includes(r.rowStatus));
    if (role === "samantha" && fErpStatus.length > 0)
      rows = rows.filter(r => {
        if (r.rowStatus !== "adjApproved") return false;
        const pending = !r.erpUpdated;
        return fErpStatus.some(v => v === "erpPending" ? pending : !pending);
      });
    return rows;
  }, [batch.rows, fAdjType, isReview, role, fRowStatus, fErpStatus]);

  const useGroups = visibleCols.length >= 10;
  const chkOffset = !batch.submitted ? 28 : 0;
  const totalWidth = chkOffset + visibleCols.reduce((s, c) => s + c.w, 0);

  // ── autoFillFromMaster ────────────────────────────────────────────────────
  const autoFillFromMaster = useCallback((barcode) => {
    const master = PRODUCT_MASTER.find(p => p.barcode === barcode);
    if (!master) return {};
    return {
      productName:  master.name,
      supplierNo:   master.supplierNo,
      supplierName: master.supplierName,
      mainCat:      master.mainCat,
      subCat:       master.subCat,
      saleStatus:   master.saleStatus || "normal",
      taxType:      master.taxRate || "應稅",
      tier:         master.tier || "",
      region:       master.region || "",
      specSummary:  master.specSummary || "",
      expType:      master.expType || "",
      origin:       master.origin || "",
    };
  }, []);

  // ── Row patching ──────────────────────────────────────────────────────────
  const patchRow = (uid, key, value) => {
    if (key !== "erpUpdated" && key !== "reviewPass" && key !== "rejectReason") setDirty(true);
    const now = new Date();
    const stamp = now.getFullYear().toString()
      + String(now.getMonth() + 1).padStart(2, "0")
      + String(now.getDate()).padStart(2, "0") + " "
      + String(now.getHours()).padStart(2, "0") + ":"
      + String(now.getMinutes()).padStart(2, "0");
    if (key === "barcode") {
      const filled = autoFillFromMaster(value);
      onPatchBatch(batch.id, uid, "_multiPatch", { barcode: value, ...filled, updatedAt: stamp });
    } else {
      onPatchBatch(batch.id, uid, key, value);
    }
  };

  const addRow = () => {
    setDirty(true);
    const uid = "as-r" + Math.random().toString(36).slice(2, 9);
    const now = new Date();
    const stamp = now.getFullYear().toString()
      + String(now.getMonth() + 1).padStart(2, "0")
      + String(now.getDate()).padStart(2, "0") + " "
      + String(now.getHours()).padStart(2, "0") + ":"
      + String(now.getMinutes()).padStart(2, "0");
    onPatchBatch(batch.id, null, "_addRow", {
      uid, barcode: "", productName: "", supplierNo: "", supplierName: "",
      mainCat: "", subCat: "", saleStatus: "normal", taxType: "應稅",
      tier: "", region: "", specSummary: "", expType: "", origin: "",
      adjType: [], adjNote: "",
      newBarcode: "", newMainCat: "", newSubCat: "", newName: "",
      newDescription: "", newListPrice: 0, newSuggestPrice: 0,
      newTier: "", newRegion: "", newTemp: "", newSpec: "", newReturnDays: "",
      approved: "", fillCheck: "", promoCheck: "", dupStatusCheck: "",
      eatOffersCheck: "", fillDateCheck: "", requiredFieldsCheck: "",
      rowId: uid, fillFieldIndex: "", fillData: "", formatCheck: "", sameDayConflict: "",
      effectiveDate: "", orderToolEffectDate: "", regionChange: "",
      erpUpdated: false, oracleUpdated: false, menuUpdated: false,
      rowStatus: "", reviewPass: "", rejectReason: "",
      createdAt: stamp, updatedAt: stamp,
    });
  };

  const deleteRow = (uid) => { setDirty(true); onPatchBatch(batch.id, uid, "_deleteRow", null); };

  // ── Submit flow ───────────────────────────────────────────────────────────
  const handleSaveDraft = () => {
    setDirty(false);
    toast({ kind: "success", msg: "草稿已儲存" });
  };
  const [sysCheckErrMap, setSysCheckErrMap] = useState(null);
  const { showErrors, submitGuard } = useFormValidation(batch.rows, AS_FORM_FIELDS, "送審");
  const handleSend = () => submitGuard(() => { setSysCheckErrMap(null); setPageMode("doubleCheck"); });
  const handleDoubleCheckBack = (errMap) => {
    if (errMap) setSysCheckErrMap(errMap);
    setPageMode("view");
  };
  const handleSysCheckConfirm = () => {
    onSubmitBatch(batch.id);
    setSysCheckErrMap(null);
    setPageMode("view");
    toast({ kind: "success", msg: "已送審，待審核" });
  };
  const handleResubmit = () => submitGuard(() => {
    onPatchBatch(batch.id, null, "_resubmit", null);
    setPageMode("doubleCheck");
  });
  const handleBulkApproveConfirm = () => {
    batch.rows
      .filter(r => r.rowStatus === "adjPending")
      .forEach(r => onPatchBatch(batch.id, r.uid, "_multiPatch", { rowStatus: "adjApproved", reviewPass: "yes" }));
    setReviewDrafts({});
    setDirty(false);
    setPageMode("view");
    toast({ kind: "success", msg: "已全部批准" });
  };

  const handleJoannaReviewConfirm = () => {
    Object.entries(reviewDrafts).forEach(([uid, draft]) => {
      onPatchBatch(batch.id, uid, "_multiPatch", {
        rowStatus: draft.reviewPass === "yes" ? "adjApproved" : "adjRejected",
        reviewPass: draft.reviewPass,
        rejectReason: draft.rejectReason || "",
      });
    });
    setReviewDrafts({});
    setDirty(false);
    setPageMode("view");
    toast({ kind: "success", msg: "審核結果已送出" });
  };

  // ── page__actions ─────────────────────────────────────────────────────────
  const hasPendingRows = batch.rows.some(r => r.rowStatus === "adjPending");
  const hasDraftRejections = Object.values(reviewDrafts).some(d => d.reviewPass === "no");

  const renderPageActions = () => {
    if (canActAsPurchase(role)) {
      if (!batch.submitted && canEdit) return (
        <>
          <Button variant="secondary" onClick={handleSaveDraft}>儲存草稿</Button>
          <Button variant="primary" icon="send" disabled={batch.rows.length === 0} onClick={handleSend}>送審</Button>
        </>
      );
      if (hasRejected) return (
        <>
          <Button variant="secondary" onClick={handleSaveDraft}>儲存草稿</Button>
          <Button variant="primary" icon="send" onClick={handleResubmit}>重新送出</Button>
        </>
      );
    }
    if (canActAsJoanna(role) && hasPendingRows) return (
      <Button variant="primary" icon="send"
        onClick={() => setPageMode(hasDraftRejections ? "joannaReviewConfirm" : "bulkApprove")}>
        {hasDraftRejections ? "送出" : "全部批准"}
      </Button>
    );
    return null;
  };

  // ── Cell rendering ────────────────────────────────────────────────────────
  const renderCell = (col, row, idx) => {
    const k = col.key;
    const isRowEditable = canActAsPurchase(role) && (!batch.submitted || row.rowStatus === "adjRejected");
    const canReview    = canActAsJoanna(role);
    const canErpUpdate = role === "samantha" && row.rowStatus === "adjApproved";
    const nonApplicable = isCellNonApplicable(k, row);

    // ── Sticky & special cols ──────────────────────────────────────────────
    if (k === "#") return (
      <td key={k} className="sticky-num" style={{ textAlign: "center", color: "var(--fg-3)", position: "sticky", left: chkOffset, background: "var(--bg-surface)", zIndex: 1, padding: "0 4px" }}>
        {idx + 1}
      </td>
    );

    if (k === "barcode") return (
      <td key={k} style={{ position: "sticky", left: chkOffset + NUM_COL_W, background: "var(--bg-surface)", zIndex: 1, boxShadow: "2px 0 4px rgba(0,0,0,.06)" }}>
        {isRowEditable
          ? <CellEditor alwaysOn field={{ type: "text", key: "barcode", label: "品號", mono: true }} value={row.barcode} row={row}
              onCommit={val => patchRow(row.uid, "barcode", val)} />
          : <span className="mono" style={{ fontSize: 12, padding: "0 8px" }}>{row.barcode || <span style={{ color: "var(--fg-4)" }}>—</span>}</span>
        }
      </td>
    );

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

    // ── saleStatus badge ───────────────────────────────────────────────────
    if (k === "saleStatus") {
      const ss = row.saleStatus;
      const bad = ss === "outOfStock" || ss === "discontinued";
      return (
        <td key={k}>
          {ss
            ? <span style={{ fontSize: 11, padding: "1px 6px", borderRadius: 2,
                background: bad ? "var(--danger-bg)" : "var(--success-bg)",
                color: bad ? "var(--danger)" : "var(--tag-approved-fg)" }}>
                {SALE_STATUS_LABELS[ss] || ss}
              </span>
            : <span style={{ color: "var(--fg-4)" }}>—</span>
          }
        </td>
      );
    }

    // ── adjType ────────────────────────────────────────────────────────────
    if (k === "adjType") {
      const types = Array.isArray(row.adjType) ? row.adjType : row.adjType ? [row.adjType] : [];
      if (!isRowEditable) {
        return (
          <td key={k} style={{ padding: "4px 8px" }}>
            {types.length === 0
              ? <span style={{ color: "var(--fg-4)" }}>—</span>
              : types.map(v => ADJTYPE_LABELS[v] || v).join(" · ")
            }
          </td>
        );
      }
      return (
        <td key={k} style={{ padding: "4px 6px", verticalAlign: "middle" }}>
          <ErrWrap errMsg={showErrors ? AS_FLD_ADJ_TYPE.validate(row) : null}>
            <AdjTypeSelector value={types} onChange={val => patchRow(row.uid, "adjType", val)} />
          </ErrWrap>
        </td>
      );
    }

    // ── adjNote ────────────────────────────────────────────────────────────
    if (k === "adjNote") {
      if (!isRowEditable) return <td key={k} style={{ padding: "0 8px" }}><TruncCell text={row.adjNote || ""} /></td>;
      return (
        <td key={k}>
          <CellEditor alwaysOn field={{ type: "text", key: "adjNote", label: "備註" }} value={row.adjNote} row={row}
            onCommit={val => patchRow(row.uid, "adjNote", val)} />
        </td>
      );
    }

    // ── D condition editable cols ──────────────────────────────────────────
    if (D_COND_COL_TYPES[k]) {
      if (nonApplicable) {
        return <td key={k} style={{ fontSize: 11, color: "var(--fg-4)", textAlign: "center" }}>—</td>;
      }
      if (!isRowEditable) {
        const v = row[k];
        const isNum = col.mono && typeof v === "number";
        return (
          <td key={k} style={{ padding: "0 8px" }}>
            {v
              ? (isNum && v > 0
                  ? `NT$${v.toLocaleString("zh-TW")}`
                  : col.mono
                  ? v
                  : <TruncCell text={String(v)} />)
              : <span style={{ color: "var(--fg-4)" }}>—</span>}
          </td>
        );
      }
      const isNum = col.mono;
      const fld = { type: isNum ? "number" : "text", key: k, label: col.label, mono: isNum, validate: (r) => !r[k] ? "必填" : null };
      return (
        <td key={k}>
          <CellEditor alwaysOn field={fld} value={row[k]} row={row}
            onCommit={val => patchRow(row.uid, k, val)} />
        </td>
      );
    }

    // ── Formula 🔒 fields (specSummary + E group) ─────────────────────────
    if (col.formula) {
      const v = row[k];
      return (
        <td key={k} className="cell-formula-val" style={{ fontSize: 11, padding: "0 8px" }}>
          {v || <span style={{ color: "var(--fg-4)" }}>—</span>}
        </td>
      );
    }

    // ── F group: effectiveDate, orderToolEffectDate, regionChange ──────────
    if (k === "effectiveDate" || k === "orderToolEffectDate" || k === "regionChange") {
      return <td key={k} className="mono" style={{ fontSize: 11, color: "var(--fg-3)", padding: "0 8px" }}>{row[k] || "—"}</td>;
    }

    // ── G group: erp（Samantha 手動勾選）/ oracle / menu（系統自動）追蹤欄，共用元件渲染 ──
    const _trk = renderAdjTrackingCell(k, row, { canErpUpdate, patchRow });
    if (_trk) return _trk;

    // ── H group: review cols ──────────────────────────────────────────────
    if (k === "rowStatus") {
      return <td key={k}>{row.rowStatus ? <Tag status={row.rowStatus} /> : <span style={{ color: "var(--fg-4)" }}>—</span>}</td>;
    }
    if (k === "reviewPass") {
      const isPending = row.rowStatus === "adjPending";
      const draftPass = reviewDrafts[row.uid]?.reviewPass;
      if (canReview && isPending) {
        return (
          <td key={k}>
            <div className="review-pass-ctrl">
              <button className={"review-pass-btn review-pass-btn--yes" + (draftPass === "yes" ? " active" : "")}
                onClick={() => { setReviewDrafts(d => ({ ...d, [row.uid]: { ...(d[row.uid] || {}), reviewPass: "yes" } })); setDirty(true); }}>✓ 通過</button>
              <button className={"review-pass-btn review-pass-btn--no" + (draftPass === "no" ? " active" : "")}
                onClick={() => { setReviewDrafts(d => ({ ...d, [row.uid]: { ...(d[row.uid] || {}), reviewPass: "no" } })); setDirty(true); }}>✗ 退回</button>
            </div>
          </td>
        );
      }
      if (row.reviewPass === "yes") return <td key={k} style={{ color: "var(--tag-approved-fg)", fontWeight: 600 }}>✓ 通過</td>;
      if (row.reviewPass === "no")  return <td key={k} style={{ color: "var(--danger)", fontWeight: 600 }}>✗ 退回</td>;
      return <td key={k} style={{ color: "var(--fg-4)" }}>—</td>;
    }
    if (k === "rejectReason") {
      const isPending = row.rowStatus === "adjPending";
      const showInput = canReview && isPending && reviewDrafts[row.uid]?.reviewPass === "no";
      if (showInput) {
        return (
          <td key={k}>
            <Textarea variant="reject" rows={2}
              placeholder="請填寫退回原因…"
              value={reviewDrafts[row.uid]?.rejectReason ?? ""}
              onChange={e => { setReviewDrafts(d => ({ ...d, [row.uid]: { ...(d[row.uid] || {}), rejectReason: e.target.value } })); setDirty(true); }} />
          </td>
        );
      }
      return (
        <td key={k}>
          <TruncCell text={row.rejectReason || ""} style={{ color: row.rejectReason ? "var(--danger)" : "var(--fg-4)" }} />
        </td>
      );
    }

    // ── Generic readonly ──────────────────────────────────────────────────
    const v = row[k];
    return (
      <td key={k} style={{ padding: "0 8px" }}>
        {v !== undefined && v !== "" && v !== null
          ? (col.mono ? <span className="mono">{v}</span> : <TruncCell text={String(v)} />)
          : <span style={{ color: "var(--fg-4)" }}>—</span>
        }
      </td>
    );
  };

  // ── Row CSS class ─────────────────────────────────────────────────────────
  const rowClass = (row) => {
    const isPending = row.rowStatus === "adjPending";
    const draftPass = isPending ? reviewDrafts[row.uid]?.reviewPass : undefined;
    if (draftPass === "yes") return "adj-row--approved";
    if (draftPass === "no")  return "adj-row--rejected";
    if (row.rowStatus === "adjApproved") return "adj-row--approved";
    if (row.rowStatus === "adjRejected") return "adj-row--rejected";
    if (row.rowStatus === "adjPending")  return "adj-row--pending";
    return "";
  };

  // ── Transient page modes ──────────────────────────────────────────────────
  if (pageMode === "bulkApprove") {
    return <AdjStatusBulkApproveView batch={batch} onBack={() => setPageMode("view")} onConfirm={handleBulkApproveConfirm} />;
  }
  if (pageMode === "joannaReviewConfirm") {
    return (
      <AdjStatusJoannaConfirmView
        batch={batch}
        reviewDrafts={reviewDrafts}
        onBack={() => setPageMode("view")}
        onConfirm={handleJoannaReviewConfirm}
      />
    );
  }
  if (pageMode === "doubleCheck") {
    return <AdjStatusDoubleCheckView batch={batch} condColKeys={condColKeys} onBack={handleDoubleCheckBack} onConfirm={handleSysCheckConfirm} />;
  }

  // ── Main view ─────────────────────────────────────────────────────────────
  const aggStatus = computeAggStatus(batch);
  return (
    <>
      <PageHead
        crumbs={[
          { label: "商品調整" },
          { label: "商品主檔調整", onClick: onBack },
          { label: batch.batchName, current: true },
        ]}
        title={<>{batch.batchName} <AggStatusDisplay batch={batch} /></>}
        dirty={dirty}
        actions={renderPageActions()}
      />

      <AdjStatusMetaCard batch={batch} />

      {!batch.submitted && 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)}
        />
      )}

      {(adjTypeChipOptions.length > 1 || (isReview && statusOptions.length > 0) || role === "samantha") && (
        <div className="filter-bar">
          {adjTypeChipOptions.length > 1 && (
            <ChipFilter label="申請事項" value={fAdjType} options={adjTypeChipOptions} onChange={v => setFAdjType(v)} multi />
          )}
          {isReview && statusOptions.length > 0 && (
            <ChipFilter label="審核狀態" value={fRowStatus} options={statusOptions} onChange={v => setFRowStatus(v)} multi />
          )}
          {role === "samantha" && (
            <ChipFilter label="ERP 狀態" value={fErpStatus}
              options={[
                { value: "erpPending", label: "ERP 待確認" },
                { value: "erpDone",    label: "ERP 已完成" },
              ]}
              onChange={v => setFErpStatus(v)} multi />
          )}
        </div>
      )}

      <div className="card">
        <SkuToolbar>
          {!batch.submitted && selectedRows.size > 0 ? (
            <BulkBar label={<>已選 <b>{selectedRows.size}</b> 筆品項</>} variant="danger">
              <Button variant="danger" size="sm" icon="trash" onClick={deleteSelected}>
                刪除已選 {selectedRows.size} 筆品項
              </Button>
              <Button variant="text" size="sm" onClick={() => setSelectedRows(new Set())}>取消選取</Button>
            </BulkBar>
          ) : (
            <>
              <ModeToggle mode={tableMode} onChange={setTableMode} />
              <span style={{ color: "var(--fg-2)", fontSize: 13, whiteSpace: "nowrap" }}>
                共 <b style={{ color: "var(--fg-1)" }}>{filteredRows.length}</b>
                {(fAdjType.length > 0 || fRowStatus.length > 0 || fErpStatus.length > 0) && <> / {batch.rows.length}</>} 筆
              </span>
              {!batch.submitted && (
                <Button variant="default" size="sm" icon="plus" onClick={addRow} style={{ marginLeft: "auto" }}>{ADD_LABEL}</Button>
              )}
            </>
          )}
        </SkuToolbar>
        {!batch.submitted && batch.rows.length === 0 ? (
          <EmptyState icon="sliders" title="尚無品項" desc="點「新增品項」開始輸入。">
            <Button variant="primary" icon="plus" onClick={addRow}>{ADD_LABEL}</Button>
          </EmptyState>
        ) : (
        <ShowErrorsProvider value={showErrors}>
        <>
        <div className="tbl-wrap">
          <table className="tbl adj-tbl" style={{ borderCollapse: "separate", borderSpacing: 0, width: "100%", minWidth: totalWidth }}>
            <colgroup>
              {!batch.submitted && <col style={{ minWidth: 28 }} />}
              {visibleCols.map(c => <col key={c.key} style={{ minWidth: c.w }} />)}
            </colgroup>
            <thead>
              {useGroups ? (() => {
                const numCol    = visibleCols.find(c => c.stickyNum);
                const actionCol = visibleCols.find(c => c.actionCol);
                const dataCols  = visibleCols.filter(c => !c.stickyNum && !c.actionCol);
                return (
                  <>
                    <TableGroupHeader
                      cols={dataCols}
                      groupLabels={AS_COL_GROUP_LABELS}
                      leadingSlot={<>
                        {!batch.submitted && (
                          <th rowSpan={2} style={{ width: 28, textAlign: "center", position: "sticky", left: 0, zIndex: 3, background: "var(--gray-50)", padding: 0 }}>
                            <input type="checkbox"
                              checked={batch.rows.length > 0 && batch.rows.every(r => selectedRows.has(r.uid))}
                              onChange={e => toggleAll(e.target.checked)} />
                          </th>
                        )}
                        {numCol && (
                          <th rowSpan={2} style={{ width: numCol.w, minWidth: numCol.w, position: "sticky", left: !batch.submitted ? 28 : 0, zIndex: 2, padding: "0 4px" }}>
                            {numCol.label}
                          </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: !batch.submitted ? 28 + NUM_COL_W : NUM_COL_W, zIndex: 2, boxShadow: "2px 0 4px rgba(0,0,0,.06)" }}>{thLabel(c)}</th>
                        );
                        return <th key={c.key} className={c.group === "H" ? "th-review-sub" : ""} style={s}>{thLabel(c)}</th>;
                      })}
                    </tr>
                  </>
                );
              })() : (
                <tr>
                  {!batch.submitted && (
                    <th style={{ width: 28, textAlign: "center", position: "sticky", left: 0, zIndex: 3, background: "var(--gray-50)", padding: 0 }}>
                      <input type="checkbox"
                        checked={batch.rows.length > 0 && batch.rows.every(r => selectedRows.has(r.uid))}
                        onChange={e => toggleAll(e.target.checked)} />
                    </th>
                  )}
                  {visibleCols.map(c => {
                    const bs = { width: c.w, minWidth: c.w };
                    if (c.stickyNum) return (
                      <th key={c.key} style={{ ...bs, position: "sticky", left: batch.submitted ? 0 : 28, zIndex: 2, padding: "0 4px" }}>{thLabel(c)}</th>
                    );
                    if (c.sticky2nd) return (
                      <th key={c.key} style={{ ...bs, position: "sticky", left: batch.submitted ? NUM_COL_W : 28 + NUM_COL_W, zIndex: 2, boxShadow: "2px 0 4px rgba(0,0,0,.06)" }}>{thLabel(c)}</th>
                    );
                    return <th key={c.key} className={c.group === "H" ? "th-review-sub" : ""} style={bs}>{thLabel(c)}</th>;
                  })}
                </tr>
              )}
            </thead>
            <tbody>
              {filteredRows.length === 0 && (
                <tr>
                  <td colSpan={visibleCols.length + (!batch.submitted ? 1 : 0) + 1}>
                    <div className="empty" style={{ padding: "40px 20px" }}>
                      <div className="empty__icon"><Icon name="sliders" size={32} /></div>
                      <div className="empty__title">沒有符合篩選條件的品項</div>
                      <div className="empty__desc">試試清除篩選條件。</div>
                    </div>
                  </td>
                </tr>
              )}
              {filteredRows.map((row, idx) => (
                <tr key={row.uid} className={rowClass(row)}>
                  {!batch.submitted && (
                    <td style={{ textAlign: "center", width: 28, position: "sticky", left: 0, background: "var(--bg-surface)", zIndex: 1, padding: 0 }}>
                      {sysCheckErrMap?.[row.uid] && <RowErrTip msg={sysCheckErrMap[row.uid]} />}
                      <input type="checkbox"
                        checked={selectedRows.has(row.uid)}
                        onChange={() => toggleRow(row.uid)} />
                    </td>
                  )}
                  {visibleCols.map(c => renderCell(c, row, idx))}
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {!batch.submitted && (
          <button className="tbl-add-row" onClick={addRow}>
            <Icon name="plus" size={16} /> 新增品項
          </button>
        )}
        </>
        </ShowErrorsProvider>
        )}

      </div>
    </>
  );
};

Object.assign(window, { AdjStatusDetail });
