/* WAREHOUSE 2.0 · 盤點 — Swiss 版式,真後端(數據源:/api/bootstrap 的 STOCKTAKE / STOCKTAKE_DIFF / ZONES) */
(() => {
const W2 = window.W2;
const { t } = window.W2_LANG;
window.W2_LANG.addEN({
  "盤點": "Stocktake",
  "盤點計劃與歷史 · 差異醒目 · 頁面只讀,操作交秘書": "Plans & history · variances up front · read-only, actions via Secretary",
  "{n} 個任務 · {a} 個進行中 · {d} 項差異待處理": "{n} tasks · {a} in progress · {d} variances pending",
  "發起盤點": "Start stocktake",
  "問秘書": "Ask Secretary",
  "我要發起一次盤點任務,請追問任務名稱、盤點區域、負責人與計劃品類數,然後創建": "Start a new stocktake task for me — ask for task name, area, owner and planned item count, then create it",
  "盤點工作現在整體情況怎麼樣?有哪些差異需要我拍板?": "How is stocktake going overall? Which variances need my decision?",
  "盤點任務": "Tasks",
  "進行中": "In progress",
  "整體進度": "Overall progress",
  "待處理差異": "Pending variances",
  "已完成 {n} 個": "{n} completed",
  "未開始 {n} 個": "{n} not started",
  "已盤 {d} / 計劃 {p} 種": "{d} counted / {p} planned",
  "賬實相符": "Books match reality",
  "交秘書逐條處理 →": "Resolve via Secretary →",
  "個": "", "項": "", "種": "",
  "差異明細": "Variance detail",
  "賬 vs 實 · 待處理優先 · 盤虧標紅": "book vs actual · pending first · shortages in red",
  "全部差異交秘書": "All variances to Secretary",
  "把全部待處理的盤點差異列出來,逐條給我調整方案(調賬或復盤),經我確認後執行": "List all pending stocktake variances and propose an adjustment (rebook or recount) for each; execute after my confirmation",
  "待處理": "Pending",
  "全部": "All",
  "物資": "Item",
  "賬面": "Book",
  "實盤": "Actual",
  "差異": "Variance",
  "狀態": "Status",
  "交給秘書": "Secretary",
  "已調整": "Adjusted",
  "處理差異": "Resolve",
  "處理盤點差異:「{item}」賬面 {book}、實盤 {real}、差異 {diff},原因「{reason}」。給我調整方案(調賬或復盤),經我確認後執行": "Resolve stocktake variance: \"{item}\" book {book}, actual {real}, variance {diff}, reason \"{reason}\". Propose an adjustment (rebook or recount) and execute after my confirmation",
  "當前篩選下沒有差異": "No variances under this filter",
  "當前沒有盤點差異。完成盤點後,新差異會第一時間出現在這裡。": "No stocktake variances right now. New variances will appear here as counts complete.",
  "盤點任務與歷史": "Tasks & history",
  "進行中優先 · 歷史檔案保留可追溯": "in progress first · history archived & traceable",
  "負責人": "owner",
  "已完成": "Completed",
  "未開始": "Not started",
  "差異 {n}": "{n} var.",
  "跟進": "Follow up",
  "開始": "Begin",
  "總結": "Recap",
  "盤點任務「{name}」(單號 {id})進行中,進度 {p}%。幫我看看還剩哪些沒盤、有沒有新差異要跟進": "Stocktake \"{name}\" ({id}) is in progress at {p}%. Check what remains uncounted and whether new variances need follow-up",
  "盤點任務「{name}」(單號 {id})還未開始,幫我安排開始執行(範圍 {area},負責人 {owner})": "Stocktake \"{name}\" ({id}) has not started. Arrange to begin it (scope {area}, owner {owner})",
  "總結盤點任務「{name}」(單號 {id})的結果:完成情況、差異與處理建議": "Recap stocktake \"{name}\" ({id}): completion, variances and recommended handling",
  "還沒有盤點任務": "No stocktake tasks yet",
  "對秘書說「發起一次全庫盤點」即可開始;計劃、進度與差異都會沉澱在這裡。": "Tell the Secretary \"start a full-warehouse stocktake\" to begin; plans, progress and variances all land here.",
  "區域覆蓋": "Zone coverage",
  "按倉庫區域 · 進行中任務覆蓋": "by warehouse zone · covered by active tasks",
  "盤完": "done",
  "盤點中": "counting",
  "未盤": "not counted",
  "2.0 約定:頁面只讀,改動經秘書確認執行,全程留痕。": "2.0 contract: read-only page; changes run via Secretary confirmation, fully audited.",
});
const { useState: _s, useMemo: _mm } = React;
const { Icon: I, Btn: B, Tag: T, Label: LB, Empty: EM, Kpi, Folio, Band, pad2, num } = W2;
const ask = (p) => W2.openSecretary(p);

/* ── 防禦性歸一化:兼容 bootstrap 兩代形狀 ── */
const normTask = (tk, i) => {
  tk = tk || {};
  const total = num(tk.total != null ? tk.total : tk.planned);
  const done = num(tk.done != null ? tk.done : tk.counted);
  const progress = tk.progress != null ? Math.max(0, Math.min(100, num(tk.progress))) : (total ? Math.round(done / total * 100) : 0);
  const raw = String(tk.status || "");
  const st = /已完成|completed|closed|done/i.test(raw) ? "done"
    : /進行|进行|progress|active|open|doing/i.test(raw) ? "active" : "pending";
  return {
    key: (tk.id || "tk") + ":" + i, idx: i,
    id: tk.id || "—",
    name: tk.name || tk.task_name || tk.scope || tk.area || tk.id || "—",
    area: tk.area || tk.scope || "—",
    owner: tk.owner || "—",
    date: tk.date || "",
    total, done, progress, diff: num(tk.diff), st,
  };
};
const normDiff = (d, i) => {
  d = d || {};
  const book = num(d.book), real = num(d.real);
  return {
    key: (d.item || "d") + ":" + i,
    item: d.item || d.item_name || "—",
    book, real,
    diff: d.diff != null ? num(d.diff) : real - book,
    reason: d.reason || "—",
    status: d.status || t("待處理"),
    pending: !/已調整|已调整|已處理|已处理|adjusted|handled|resolved|closed/i.test(String(d.status || "")),
  };
};
const ST_META = { active: ["inv", "進行中"], pending: ["plain", "未開始"], done: ["ok", "已完成"] };
const ST_ORDER = { active: 0, pending: 1, done: 2 };

const Page = ({ boot }) => {
  const tasks = _mm(() => (Array.isArray(boot.STOCKTAKE) ? boot.STOCKTAKE : []).map(normTask), [boot]);
  const diffs = _mm(() => (Array.isArray(boot.STOCKTAKE_DIFF) ? boot.STOCKTAKE_DIFF : []).map(normDiff), [boot]);
  const zones = Array.isArray(boot.ZONES) ? boot.ZONES : [];

  const active = tasks.filter(k => k.st === "active");
  const doneTasks = tasks.filter(k => k.st === "done");
  const pendDiffs = diffs.filter(d => d.pending);
  const overall = tasks.length ? Math.round(tasks.reduce((s, k) => s + k.progress, 0) / tasks.length) : 0;
  const doneItems = tasks.reduce((s, k) => s + k.done, 0);
  const planItems = tasks.reduce((s, k) => s + k.total, 0);

  const [dv, setDv] = _s(pendDiffs.length ? "pending" : "all");
  const shownDiffs = _mm(() => {
    const arr = (dv === "pending" ? diffs.filter(d => d.pending) : [...diffs]);
    return arr.sort((a, b) => (a.pending === b.pending ? Math.abs(b.diff) - Math.abs(a.diff) : a.pending ? -1 : 1));
  }, [diffs, dv]);
  const sortedTasks = _mm(() =>
    [...tasks].sort((a, b) => (ST_ORDER[a.st] - ST_ORDER[b.st]) || (b.idx - a.idx)), [tasks]);

  const askStart = () => ask(t("我要發起一次盤點任務,請追問任務名稱、盤點區域、負責人與計劃品類數,然後創建"));
  const askAllDiffs = () => ask(t("把全部待處理的盤點差異列出來,逐條給我調整方案(調賬或復盤),經我確認後執行"));
  const taskAct = (k) =>
    k.st === "active" ? ["跟進", t("盤點任務「{name}」(單號 {id})進行中,進度 {p}%。幫我看看還剩哪些沒盤、有沒有新差異要跟進", { name: k.name, id: k.id, p: k.progress })]
    : k.st === "pending" ? ["開始", t("盤點任務「{name}」(單號 {id})還未開始,幫我安排開始執行(範圍 {area},負責人 {owner})", { name: k.name, id: k.id, area: k.area, owner: k.owner })]
    : ["總結", t("總結盤點任務「{name}」(單號 {id})的結果:完成情況、差異與處理建議", { name: k.name, id: k.id })];

  return (<>
    <Folio no="06" en="STOCKTAKE" title={t("盤點")}
      sub={tasks.length || diffs.length
        ? t("{n} 個任務 · {a} 個進行中 · {d} 項差異待處理", { n: tasks.length, a: active.length, d: pendDiffs.length })
        : t("盤點計劃與歷史 · 差異醒目 · 頁面只讀,操作交秘書")}
      right={<>
        <B icon="clipboard" onClick={askStart}>{t("發起盤點")}</B>
        <B kind="primary" icon="sparkle" onClick={() => ask(t("盤點工作現在整體情況怎麼樣?有哪些差異需要我拍板?"))}>{t("問秘書")}</B>
      </>}/>

    <div className="kpi-band">
      <Kpi label={t("盤點任務")} value={tasks.length} unit={t("個")} delay={0}
        foot={<span className="muted" style={{ fontSize: 11.5 }}>{t("已完成 {n} 個", { n: doneTasks.length })}</span>}/>
      <Kpi label={t("進行中")} value={active.length} unit={t("個")} delay={.05}
        foot={active.length
          ? <T tone="inv">{t("進行中")}</T>
          : <span className="muted" style={{ fontSize: 11.5 }}>{t("未開始 {n} 個", { n: tasks.filter(k => k.st === "pending").length })}</span>}/>
      <Kpi label={t("整體進度")} value={tasks.length ? overall : "—"} unit="%" delay={.1}
        foot={<>
          <span className="muted" style={{ fontSize: 11.5 }}>{t("已盤 {d} / 計劃 {p} 種", { d: doneItems, p: planItems })}</span>
          <div className="bar" style={{ width: 72 }}><i style={{ width: overall + "%", background: "var(--ink)" }}/></div>
        </>}/>
      <Kpi label={t("待處理差異")} value={pendDiffs.length} unit={t("項")} red={pendDiffs.length > 0} delay={.15}
        foot={pendDiffs.length
          ? <button className="tag redinv" style={{ cursor: "pointer" }} onClick={askAllDiffs}>{t("交秘書逐條處理 →")}</button>
          : <T tone="ok" dot>{t("賬實相符")}</T>}/>
    </div>

    <Band no="01" title={t("差異明細")} sub={t("賬 vs 實 · 待處理優先 · 盤虧標紅")} delay={.1}
      right={<div className="row g10">
        {diffs.length > 0 && (
          <div className="seg">
            {[["pending", "待處理"], ["all", "全部"]].map(([id, label]) => (
              <button key={id} className={dv === id ? "on" : ""} onClick={() => setDv(id)}>
                {t(label)}{id === "pending" && pendDiffs.length ? " " + pendDiffs.length : ""}
              </button>
            ))}
          </div>
        )}
        {pendDiffs.length > 0 && <B size="sm" icon="sparkle" onClick={askAllDiffs}>{t("全部差異交秘書")}</B>}
      </div>}>
      {shownDiffs.length ? (
        <div style={{ overflowX: "auto" }}>
          <table className="tbl2">
            <thead><tr>
              <th style={{ width: 40 }}>#</th><th>{t("物資")}</th><th>{t("賬面")}</th><th>{t("實盤")}</th><th>{t("差異")}</th><th>{t("狀態")}</th><th style={{ width: 120 }}>{t("交給秘書")}</th>
            </tr></thead>
            <tbody>
              {shownDiffs.map((d, i) => (
                <tr key={d.key}>
                  <td><span className="lr-idx">{pad2(i + 1)}</span></td>
                  <td>
                    <div className="col g4">
                      <span style={{ fontWeight: 650, fontSize: 13.5 }}>{d.item}</span>
                      <span className="muted" style={{ fontSize: 11.5 }}>{d.reason}</span>
                    </div>
                  </td>
                  <td><span className="num" style={{ fontSize: 14 }}>{d.book}</span></td>
                  <td><span className="num" style={{ fontSize: 14 }}>{d.real}</span></td>
                  <td>
                    <span className="num" style={{ fontSize: 17, fontWeight: 700, color: d.diff < 0 ? "var(--red)" : d.diff > 0 ? "var(--ink)" : "var(--ink-3)" }}>
                      {d.diff > 0 ? "+" : ""}{d.diff}
                    </span>
                  </td>
                  <td>{d.pending ? <T tone="bad" dot>{t("待處理")}</T> : <T tone="ok" dot>{t("已調整")}</T>}</td>
                  <td>
                    <B size="sm" icon="sparkle" onClick={() => ask(t("處理盤點差異:「{item}」賬面 {book}、實盤 {real}、差異 {diff},原因「{reason}」。給我調整方案(調賬或復盤),經我確認後執行", { item: d.item, book: d.book, real: d.real, diff: (d.diff > 0 ? "+" : "") + d.diff, reason: d.reason }))}>{t("處理差異")}</B>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      ) : diffs.length ? (
        <EM icon="search" title={t("當前篩選下沒有差異")} sub={t("當前沒有盤點差異。完成盤點後,新差異會第一時間出現在這裡。")}/>
      ) : (
        <EM icon="checkCircle" title={t("賬實相符")} sub={t("當前沒有盤點差異。完成盤點後,新差異會第一時間出現在這裡。")}/>
      )}
    </Band>

    <Band no="02" title={t("盤點任務與歷史")} sub={t("進行中優先 · 歷史檔案保留可追溯")} delay={.15}
      right={tasks.length ? <B size="sm" icon="clipboard" onClick={askStart}>{t("發起盤點")}</B> : null}>
      {tasks.length ? (
        <div style={{ borderTop: "2px solid var(--rule)" }}>
          {sortedTasks.map((k, i) => {
            const [tone, label] = ST_META[k.st];
            const [actLabel, prompt] = taskAct(k);
            return (
              <div key={k.key} className="ledger-row">
                <span className="lr-idx">{pad2(i + 1)}</span>
                <div className="col g4" style={{ flex: 1.5, minWidth: 0 }}>
                  <span style={{ fontWeight: 650, fontSize: 13.5 }}>{k.name}</span>
                  <span className="muted num" style={{ fontSize: 11 }}>
                    {k.id}{k.date ? " · " + k.date : ""} · {k.area} · {t("負責人")} {k.owner}
                  </span>
                </div>
                <div className="col g4" style={{ flex: 1, minWidth: 150 }}>
                  <div className="row spread" style={{ width: 170 }}>
                    <span className="muted num" style={{ fontSize: 11 }}>{k.done} / {k.total || "—"}</span>
                    <span className="num" style={{ fontSize: 12.5, fontWeight: 700 }}>{k.progress}%</span>
                  </div>
                  <div className="bar" style={{ width: 170 }}>
                    <i style={{ width: k.progress + "%", background: k.st === "done" ? "var(--ok)" : k.st === "active" ? "var(--ink)" : "var(--ink-4)" }}/>
                  </div>
                </div>
                {k.diff !== 0
                  ? <T tone="redinv">{t("差異 {n}", { n: Math.abs(k.diff) })}</T>
                  : <T tone="ok" dot>{t("賬實相符")}</T>}
                <T tone={tone} dot={k.st !== "pending"}>{t(label)}</T>
                <B size="sm" icon="sparkle" onClick={() => ask(prompt)}>{t(actLabel)}</B>
              </div>
            );
          })}
        </div>
      ) : (
        <EM icon="clipboard" title={t("還沒有盤點任務")}
          sub={t("對秘書說「發起一次全庫盤點」即可開始;計劃、進度與差異都會沉澱在這裡。")}
          action={<B icon="clipboard" onClick={askStart}>{t("發起盤點")}</B>}/>
      )}
    </Band>

    {zones.length > 0 && (
      <Band no="03" title={t("區域覆蓋")} sub={t("按倉庫區域 · 進行中任務覆蓋")} delay={.2}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(88px, 1fr))", gap: 10 }}>
          {zones.map((z, i) => {
            const zid = String((z && z.id) || "");
            const hit = tasks.filter(k => zid && String(k.area).indexOf(zid) === 0);
            const p = hit.length ? Math.max(...hit.map(k => k.progress)) : 0;
            const on = hit.some(k => k.st === "active");
            return (
              <div key={zid || i} title={(z && z.name) || zid} style={{ aspectRatio: "1", position: "relative", overflow: "hidden", border: "1px solid var(--hair)", background: "var(--white)", display: "grid", placeItems: "center" }}>
                <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, height: p + "%", background: "var(--hair-soft)" }}/>
                <div className="col" style={{ alignItems: "center", gap: 2, zIndex: 1 }}>
                  <span className="num" style={{ fontSize: 20, fontWeight: 700, color: on ? "var(--red)" : p >= 100 ? "var(--ink)" : "var(--ink-4)" }}>{zid || "—"}</span>
                  <span className="mono muted" style={{ fontSize: 9 }}>{p}%</span>
                </div>
              </div>
            );
          })}
        </div>
        <div className="row g16" style={{ marginTop: 12, fontSize: 11.5, color: "var(--ink-3)" }}>
          <span className="row g6"><span style={{ width: 9, height: 9, background: "var(--ink)" }}/>{t("盤完")}</span>
          <span className="row g6"><span style={{ width: 9, height: 9, background: "var(--red)" }}/>{t("盤點中")}</span>
          <span className="row g6"><span style={{ width: 9, height: 9, background: "var(--ink-4)" }}/>{t("未盤")}</span>
        </div>
      </Band>
    )}

    <div className="muted" style={{ fontSize: 10.5, padding: "14px 0 0", lineHeight: 1.6 }}>
      {t("2.0 約定:頁面只讀,改動經秘書確認執行,全程留痕。")}
    </div>
  </>);
};

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