/* global React, Button, Field, Dialog, PageHead, Pager, FilterBar, PAGE_SIZES, useToast, useSortableTable, PortalSelect */

const { useState, useMemo } = React;

const BD_PAGE_CONFIG = {
  "bd-region": {
    defaultSort: "name",
    searchPlaceholder: "搜尋銷售地區名稱",
    addLabel: "新增銷售地區",
    editTitle: "編輯銷售地區",
    emptyTitle: "尚無銷售地區",
    cols: [{ key: "name", label: "銷售地區名稱" }],
    fields: [{ key: "name", label: "銷售地區名稱", required: true, dupKey: "name", dupMsg: "銷售地區名稱不可重複" }],
    searchKeys: ["name"],
  },
  "bd-store": {
    defaultSort: "storeNo",
    searchPlaceholder: "搜尋店號、門店名稱",
    addLabel: "新增門店",
    editTitle: "編輯門店",
    emptyTitle: "尚無門店",
    cols: [
      { key: "storeNo", label: "店號", mono: true },
      { key: "name", label: "門店名稱" },
      { key: "region", label: "銷售地區" },
    ],
    fields: [
      { key: "storeNo", label: "店號", required: true, dupKey: "storeNo", dupMsg: "店號不可重複" },
      { key: "name", label: "門店名稱", required: true, dupKey: "name", dupMsg: "門店名稱不可重複" },
      { key: "region", label: "銷售地區", type: "select", required: true },
    ],
    searchKeys: ["storeNo", "name"],
  },
  "bd-tier": {
    defaultSort: "name",
    searchPlaceholder: "搜尋品項分級名稱",
    addLabel: "新增品項分級",
    editTitle: "編輯品項分級",
    emptyTitle: "尚無品項分級",
    cols: [{ key: "name", label: "品項分級名稱" }],
    fields: [{ key: "name", label: "品項分級名稱", required: true, dupKey: "name", dupMsg: "品項分級名稱不可重複" }],
    searchKeys: ["name"],
  },
  "bd-temp": {
    defaultSort: "name",
    searchPlaceholder: "搜尋溫層名稱",
    addLabel: "新增溫層",
    editTitle: "編輯溫層",
    emptyTitle: "尚無溫層",
    cols: [{ key: "name", label: "溫層名稱" }],
    fields: [{ key: "name", label: "溫層名稱", required: true, dupKey: "name", dupMsg: "溫層名稱不可重複" }],
    searchKeys: ["name"],
  },
};

const BasedataFormDialog = ({ cfg, mode, initial, rows, regionOptions, onClose, onSave }) => {
  const empty = () => Object.fromEntries(cfg.fields.map(f => [f.key, ""]));
  const [form, setForm] = useState(mode === "edit" ? { ...initial } : empty());
  const [errors, setErrors] = useState({});

  const setField = (key, val) => {
    setForm(prev => ({ ...prev, [key]: val }));
    setErrors(prev => ({ ...prev, [key]: "" }));
  };

  const handleSave = () => {
    const nextErr = {};
    cfg.fields.forEach(f => {
      const v = String(form[f.key] ?? "").trim();
      if (f.required && !v) nextErr[f.key] = `請輸入${f.label}`;
      if (f.dupKey && v) {
        const dup = rows.some(r => r.id !== initial?.id && String(r[f.dupKey]).trim() === v);
        if (dup) nextErr[f.key] = f.dupMsg;
      }
    });
    if (Object.keys(nextErr).length) { setErrors(nextErr); return; }
    onSave(form);
  };

  return (
    <Dialog
      open
      title={mode === "add" ? cfg.addLabel : cfg.editTitle}
      onClose={onClose}
      footer={<>
        <Button variant="text" onClick={onClose}>取消</Button>
        <Button variant="primary" onClick={handleSave}>確認</Button>
      </>}
    >
      {cfg.fields.map(f => (
        <div key={f.key} className="dialog__field-row">
          <span className={"dialog__field-label" + (f.required ? " dialog__field-label--req" : "")}>{f.label}</span>
          <div className="dialog__field-body">
            {f.type === "select" ? (
              <PortalSelect
                value={form[f.key] || null}
                options={(regionOptions || []).map(r => ({ value: r, label: r }))}
                onChange={v => setField(f.key, v)}
                triggerClassName="field-trigger"
                triggerStyle={{ width: "100%" }}
              />
            ) : (
              <Field
                value={form[f.key] || ""}
                onChange={e => setField(f.key, e.target.value)}
                onKeyDown={e => { if (e.key === "Enter") handleSave(); if (e.key === "Escape") onClose(); }}
                placeholder={`請輸入${f.label}`}
                error={!!errors[f.key]}
                style={{ width: "100%" }}
              />
            )}
            {errors[f.key] && <div style={{ fontSize: "var(--fs-12)", color: "var(--danger)", marginTop: 4 }}>{errors[f.key]}</div>}
          </div>
        </div>
      ))}
    </Dialog>
  );
};

const BasedataList = ({ pageId, rows, regionNames, onAdd, onUpdate, onDelete, sectionLabel, titleLabel }) => {
  const cfg = BD_PAGE_CONFIG[pageId];
  const { push: toast } = useToast();
  const [q, setQ] = useState("");
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(PAGE_SIZES[0]);
  const [formDlg, setFormDlg] = useState(null);
  const [deleteDlg, setDeleteDlg] = useState(null);
  const { SortHead, applySortTo } = useSortableTable(cfg.defaultSort, "asc");

  const filtered = useMemo(() => {
    const lq = q.trim().toLowerCase();
    const base = !lq ? rows : rows.filter(r =>
      cfg.searchKeys.some(k => String(r[k] || "").toLowerCase().includes(lq))
    );
    return applySortTo(base);
  }, [rows, q, cfg, applySortTo]);

  const paged = filtered.slice((page - 1) * pageSize, page * pageSize);

  return (
    <>
      <PageHead
        section={sectionLabel}
        title={titleLabel}
        actions={
          <Button variant="primary" icon="plus" onClick={() => setFormDlg({ mode: "add" })}>
            {cfg.addLabel}
          </Button>
        }
      />

      <FilterBar filters={[
        { type: "search", placeholder: cfg.searchPlaceholder, value: q, onChange: v => { setQ(v); setPage(1); } },
      ]} />

      <div className="card">
        <div className="tbl-wrap">
          <table className="tbl">
            <thead>
              <tr>
                {cfg.cols.map(c => (
                  <th key={c.key}><SortHead colKey={c.key} label={c.label} /></th>
                ))}
                <th className="center" style={{ width: 160 }}>功能</th>
              </tr>
            </thead>
            <tbody>
              {paged.length === 0 ? (
                <tr><td colSpan={cfg.cols.length + 1} style={{ textAlign: "center", color: "var(--fg-4)", padding: "40px 0" }}>{cfg.emptyTitle}</td></tr>
              ) : paged.map(row => (
                <tr key={row.id}>
                  {cfg.cols.map(c => (
                    <td key={c.key} style={c.mono ? { fontFamily: "var(--font-mono)", fontSize: "var(--fs-12)" } : { fontWeight: "var(--fw-medium)" }}>
                      {row[c.key] || "—"}
                    </td>
                  ))}
                  <td className="center">
                    <div className="actions">
                      <button className="row-act" onClick={() => setFormDlg({ mode: "edit", row })}>編輯</button>
                      <button className="row-act row-act--danger" onClick={() => setDeleteDlg(row)}>刪除</button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <Pager total={filtered.length} page={page} pageSize={pageSize}
          onPageChange={setPage} onSizeChange={s => { setPageSize(s); setPage(1); }} />
      </div>

      {formDlg && (
        <BasedataFormDialog
          cfg={cfg}
          mode={formDlg.mode}
          initial={formDlg.row}
          rows={rows}
          regionOptions={regionNames}
          onClose={() => setFormDlg(null)}
          onSave={(form) => {
            if (formDlg.mode === "add") {
              onAdd(form);
              toast({ kind: "success", msg: "已新增" });
            } else {
              onUpdate(formDlg.row.id, form);
              toast({ kind: "success", msg: "已更新" });
            }
            setFormDlg(null);
          }}
        />
      )}

      {deleteDlg && (
        <Dialog
          open
          title="刪除確認"
          onClose={() => setDeleteDlg(null)}
          footer={<>
            <Button variant="text" onClick={() => setDeleteDlg(null)}>取消</Button>
            <Button variant="danger" onClick={() => {
              onDelete(deleteDlg.id);
              setDeleteDlg(null);
              toast({ kind: "success", msg: "已刪除" });
            }}>刪除</Button>
          </>}
        >
          <div style={{ lineHeight: 1.6 }}>確定要刪除這筆資料嗎？此動作無法還原。</div>
        </Dialog>
      )}
    </>
  );
};

Object.assign(window, { BasedataList, BD_PAGE_CONFIG });
