/* WAREHOUSE 2.0 · ERP 中樞 — Swiss 版式,真後端(/api/erp/overview 駕駛艙子集) */
(() => {
const W2 = window.W2;
const { t } = window.W2_LANG;
window.W2_LANG.addEN({
  "ERP 中樞": "ERP Hub",
  "預算 · 採購 · 閉環 · {p} · 頁面只讀,操作交秘書": "Budget · Procurement · Closure · {p} · Read-only, actions via Secretary",
  "刷新": "Refresh",
  "問秘書": "Ask Secretary",
  "ERP 現在最需要處理什麼?按預算、採購、閉環分類,給我優先級清單": "What needs attention in ERP right now? Give me a prioritised list across budgets, procurement and closure",
  "當前期間": "Current period",
  "讀取 ERP 數據…": "Loading ERP data…",
  "可用預算": "Available budget",
  "元": "CNY",
  "萬元": "×10K CNY",
  "億元": "×100M CNY",
  "總額 {a} · 已用 {u}%": "Total {a} · {u}% used",
  "預算使用率": "Budget usage",
  "已佔用 {r} · 已支出 {s}": "Reserved {r} · Spent {s}",
  "未掛預算單據": "Unlinked documents",
  "張": "docs",
  "讓秘書關聯 →": "Secretary: link →",
  "全部閉環": "All closed",
  "把所有未掛預算的庫存單據列出來,逐張關聯到合適的可用預算,先給我方案": "List every inventory document without a budget link and link each to a suitable available budget; propose a plan first",
  "活躍預警": "Open alerts",
  "條": "items",
  "交秘書處置 →": "Secretary: handle →",
  "無預警": "No alerts",
  "把 ERP 相關的活躍預警列出來,按風險排序給我處置方案": "List the open ERP-related alerts sorted by risk and give me handling plans",
  "成本中心": "Cost centers",
  "進行工單": "Open work orders",
  "進行採購": "Open purchases",
  "活躍供應商": "Active suppliers",
  "庫存單據": "Inventory documents",
  "預算": "Budgets",
  "進行 {a} · 待閉環 {r} · 歸檔 {c}": "Active {a} · Review {r} · Archived {c}",
  "進行中": "Active",
  "待閉環": "Pending closure",
  "已歸檔": "Archived",
  "全部": "All",
  "編號": "No.",
  "成本中心 / 科目": "Cost center / Account",
  "期間": "Period",
  "額度": "Amount",
  "可用": "Available",
  "使用率": "Usage",
  "狀態": "Status",
  "交給秘書": "To Secretary",
  "預算中心": "Budget center",
  "交秘書": "Secretary",
  "草稿": "Draft",
  "計劃": "Planned",
  "暫停": "Paused",
  "完成": "Completed",
  "凍結": "Frozen",
  "已關閉": "Closed",
  "已佔用": "Reserved",
  "已批准": "Approved",
  "已提交": "Submitted",
  "已下單": "Ordered",
  "已到貨": "Received",
  "已支出": "Spent",
  "已釋放": "Released",
  "已取消": "Cancelled",
  "已確認": "Confirmed",
  "已過賬": "Posted",
  "待處理": "Pending",
  "AI 閉環": "AI closed",
  "異常": "Exception",
  "預算「{no}」({cc} · {acc})顯示{st},原因:{r}。請核對並完成閉環或結項,先給方案,我確認後執行": "Budget \"{no}\" ({cc} · {acc}) shows {st}, reason: {r}. Verify and close or finalise it; propose a plan and execute after my confirmation",
  "分析預算「{no}」({cc} · {acc}):額度 {amt},可用 {av},使用率 {u}%。有無風險?給下一步建議": "Analyse budget \"{no}\" ({cc} · {acc}): amount {amt}, available {av}, usage {u}%. Any risks? Suggest next steps",
  "還沒有預算": "No budgets yet",
  "對秘書說「為◯◯成本中心建立◯◯預算 50000 元」即可開始。": "Tell the Secretary \"create a 50,000 budget for cost center X\" to get started.",
  "讓秘書建預算": "Create via Secretary",
  "我要建立一筆預算,請追問成本中心、科目、期間和金額後執行": "I want to create a budget; ask me for the cost center, account, period and amount, then execute",
  "當前篩選下沒有預算": "No budgets under this filter",
  "採購申請": "Purchase requests",
  "進行 {o} · 歸檔 {a} · 供應商 {s}": "Open {o} · Archived {a} · Suppliers {s}",
  "申請號": "Request no.",
  "標題 / 明細": "Title / Lines",
  "供應商": "Supplier",
  "金額": "Amount",
  "未指定供應商": "No supplier",
  "未命名物資": "Unnamed item",
  "未填明細": "No lines",
  "{p} 等 {n} 項": "{p} · {n} lines",
  "緊急": "Urgent",
  "提交": "Submit",
  "批准": "Approve",
  "下單": "Order",
  "確認到貨": "Confirm receipt",
  "採購申請「{no} · {title}」當前狀態「{st}」,下一步是「{nx}」;金額 {amt},供應商 {sp}。請核對後與我確認執行": "Purchase request \"{no} · {title}\" is currently \"{st}\", next step is \"{nx}\"; amount {amt}, supplier {sp}. Verify and confirm with me before executing",
  "看看採購申請「{no} · {title}」的情況,給我下一步建議": "Review purchase request \"{no} · {title}\" and suggest next steps",
  "還沒有採購申請": "No purchase requests yet",
  "對秘書說「採購一批◯◯,預算 5000」即可發起。": "Tell the Secretary \"purchase some X with a 5,000 budget\" to start one.",
  "讓秘書發起採購": "Start via Secretary",
  "我要發起一筆採購申請,請追問物資、數量、預算和供應商後執行": "I want to raise a purchase request; ask me for the items, quantities, budget and supplier, then execute",
  "當前篩選下沒有採購申請": "No purchase requests under this filter",
  "未閉環事項": "Open-loop items",
  "{n} 項待處理": "{n} pending",
  "一鍵全部交秘書": "Hand all to Secretary",
  "把 ERP 未閉環事項(未掛預算單據、預算佔用、進行中盤點)逐項給我處置方案,我確認後執行": "Go through the ERP open-loop items (unlinked documents, budget reservations, running stocktakes) one by one with handling plans; execute after my confirmation",
  "未掛預算": "No budget link",
  "預算佔用": "Budget reservation",
  "盤點": "Stocktake",
  "明細 {n} 項": "{n} lines",
  "差異 {n} 項": "{n} diffs",
  "全庫": "Whole warehouse",
  "沒有未閉環事項": "No open-loop items",
  "佔用、單據與盤點全部閉環。秘書持續盯守,有異常會出現在這裡。": "All reservations, documents and stocktakes are closed. The Secretary keeps watch; exceptions surface here.",
  "把庫存單據「{no}」關聯到合適的可用預算,金額按單據核定;先給我方案,確認後執行": "Link inventory document \"{no}\" to a suitable available budget, amount per the document; propose a plan first and execute after confirmation",
  "預算佔用「{no}」({title},金額 {amt})該如何閉環?可批准、記支出或釋放;給我建議,確認後執行": "How should budget reservation \"{no}\" ({title}, amount {amt}) be closed? Approve, mark spent or release; advise me and execute after confirmation",
  "盤點任務「{no}」({name})還未閉環,差異 {n} 項;幫我跟進收尾": "Stocktake task \"{no}\" ({name}) is still open with {n} diffs; help me follow up and close it",
  "手動": "Manual",
  "共創計劃": "Collab plan",
  "工單": "Work order",
  "採購": "Purchase",
  "其他": "Other",
});

const { useState: _s, useEffect: _e, useMemo: _mm } = React;
const { Icon: I, Btn: B, Tag: T, Empty: EM, Kpi, Folio, Band, pad2, num } = W2;
const ask = (p) => W2.openSecretary(p);

/* ── 格式化 ── */
const money = (v, c) => {
  const n = Number(v);
  if (!Number.isFinite(n)) return "—";
  return ((!c || c === "CNY") ? "¥" : c + " ") + n.toLocaleString("zh-CN", { maximumFractionDigits: 2 });
};
const kMoney = (v) => {
  const n = Number(v) || 0;
  const a = Math.abs(n);
  if (a >= 1e8) return [+(n / 1e8).toFixed(1), "億元"];
  if (a >= 1e4) return [+(n / 1e4).toFixed(1), "萬元"];
  return [Math.round(n), "元"];
};

/* ── 後端狀態字典(語氣 + 繁中) ── */
const ST = {
  draft: ["plain", "草稿"], planned: ["plain", "計劃"], active: ["ok", "進行中"], paused: ["warn", "暫停"],
  completed: ["ok", "完成"], frozen: ["warn", "凍結"], closed: ["plain", "已關閉"], reserved: ["warn", "已佔用"],
  approved: ["ok", "已批准"], submitted: ["warn", "已提交"], ordered: ["warn", "已下單"], received: ["ok", "已到貨"],
  spent: ["bad", "已支出"], released: ["plain", "已釋放"], cancelled: ["plain", "已取消"], confirmed: ["ok", "已確認"],
  posted: ["ok", "已過賬"], pending: ["warn", "待處理"], pending_closure: ["warn", "待閉環"],
  auto_closed: ["ok", "AI 閉環"], exception: ["bad", "異常"],
};
const stKey = (v) => String(v == null ? "" : v).trim().toLowerCase();
const stText = (v) => { const m = ST[stKey(v)]; return m ? t(m[1]) : (v || "—"); };
const StTag = ({ v, dot }) => { const m = ST[stKey(v)]; return <T tone={m ? m[0] : "plain"} dot={dot}>{m ? t(m[1]) : (v || "—")}</T>; };
const SRC = { manual: "手動", collab_idea: "共創計劃", work_task: "工單", purchase_request: "採購", inventory_document: "庫存單據", other: "其他" };

/* ── 業務判定(照 1.0 口徑,全部防禦) ── */
const usageOf = (b) => { const a = num(b.amount); return a ? Math.min(100, Math.round((num(b.reserved) + num(b.spent)) / a * 100)) : 0; };
const budgetState = (b) => {
  const ai = b.ai_status || "";
  if (b.status === "closed" || ai === "auto_closed" || ai === "closed") return "archived";
  if (ai === "pending_closure" || ai === "exception") return "review";
  return "active";
};
const DOC_DONE = ["confirmed", "posted", "closed", "cancelled", "completed", "done", "已完成"];
const docOpen = (x) => !DOC_DONE.includes(stKey(x.status)) && !x.confirmed_at && !x.cancelled_at;
const docUnlinked = (x) => x.budget_unlinked_open === true
  || (x.budget_unlinked_open == null && docOpen(x) && x.needs_budget && !x.budget_reservation_id);
const rsvActive = (r) => !["spent", "released", "cancelled", "closed"].includes(stKey(r.status));
const stkOpen = (x) => !["completed", "closed", "cancelled", "done", "已完成"].includes(stKey(x.status));
const prOpen = (p) => !["received", "cancelled", "completed", "closed"].includes(stKey(p.status || "draft"));
const PR_NEXT = { draft: "提交", submitted: "批准", approved: "下單", ordered: "確認到貨" };

const linePreview = (p) => {
  const lines = Array.isArray(p.lines) ? p.lines : [];
  if (!lines.length) return t("未填明細");
  const prev = lines.slice(0, 2).map((l) => (l.item_name || t("未命名物資")) + " ×" + num(l.quantity) + (l.unit || "")).join("、");
  return lines.length > 2 ? t("{p} 等 {n} 項", { p: prev, n: lines.length }) : prev;
};

const Page = ({ boot, reload }) => {
  const [data, setData] = _s(null);
  const [tick, setTick] = _s(0);
  const [bScope, setBScope] = _s("active");
  const [pScope, setPScope] = _s("open");

  _e(() => {
    let on = true;
    W2.json("/api/erp/overview")
      .then((d) => { if (on) setData(d && typeof d === "object" ? d : {}); })
      .catch(() => { if (on) setData({}); });
    return () => { on = false; };
  }, [tick]);

  const d = data || {};
  const summary = d.summary || {};
  const budgets = Array.isArray(d.budgets) ? d.budgets : [];
  const purchases = Array.isArray(d.purchase_requests) ? d.purchase_requests : [];
  const reservations = Array.isArray(d.reservations) ? d.reservations : [];
  const docs = Array.isArray(d.inventory_documents) ? d.inventory_documents : [];
  const alerts = Array.isArray(d.open_alerts) ? d.open_alerts : [];
  const stocktakes = Array.isArray(d.stocktake_tasks) ? d.stocktake_tasks : [];

  const unlinkedDocs = docs.filter(docUnlinked);
  const openRsv = reservations.filter(rsvActive);
  const openStk = stocktakes.filter(stkOpen);
  const openPr = purchases.filter(prOpen);
  const archPr = purchases.filter((p) => !prOpen(p));

  const unlinkedCount = Math.max(unlinkedDocs.length, num(summary.inventory_unlinked));
  const alertCount = Math.max(alerts.length, num(summary.open_alerts));
  const usage = num(summary.budget_amount)
    ? Math.min(100, Math.round((num(summary.budget_reserved) + num(summary.budget_spent)) / num(summary.budget_amount) * 100))
    : 0;
  const [avVal, avUnit] = kMoney(summary.budget_available);
  const period = (summary.active_period && summary.active_period.period_name) || t("當前期間");

  const byState = _mm(() => {
    const g = { active: [], review: [], archived: [] };
    budgets.forEach((b) => g[budgetState(b)].push(b));
    return g;
  }, [budgets]);
  const bList = bScope === "all" ? [...byState.review, ...byState.active, ...byState.archived] : (byState[bScope] || []);
  const pList = pScope === "open" ? openPr : pScope === "arch" ? archPr : purchases;

  const bPrompt = (b) => {
    const no = b.budget_no || b.account_name || "—";
    const cc = b.center_name || "—";
    const acc = b.account_name || "—";
    if (budgetState(b) === "review") {
      return t("預算「{no}」({cc} · {acc})顯示{st},原因:{r}。請核對並完成閉環或結項,先給方案,我確認後執行",
        { no, cc, acc, st: stText(b.ai_status || b.status), r: b.ai_status_reason || "—" });
    }
    return t("分析預算「{no}」({cc} · {acc}):額度 {amt},可用 {av},使用率 {u}%。有無風險?給下一步建議",
      { no, cc, acc, amt: money(num(b.amount), b.currency), av: money(num(b.available), b.currency), u: usageOf(b) });
  };
  const pPrompt = (p) => {
    const no = p.request_no || "—";
    const title = p.title || "—";
    const nx = PR_NEXT[stKey(p.status || "draft")];
    if (nx) {
      return t("採購申請「{no} · {title}」當前狀態「{st}」,下一步是「{nx}」;金額 {amt},供應商 {sp}。請核對後與我確認執行",
        { no, title, st: stText(p.status || "draft"), nx: t(nx), amt: money(num(p.total_amount), p.currency), sp: p.supplier_name || t("未指定供應商") });
    }
    return t("看看採購申請「{no} · {title}」的情況,給我下一步建議", { no, title });
  };

  const closure = [
    ...unlinkedDocs.map((x, i) => ({
      key: "doc" + (x.id || x.document_no || i),
      icon: "doc", tagTone: "bad", tagText: t("未掛預算"),
      title: x.document_no || t("庫存單據"),
      sub: [x.business_type || x.document_type || t("庫存單據"), x.summary, x.line_count != null ? t("明細 {n} 項", { n: num(x.line_count) }) : ""].filter(Boolean).join(" · "),
      right: <StTag v={x.status}/>,
      prompt: t("把庫存單據「{no}」關聯到合適的可用預算,金額按單據核定;先給我方案,確認後執行", { no: x.document_no || "—" }),
    })),
    ...openRsv.map((r, i) => ({
      key: "rsv" + (r.id || r.reservation_no || i),
      icon: "clock", tagTone: "warn", tagText: t("預算佔用"),
      title: r.source_title || r.note || r.reservation_no || t("預算佔用"),
      sub: [r.reservation_no, r.center_name, r.account_name, SRC[r.source_type] ? t(SRC[r.source_type]) : ""].filter(Boolean).join(" · "),
      right: <span className="row g8"><span className="num" style={{ fontWeight: 700 }}>{money(num(r.amount), r.currency)}</span><StTag v={r.status}/></span>,
      prompt: t("預算佔用「{no}」({title},金額 {amt})該如何閉環?可批准、記支出或釋放;給我建議,確認後執行",
        { no: r.reservation_no || "—", title: r.source_title || r.note || "—", amt: money(num(r.amount), r.currency) }),
    })),
    ...openStk.map((x, i) => ({
      key: "stk" + (x.task_no || i),
      icon: "scan", tagTone: "plain", tagText: t("盤點"),
      title: x.task_name || x.task_no || t("盤點"),
      sub: [x.task_no, x.area || t("全庫"), t("差異 {n} 項", { n: num(x.diff_count) })].filter(Boolean).join(" · "),
      right: <span className="num muted" style={{ fontSize: 12 }}>{num(x.progress)}%</span>,
      prompt: t("盤點任務「{no}」({name})還未閉環,差異 {n} 項;幫我跟進收尾",
        { no: x.task_no || "—", name: x.task_name || "—", n: num(x.diff_count) }),
    })),
  ];

  const rightTh = { textAlign: "right" };

  return (
    <>
      <Folio no="07" en="ERP" title={t("ERP 中樞")}
        sub={t("預算 · 採購 · 閉環 · {p} · 頁面只讀,操作交秘書", { p: period })}
        right={<>
          <B icon="refresh" onClick={() => { setData(null); setTick((k) => k + 1); }}>{t("刷新")}</B>
          <B kind="primary" icon="sparkle" onClick={() => ask(t("ERP 現在最需要處理什麼?按預算、採購、閉環分類,給我優先級清單"))}>{t("問秘書")}</B>
        </>}/>

      {data === null ? (
        <div className="muted rise" style={{ padding: "42px 0", fontSize: 12.5 }}>{t("讀取 ERP 數據…")}</div>
      ) : (<>
        <div className="kpi-band">
          <Kpi label={t("可用預算")} value={avVal} unit={t(avUnit)} red={num(summary.budget_available) < 0} delay={0}
            foot={<span className="muted" style={{ fontSize: 11.5 }}>{t("總額 {a} · 已用 {u}%", { a: money(num(summary.budget_amount)), u: usage })}</span>}/>
          <Kpi label={t("預算使用率")} value={usage} unit="%" red={usage > 90} delay={.05}
            foot={<span className="muted" style={{ fontSize: 11.5 }}>{t("已佔用 {r} · 已支出 {s}", { r: money(num(summary.budget_reserved)), s: money(num(summary.budget_spent)) })}</span>}/>
          <Kpi label={t("未掛預算單據")} value={unlinkedCount} unit={t("張")} red={unlinkedCount > 0} delay={.1}
            foot={unlinkedCount
              ? <button className="tag redinv" style={{ cursor: "pointer" }} onClick={() => ask(t("把所有未掛預算的庫存單據列出來,逐張關聯到合適的可用預算,先給我方案"))}>{t("讓秘書關聯 →")}</button>
              : <T tone="ok" dot>{t("全部閉環")}</T>}/>
          <Kpi label={t("活躍預警")} value={alertCount} unit={t("條")} red={alertCount > 0} delay={.15}
            foot={alertCount
              ? <button className="tag bad" style={{ cursor: "pointer" }} onClick={() => ask(t("把 ERP 相關的活躍預警列出來,按風險排序給我處置方案"))}>{t("交秘書處置 →")}</button>
              : <T tone="ok" dot>{t("無預警")}</T>}/>
        </div>

        <div className="row g24 wrap rise" style={{ padding: "14px 0", borderBottom: "1px solid var(--hair)", animationDelay: ".05s" }}>
          {[
            [t("成本中心"), num(summary.cost_centers)],
            [t("進行工單"), num(summary.work_tasks_open)],
            [t("進行採購"), num(summary.purchase_open) || openPr.length],
            [t("活躍供應商"), num(summary.suppliers_active)],
            [t("庫存單據"), num(summary.inventory_documents) || docs.length],
          ].map(([k, v]) => (
            <div key={k} className="row g8">
              <span className="label dim">{k}</span>
              <span className="num" style={{ fontWeight: 700, fontSize: 15 }}>{v}</span>
            </div>
          ))}
        </div>

        <Band no="01" title={t("預算")}
          sub={t("進行 {a} · 待閉環 {r} · 歸檔 {c}", { a: byState.active.length, r: byState.review.length, c: byState.archived.length })}
          right={
            <div className="seg">
              {[["active", "進行中"], ["review", "待閉環"], ["archived", "已歸檔"], ["all", "全部"]].map(([id, label]) => (
                <button key={id} className={bScope === id ? "on" : ""} onClick={() => setBScope(id)}>{t(label)}</button>
              ))}
            </div>
          } delay={.1}>
          {budgets.length === 0 ? (
            <EM icon="wallet" title={t("還沒有預算")} sub={t("對秘書說「為◯◯成本中心建立◯◯預算 50000 元」即可開始。")}
              action={<B icon="sparkle" onClick={() => ask(t("我要建立一筆預算,請追問成本中心、科目、期間和金額後執行"))}>{t("讓秘書建預算")}</B>}/>
          ) : bList.length === 0 ? (
            <EM icon="search" title={t("當前篩選下沒有預算")}/>
          ) : (
            <div style={{ overflowX: "auto" }}>
              <table className="tbl2">
                <thead><tr>
                  <th>{t("編號")}</th><th>{t("成本中心 / 科目")}</th><th>{t("期間")}</th>
                  <th style={rightTh}>{t("額度")}</th><th style={rightTh}>{t("可用")}</th>
                  <th>{t("使用率")}</th><th>{t("狀態")}</th><th style={{ width: 96 }}>{t("交給秘書")}</th>
                </tr></thead>
                <tbody>
                  {bList.map((b, i) => {
                    const u = usageOf(b);
                    return (
                      <tr key={(b.id || b.budget_no || i) + ":" + i}>
                        <td>
                          <div className="col g4">
                            <span className="num" style={{ fontWeight: 600 }}>{b.budget_no || "—"}</span>
                            {b.budget_kind === "center" && <span className="mono" style={{ fontSize: 9, letterSpacing: ".12em", color: "var(--ink-3)" }}>{t("預算中心")}</span>}
                          </div>
                        </td>
                        <td>
                          <div className="col g4">
                            <span style={{ fontWeight: 650 }}>{b.center_name || "—"}</span>
                            <span className="muted" style={{ fontSize: 11.5 }}>{b.account_name || "—"}</span>
                          </div>
                        </td>
                        <td className="muted" style={{ fontSize: 12.5 }}>{b.period_name || "—"}</td>
                        <td style={rightTh}><span className="num" style={{ fontWeight: 700 }}>{money(num(b.amount), b.currency)}</span></td>
                        <td style={rightTh}><span className="num" style={{ fontWeight: 700, color: num(b.available) < 0 ? "var(--red)" : undefined }}>{money(num(b.available), b.currency)}</span></td>
                        <td>
                          <div className="row g8">
                            <div className="bar" style={{ width: 64 }}><i style={{ width: u + "%", background: u > 90 ? "var(--red)" : "var(--ink)" }}/></div>
                            <span className="num muted" style={{ fontSize: 11 }}>{u}%</span>
                          </div>
                        </td>
                        <td><StTag v={b.ai_status || b.status}/></td>
                        <td><B size="sm" icon="sparkle" onClick={() => ask(bPrompt(b))}>{t("交秘書")}</B></td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
        </Band>

        <Band no="02" title={t("採購申請")}
          sub={t("進行 {o} · 歸檔 {a} · 供應商 {s}", { o: openPr.length, a: archPr.length, s: num(summary.suppliers_active) })}
          right={
            <div className="seg">
              {[["open", "進行中"], ["arch", "已歸檔"], ["all", "全部"]].map(([id, label]) => (
                <button key={id} className={pScope === id ? "on" : ""} onClick={() => setPScope(id)}>{t(label)}</button>
              ))}
            </div>
          } delay={.15}>
          {purchases.length === 0 ? (
            <EM icon="inbound" title={t("還沒有採購申請")} sub={t("對秘書說「採購一批◯◯,預算 5000」即可發起。")}
              action={<B icon="sparkle" onClick={() => ask(t("我要發起一筆採購申請,請追問物資、數量、預算和供應商後執行"))}>{t("讓秘書發起採購")}</B>}/>
          ) : pList.length === 0 ? (
            <EM icon="search" title={t("當前篩選下沒有採購申請")}/>
          ) : (
            <div style={{ overflowX: "auto" }}>
              <table className="tbl2">
                <thead><tr>
                  <th>{t("申請號")}</th><th>{t("標題 / 明細")}</th><th>{t("供應商")}</th>
                  <th style={rightTh}>{t("金額")}</th><th>{t("狀態")}</th><th style={{ width: 96 }}>{t("交給秘書")}</th>
                </tr></thead>
                <tbody>
                  {pList.map((p, i) => (
                    <tr key={(p.id || p.request_no || i) + ":" + i}>
                      <td><span className="num" style={{ fontWeight: 600 }}>{p.request_no || "—"}</span></td>
                      <td>
                        <div className="col g4" style={{ minWidth: 0 }}>
                          <span className="row g8" style={{ fontWeight: 650 }}>
                            {p.priority === "urgent" && <I name="flame" size={12} color="var(--red)"/>}
                            {p.title || "—"}
                            {p.priority === "urgent" && <T tone="bad">{t("緊急")}</T>}
                          </span>
                          <span className="muted" style={{ fontSize: 11.5 }}>{linePreview(p)}</span>
                        </div>
                      </td>
                      <td className="muted" style={{ fontSize: 12.5 }}>{p.supplier_name || t("未指定供應商")}</td>
                      <td style={rightTh}><span className="num" style={{ fontWeight: 700 }}>{money(num(p.total_amount), p.currency)}</span></td>
                      <td><StTag v={p.status || "draft"}/></td>
                      <td><B size="sm" icon="sparkle" onClick={() => ask(pPrompt(p))}>{t("交秘書")}</B></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </Band>

        <Band no="03" title={t("未閉環事項")}
          sub={closure.length ? t("{n} 項待處理", { n: closure.length }) : t("全部閉環")}
          right={closure.length
            ? <B size="sm" icon="sparkle" onClick={() => ask(t("把 ERP 未閉環事項(未掛預算單據、預算佔用、進行中盤點)逐項給我處置方案,我確認後執行"))}>{t("一鍵全部交秘書")}</B>
            : null} delay={.2}>
          {closure.length === 0 ? (
            <EM icon="checkCircle" title={t("沒有未閉環事項")} sub={t("佔用、單據與盤點全部閉環。秘書持續盯守,有異常會出現在這裡。")}/>
          ) : (
            <div style={{ borderTop: "2px solid var(--rule)" }}>
              {closure.map((c, i) => (
                <div key={c.key} className="ledger-row">
                  <span className="lr-idx">{pad2(i + 1)}</span>
                  <I name={c.icon} size={15} color="var(--ink-3)"/>
                  <div className="col g4" style={{ flex: 1, minWidth: 0 }}>
                    <span className="row g8 wrap" style={{ fontWeight: 650, fontSize: 13.5 }}>{c.title}<T tone={c.tagTone}>{c.tagText}</T></span>
                    {c.sub && <span className="muted num" style={{ fontSize: 11.5 }}>{c.sub}</span>}
                  </div>
                  <div className="row g10">{c.right}</div>
                  <B size="sm" icon="sparkle" onClick={() => ask(c.prompt)}>{t("交秘書")}</B>
                </div>
              ))}
            </div>
          )}
        </Band>
      </>)}
    </>
  );
};

window.W2.PAGES["erp"] = Page;
})();
