/* global React, Icon, Button, Field, Tag, useToast, Dialog, ModeToggle, BulkBar, FIELDS, baseSku, PageHead, InfoNote, EmptyState, SkuToolbar, canActAsPurchase */
/* global FormMetaCard, SkuTable, ImportBanner */
// L2 — Creation-form detail: Excel-mode SKU table + meta card + import flow

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

// ===== Validation =====================================================
const validateSku = (row) => {
  const errs = {};
  for (const f of FIELDS) {
    if (!f.required) continue;
    if (f.showWhen) {
      const { mainCat, subCat } = f.showWhen;
      if (mainCat && !mainCat.includes(row.mainCat)) continue;
      if (subCat && !subCat.includes(row.subCat)) continue;
    }
    const v = row[f.key];
    if (v === "" || v == null) errs[f.key] = `${f.label}必填`;
  }
  if (row.barcode && !/^\d{8}$|^\d{12,14}$/.test(String(row.barcode))) {
    errs.barcode = "品號需為 8 / 12–14 碼數字";
  }
  if (row.cost && row.listPrice && Number(row.cost) >= Number(row.listPrice)) {
    errs.cost = "進價不可 ≥ 牌價";
  }
  if (row.name && row.name.length > 100) {
    errs.name = `品名不可超過 100 字（目前 ${row.name.length} 字）`;
  }
  return errs;
};

// ===== Excel hint =====================================================

// ===== Detail page ===================================================
const BatchDetail = ({ form, role, onBack, onSubmit, onPatch, onDelete, onDirtyChange }) => {
  const readOnly = form.status === "submitted" || !canActAsPurchase(role);
  const purchaseReadOnly = readOnly;

  const [mode, setMode] = useState("compact"); // "compact" | "full"
  const [importPhase, setImportPhase] = useState(null);
  const [importStats, setImportStats] = useState({ done: 0, total: 0, errorCount: 0 });
  const [errorMap, setErrorMap] = useState({});
  const [submitConfirm, setSubmitConfirm] = useState(false);
  const [submitConfirmText, setSubmitConfirmText] = useState("");
  const [submitError, setSubmitError] = useState(null);
  const [selectedSkus, setSelectedSkus] = useState(new Set());
  const [dirty, setDirty] = useState(false);
  const fileInputRef = useRef(null);
  const toast = useToast();

  useEffect(() => { onDirtyChange?.(dirty); }, [dirty, onDirtyChange]);
  useEffect(() => () => onDirtyChange?.(false), [onDirtyChange]);
  useEffect(() => { setSelectedSkus(new Set()); }, [form.id]);

  const skus = form.items;
  const errorRowCount = Object.keys(errorMap).filter(uid => Object.keys(errorMap[uid] || {}).length).length;

  // ----- Selection handlers ------
  const toggleRow = (uid) => {
    setSelectedSkus(s => {
      const next = new Set(s);
      next.has(uid) ? next.delete(uid) : next.add(uid);
      return next;
    });
  };
  const toggleAll = (checked) => {
    setSelectedSkus(checked ? new Set(skus.map(s => s.uid)) : new Set());
  };
  const deleteSelected = () => {
    selectedSkus.forEach(uid => onPatch(form.id, uid, "_delete", true));
    setSelectedSkus(new Set());
    setDirty(true);
  };

  // ----- Cell patch ------
  const patchCell = (uid, key, value) => {
    if (purchaseReadOnly) return;
    onPatch(form.id, uid, key, value);
    setDirty(true);
  };

  // ----- Add / Delete row ------
  const addRow = () => {
    if (purchaseReadOnly) return;
    onPatch(form.id, null, "_add", baseSku());
    setDirty(true);
  };
  const deleteRow = (uid) => {
    if (purchaseReadOnly) return;
    onPatch(form.id, uid, "_delete", true);
    setDirty(true);
  };

  // ----- Excel import ------
  const handleImport = () => { if (!purchaseReadOnly) fileInputRef.current?.click(); };
  const onFileChosen = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    e.target.value = "";
    runFakeImport(file.name);
  };
  const runFakeImport = (filename) => {
    setImportPhase("parsing");
    setSubmitError(null);
    const total = 12;
    setImportStats({ done: 0, total, errorCount: 0 });
    let done = 0;
    const tick = () => {
      done += 1;
      setImportStats(s => ({ ...s, done }));
      if (done < total) setTimeout(tick, 110);
      else finishImport(filename, total);
    };
    setTimeout(tick, 200);
    setDirty(true);
  };
  const finishImport = (filename, total) => {
    const newRows = Array.from({ length: total }).map((_, i) => baseSku({
      barcode: i === 2 ? "ABC" : (i === 5 ? "" : "4710" + String(100000 + Math.floor(Math.random() * 900000))),
      name: i === 7 ? "" : "賀氏起司條 範例 " + (i + 1),
      supplierName: "友暉", supplierNo: "120" + (100 + i),
      mainCat: "糖果零食", subCat: "洋芋片", brand: "賀氏",
      cost: i === 4 ? 200 : 116.67, listPrice: i === 4 ? 150 : 175,
      deliv: "統配", temp: "常溫", unit: "包", specNum: 170, specUnit: "公克",
      minOrder: 12, shelfDays: 365, expType: "日/月/年", origin: "美國", taxRate: "應稅",
      tier: "T2", region: "雙北", imported: "進口",
    }));
    onPatch(form.id, null, "_replace", newRows);
    const errs = {};
    newRows.forEach((r, i) => {
      const rowErrs = {};
      if (i === 2) rowErrs.barcode = "品號需為 8 / 12–14 碼數字";
      if (i === 5) rowErrs.barcode = "品號必填";
      if (i === 7) rowErrs.name = "品名必填";
      if (i === 4) rowErrs.cost = "進價不可 ≥ 牌價";
      if (Object.keys(rowErrs).length) errs[r.uid] = rowErrs;
    });
    setErrorMap(errs);
    const errorCount = Object.keys(errs).length;
    setImportStats({ done: total, total, errorCount });
    setImportPhase(errorCount > 0 ? "error" : "ok");
    toast.push({ msg: `已匯入 ${total} 筆，${errorCount > 0 ? errorCount + " 筆需修正" : "全部通過"}`,
      kind: errorCount > 0 ? "warning" : "success" });
  };

  // ----- Save draft ------
  const handleSaveDraft = () => {
    setDirty(false);
    toast.push({ msg: "已儲存草稿", kind: "success" });
  };

  // ----- Submit ------
  const askSubmit = () => {
    const allErrs = {};
    skus.forEach(s => {
      const e = validateSku(s);
      if (Object.keys(e).length) allErrs[s.uid] = e;
    });
    if (Object.keys(allErrs).length) {
      setErrorMap(allErrs);
      setSubmitError({ count: Object.keys(allErrs).length });
      setImportPhase(null);
      window.scrollTo({ top: 0, behavior: "smooth" });
      return;
    }
    setSubmitError(null);
    setSubmitConfirmText("");
    setSubmitConfirm(true);
  };
  const doSubmit = () => {
    setDirty(false);
    setSubmitError(null);
    setErrorMap({});
    toast.push({ msg: `${form.id} 建立單已送出，後續進行圖片上傳與 Oracle 匯出`, kind: "success" });
    onSubmit(form.id);
    setSubmitConfirm(false);
  };

  // ----- scroll to Nth error row ------
  const scrollToFirstError = (idx = 0) => {
    const seen = new Set();
    const errRows = [];
    document.querySelectorAll('.cell-err-msg').forEach(el => {
      const tr = el.closest('tr');
      if (tr && !seen.has(tr)) { seen.add(tr); errRows.push(tr); }
    });
    const target = errRows[idx % (errRows.length || 1)];
    target?.scrollIntoView({ block: "center", behavior: "smooth" });
  };

  return (
    <>
      {/* ── Page header ──────────────────────────────────────────────── */}
      <PageHead
        crumbs={[
          { label: "商品資料" },
          { label: "新商品建立單", onClick: onBack },
          { label: form.batch, current: true },
        ]}
        title={<>{form.batch} <Tag status={form.status} /></>}
        dirty={dirty}
        actions={<>
          {!purchaseReadOnly && (
            <>
              <Button variant="default" icon="download">下載匯入格式</Button>
              <Button variant="default" icon="upload" onClick={handleImport}>匯入 Excel</Button>
              <Button variant="default" onClick={handleSaveDraft} disabled={!dirty}>儲存草稿</Button>
              <Button variant="primary" icon="send" onClick={askSubmit}>送出（不可復原）</Button>
            </>
          )}
          {form.status === "submitted" && (
            <Button variant="default" icon="download">下載 Excel</Button>
          )}
        </>}
      />

      <input ref={fileInputRef} type="file" accept=".xlsx,.xls,.csv" style={{ display: "none" }} onChange={onFileChosen} />

      {/* ── FormMetaCard ─────────────────────────────────────────────── */}
      <FormMetaCard form={form} />

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

      {submitError && (
        <ImportBanner
          phase="error"
          titlePrefix="送出失敗，"
          titleSuffix="品項需要修正"
          desc="下方標紅的列有必填未填或格式錯誤，修正後請重新送出。"
          errorCount={submitError.count}
          onView={scrollToFirstError}
          onClose={() => setSubmitError(null)}
        />
      )}

      {/* ── SKU card ─────────────────────────────────────────────────── */}
      <div className="card sku-card">
        {/* Toolbar */}
        <SkuToolbar>
          {!purchaseReadOnly && selectedSkus.size > 0 ? (
            <BulkBar label={<>已選 <b>{selectedSkus.size}</b> 筆品項</>} variant="danger">
              <Button variant="danger" size="sm" icon="trash" onClick={deleteSelected}>
                刪除已選 {selectedSkus.size} 筆品項
              </Button>
              <Button variant="text" size="sm" onClick={() => setSelectedSkus(new Set())}>取消選取</Button>
            </BulkBar>
          ) : (
            <>
              {/* mode toggle — 最左 */}
              <ModeToggle mode={mode} onChange={setMode} />

              <span style={{ color: "var(--fg-3)", fontSize: 13, whiteSpace: "nowrap", flexShrink: 0 }}>
                共 <b style={{ color: "var(--fg-1)" }}>{skus.length}</b> 筆
              </span>
              {errorRowCount > 0 && (
                <span style={{ color: "var(--danger)", fontSize: 13, display: "inline-flex", alignItems: "center", gap: 4 }}>
                  <Icon name="alertCircle" size={13} /> {errorRowCount} 筆有錯誤
                </span>
              )}

              {!purchaseReadOnly && (
                <Button variant="default" size="sm" icon="plus" onClick={addRow}
                  style={{ marginLeft: "auto" }}>新增品項列</Button>
              )}
            </>
          )}
        </SkuToolbar>


        {/* SKU table */}
        {skus.length === 0 ? (
          <EmptyState icon="box" title="尚無品項" desc="用匯入 Excel 批量建立，或一筆一筆新增。">
            <Button variant="default" icon="download">下載匯入格式</Button>
            <Button variant="default" icon="upload" onClick={handleImport}>匯入 Excel</Button>
            <Button variant="primary" icon="plus" onClick={addRow}>新增品項列</Button>
          </EmptyState>
        ) : (
          <SkuTable
            skus={skus}
            role={role}
            readOnly={purchaseReadOnly}
            errorMap={errorMap}
            mode={mode}
            formStatus={form.status}
            onPatchCell={patchCell}
            onDeleteRow={deleteRow}
            onAddRow={!purchaseReadOnly ? addRow : null}
            onToast={(msg, kind) => toast.push({ msg, kind: kind || "success" })}
            selectedRows={selectedSkus}
            onToggleRow={!purchaseReadOnly ? toggleRow : null}
            onToggleAll={!purchaseReadOnly ? toggleAll : null}
          />
        )}
      </div>

      {/* ── Submit confirm dialog ─────────────────────────────────────── */}
      <Dialog open={submitConfirm} title="送出建立單" onClose={() => setSubmitConfirm(false)}
        footer={<>
          <Button variant="text" onClick={() => setSubmitConfirm(false)}>取消</Button>
          <Button variant="primary" disabled={submitConfirmText !== "送出"} onClick={doSubmit}>
            確認送出
          </Button>
        </>}>
        <div style={{ marginBottom: 12 }}>
          將 <b>{form.batch}</b>（{form.applicant}）的 <b>{form.items.length}</b> 筆品項送出。
        </div>
        <InfoNote variant="warning">
          <div>
            <div style={{ fontWeight: 600 }}>送出後此單將被鎖定，不能再編輯</div>
            <div style={{ color: "var(--fg-3)", fontSize: 12, marginTop: 2 }}>
              下一步：圖檔處理人員會匯出本單 Excel 補圖檔；Oracle 匯出人員會同步系統。
            </div>
          </div>
        </InfoNote>
        <div style={{ marginTop: 14 }}>
          <div className="lab" style={{ textAlign: "left", marginBottom: 4 }}>請輸入 <b>送出</b> 以確認：</div>
          <Field placeholder="送出" value={submitConfirmText} onChange={e => setSubmitConfirmText(e.target.value)} />
        </div>
      </Dialog>
    </>
  );
};

Object.assign(window, { BatchDetail });
