/* WAREHOUSE 2.0 · 資產 — Swiss 版式,真後端
   駕駛艙子集:金融資產組合(/api/assets + /api/assets/portfolio)
   + 數字資產市場(/api/digital-assets/listings|trades|revenue)。
   頁面只讀;記交易/上架/購買/分潤全部交秘書。 */
(() => {
const W2 = window.W2;
const { t } = window.W2_LANG;
window.W2_LANG.addEN({
  "資產": "Assets",
  "金融資產組合 + 數字資產市場 · 頁面只讀,交易與上架全交秘書": "Financial portfolio + digital asset market · read-only page, trades & listings via the Secretary",
  "記一筆交易": "Record a trade",
  "問秘書": "Ask Secretary",
  "金融資產市值": "Portfolio value",
  "浮動盈虧": "Unrealized P&L",
  "市場在售": "Live listings",
  "累計成交": "Total traded",
  "元": "CNY", "萬元": "×10k CNY", "億元": "×100M CNY", "檔": "live", "項": "items",
  "持倉 {h} 項 · 觀察 {w} 項": "{h} holdings · {w} watching",
  "尚未登記金融資產": "No financial assets yet",
  "回報率 {p}": "Return {p}",
  "全部達標": "All good",
  "數字資產可上架交易": "Digital assets can be listed",
  "讓秘書上架 →": "List via Secretary →",
  "已分潤 {v}": "Distributed {v}",
  "暫無成交": "No trades yet",
  "金融資產組合": "Financial portfolio",
  "行情來自公開接口,可能延遲 · 買賣分紅自動生成記賬憑證": "Quotes from public feeds, may lag · trades & dividends auto-post to GL",
  "持倉": "Holdings", "觀察": "Watching", "全部": "All",
  "總成本": "Total cost", "已實現+分紅": "Realized + dividends", "今日波動": "Day change", "資產配置": "Allocation",
  "類型": "Type", "數量": "Qty", "現價": "Price", "漲跌": "Chg", "市值 CNY": "Value CNY", "交給秘書": "Via Secretary",
  "股票": "Stock", "基金": "Fund", "黃金": "Gold", "加密": "Crypto", "其他": "Other",
  "買": "Buy", "賣": "Sell", "息": "Div",
  "待補代碼": "No symbol", "待刷新": "Stale", "未填代碼": "no symbol",
  "還沒有登記金融資產": "No financial assets registered yet",
  "當前篩選下沒有資產": "No assets under this filter",
  "換個範圍,或直接吩咐秘書。": "Change the scope, or just tell the Secretary.",
  "對秘書說「我買了 100 股◯◯,幫我登記」即可開始。": "Tell the Secretary \"I bought 100 shares of X, register it\" to get started.",
  "讓秘書登記": "Register via Secretary",
  "持有數量": "Quantity", "成本均價": "Avg cost", "現價(原幣)": "Price (ccy)", "今日漲跌": "Day chg", "市值(CNY)": "Value (CNY)", "行情更新": "Quote time",
  "觀察倉 · 只跟蹤行情,不參與記賬": "Watch-only · quotes tracked, no accounting",
  "直接吩咐秘書": "Tell the Secretary",
  "記買入": "Record buy", "記賣出": "Record sell", "記分紅": "Record dividend", "深度解讀": "Deep dive",
  "轉為持倉": "Convert to holding", "補代碼 / 行情": "Fix symbol / quote",
  "2.0 約定:頁面只讀,改動經秘書確認執行,全程留痕。": "2.0 rule: this page is read-only; changes run through the Secretary with a full audit trail.",
  "行情僅供參考,不構成投資建議 · 買賣分紅自動生成記賬憑證,可在財務模塊查賬": "Quotes for reference only, not investment advice · trades & dividends auto-post vouchers, see Finance",
  "數字資產市場": "Digital asset market",
  "條款鋼印 · 擔保交付 · 平台不碰資金": "Sealed terms · guaranteed delivery · platform never touches funds",
  "上架諮詢": "Listing advice",
  "在售 {n} 檔": "{n} live",
  "上架": "Listing", "權益": "Right", "AI 評估": "AI grade", "單價": "Price", "剩餘": "Remaining", "已售": "Sold",
  "《{ti}》": "“{ti}”",
  "使用權": "License", "訂閱": "Subscription", "收益權": "Revenue share", "份額權": "Fractional",
  "面議": "Negotiable", "不限": "Unlimited", "未評估": "Not assessed",
  "{n} 份": "{n} units",
  "詳情": "Details", "購買": "Buy",
  "市場虛位以待": "The market awaits its first listing",
  "確權 → 估值 → 合規 → 上架,秘書全程代辦。": "Rights → valuation → compliance → listing, the Secretary handles it all.",
  "交給秘書上架": "List via Secretary",
  "成交與分潤": "Trades & distribution",
  "最近成交": "Recent trades", "收益與分潤": "Revenue & distribution",
  "記一筆收益": "Record revenue",
  "累計 {v}": "Total {v}", "已分潤": "Distributed",
  "待付分潤": "Distribution due",
  "憑證 #{n}": "Voucher #{n}",
  "買方 {c}": "buyer {c}",
  "待驗收": "Pending acceptance", "已驗收": "Accepted", "爭議": "Disputed",
  "收入": "Revenue", "授權費": "Royalty", "調用費": "Usage fee", "分紅": "Dividend", "成本": "Cost",
  "暫無成交。結算後自動出現在這裡。": "No trades yet. Settlements appear here automatically.",
  "暫無收益事件。": "No revenue events yet.",
  // 秘書指令
  "資產這塊現在有什麼要我拍板的?組合異動、缺代碼缺行情的資產、市場待處理訂單和待付分潤都列出來": "What asset decisions are waiting on me? List portfolio movers, assets missing symbols or quotes, pending market orders and unpaid distributions.",
  "我要記一筆金融資產交易(買入/賣出/分紅),請按資產、數量、成交價或總額、手續費、賬戶、日期逐項追問,確認後登記並生成記賬憑證": "I want to record a financial asset trade (buy/sell/dividend). Ask me for asset, quantity, price or total, fees, account and date one by one, then register it and post the voucher.",
  "我要登記一種金融資產(股票/基金/黃金/加密),請追問名稱、代碼、數量、總成本,確認後登記建檔": "I want to register a financial asset (stock/fund/gold/crypto). Ask me for name, symbol, quantity and total cost, then create it.",
  "我買入了「{name}」({sym}),請追問數量、成交價/總額、手續費、支付賬戶和日期,然後登記並記賬": "I bought \"{name}\" ({sym}). Ask me for quantity, price/total, fees, paying account and date, then register and post it.",
  "我賣出了「{name}」({sym}),請追問數量、成交價/總額、手續費、收款賬戶和日期,計算已實現盈虧並記賬": "I sold \"{name}\" ({sym}). Ask me for quantity, price/total, fees, receiving account and date, compute realized P&L and post it.",
  "「{name}」有分紅/派息,請追問金額、稅費、到賬賬戶和日期,登記並記賬": "\"{name}\" paid a dividend. Ask me for amount, tax, receiving account and date, then register and post it.",
  "請對「{name}」({sym})做深度解讀:先查最新行情與走勢,再跑量化與風險分析,用人話講結論和風險": "Deep-dive \"{name}\" ({sym}): check latest quote and trend, run quant and risk analysis, and explain conclusions and risks in plain words.",
  "「{name}」是觀察倉,我想登記買入轉為持倉:請追問數量、成交價、手續費、賬戶和日期後執行": "\"{name}\" is watch-only. I want to record a buy and convert it to a holding: ask me for quantity, price, fees, account and date, then execute.",
  "「{name}」缺代碼或行情,請搜索候選代碼讓我確認,然後刷新現價、匯率和漲跌幅": "\"{name}\" is missing a symbol or quote. Search candidate symbols for my confirmation, then refresh price, FX and change.",
  "我想把一項數字資產上架交易:請列出已登記資產讓我選,先出 AI 評估與合規預審,再和我確定權益類型與定價,確認後上架": "I want to list a digital asset for trading: show me registered assets to choose from, run the AI assessment and compliance pre-check first, agree right type and pricing with me, then list it.",
  "數字市場上架《{title}》(資產「{a}」,{r},單價 {p}):請調出完整檔案與 AI 評估,幫我判斷值不值得買": "Market listing \"{title}\" (asset \"{a}\", {r}, price {p}): pull its full file and AI assessment and help me judge whether it is worth buying.",
  "我想購買上架《{title}》(單價 {p}):請追問買方名稱、實名聯繫方式和份數,登記訂單並講解受理 → 付款申報 → 收款確認 → 結算交付的流程": "I want to buy listing \"{title}\" (price {p}): ask me for buyer name, verified contact and units, register the order and walk me through review → payment declaration → receipt confirmation → settlement & delivery.",
  "成交 #{id}「{a}」《{ti}》× {u},買方 {c},金額 {amt}:請查交付與驗收狀態,需要我跟進的列出來": "Trade #{id} \"{a}\" listing \"{ti}\" × {u}, buyer {c}, amount {amt}: check delivery and acceptance status and list anything I need to follow up.",
  "收益事件 #{id}({a},{ty},{amt}):請帶出分潤明細與支付狀態,未付的列出應付名單": "Revenue event #{id} ({a}, {ty}, {amt}): show the distribution breakdown and payment status, and list unpaid payees.",
  "我要登記一筆數字資產收益並分潤:請追問是哪個資產、金額、收益來源,登記後把每位持有人的分潤明細列給我": "I want to record a digital asset revenue event and distribute it: ask me which asset, the amount and the source, then register it and show each holder's share.",
});
const { useState: _s, useEffect: _e, useMemo: _mm } = React;
const { Icon: I, Btn: B, Tag: T, Label: LB, Empty: EM, Kpi, StackBar, Folio, Band, pad2, num } = W2;
const ask = (p) => W2.openSecretary(p);

/* ── 格式化(防禦性:任何字段可缺) ── */
const fin = (v) => v != null && Number.isFinite(Number(v));
const cny = (v, d = 0) => fin(v) ? "¥" + Number(v).toLocaleString("zh-CN", { minimumFractionDigits: d, maximumFractionDigits: Math.max(d, 2) }) : "—";
const nfmt = (v, mx = 4) => fin(v) ? Number(v).toLocaleString("zh-CN", { maximumFractionDigits: mx }) : "—";
const pctf = (v) => fin(v) ? (Number(v) >= 0 ? "+" : "") + Number(v).toFixed(2) + "%" : "—";
const toneOf = (v) => fin(v) && Number(v) < 0 ? "var(--red)" : "var(--ink)";
const qtime = (v) => v ? String(v).replace("T", " ").slice(5, 16) : "";
/* KPI 巨型數字用緊湊制:值 + 單位 */
const kfmt = (v) => {
  if (!fin(v)) return ["—", ""];
  const n = Number(v), a = Math.abs(n);
  if (a >= 1e8) return [(n / 1e8).toFixed(a >= 1e10 ? 0 : 2), t("億元")];
  if (a >= 1e4) return [(n / 1e4).toFixed(a >= 1e6 ? 0 : 1), t("萬元")];
  return [Math.round(n).toLocaleString("zh-CN"), t("元")];
};

const TYPE_L = { stock: "股票", fund: "基金", gold: "黃金", crypto: "加密", other: "其他" };
const RIGHT_L = { license: "使用權", subscription: "訂閱", revenue_share: "收益權", fractional: "份額權" };
const EVENT_L = { revenue: "收入", royalty: "授權費", usage_fee: "調用費", dividend: "分紅", cost: "成本" };
const ACCEPT_L = { pending: "待驗收", accepted: "已驗收", disputed: "爭議" };

/* ── 金融資產抽屜 ── */
const AssetDrawer = ({ a, onClose }) => {
  const sym = a.symbol || t("未填代碼");
  const watch = !!a.watch_only;
  const acts = watch ? [
    ["inbound", "轉為持倉", t("「{name}」是觀察倉,我想登記買入轉為持倉:請追問數量、成交價、手續費、賬戶和日期後執行", { name: a.name })],
    ["scan", "補代碼 / 行情", t("「{name}」缺代碼或行情,請搜索候選代碼讓我確認,然後刷新現價、匯率和漲跌幅", { name: a.name })],
    ["sparkle", "深度解讀", t("請對「{name}」({sym})做深度解讀:先查最新行情與走勢,再跑量化與風險分析,用人話講結論和風險", { name: a.name, sym })],
  ] : [
    ["inbound", "記買入", t("我買入了「{name}」({sym}),請追問數量、成交價/總額、手續費、支付賬戶和日期,然後登記並記賬", { name: a.name, sym })],
    ["outbound", "記賣出", t("我賣出了「{name}」({sym}),請追問數量、成交價/總額、手續費、收款賬戶和日期,計算已實現盈虧並記賬", { name: a.name, sym })],
    ["wallet", "記分紅", t("「{name}」有分紅/派息,請追問金額、稅費、到賬賬戶和日期,登記並記賬", { name: a.name })],
    ["sparkle", "深度解讀", t("請對「{name}」({sym})做深度解讀:先查最新行情與走勢,再跑量化與風險分析,用人話講結論和風險", { name: a.name, sym })],
  ];
  const cells = [
    [t("持有數量"), watch ? "—" : nfmt(a.quantity)],
    [t("成本均價"), watch ? "—" : cny(a.avg_cost_cny, 2)],
    [t("現價(原幣)"), fin(a.last_price) ? nfmt(a.last_price) + " " + (a.last_price_currency || "") : "—"],
    [t("今日漲跌"), pctf(a.last_change_pct)],
    [t("市值(CNY)"), watch ? "—" : cny(a.market_value_cny)],
    [t("浮動盈虧"), watch ? "—" : cny(a.unrealized_pnl_cny)],
  ];
  return (
    <div className="drawer">
      <div style={{ padding: "16px 18px", borderBottom: "2px solid var(--rule)" }}>
        <div className="row spread" style={{ marginBottom: 10 }}>
          <T tone={watch ? "plain" : (fin(a.last_change_pct) && Number(a.last_change_pct) < 0 ? "bad" : "ok")} dot>
            {watch ? t("觀察") : t("持倉")}
          </T>
          <button className="btn ghost sm" style={{ padding: "0 7px" }} onClick={onClose} title="Esc"><I name="x" size={13}/></button>
        </div>
        <div style={{ fontSize: 19, fontWeight: 750, letterSpacing: "-.025em", lineHeight: 1.25 }}>{a.name || "—"}</div>
        <div className="num muted" style={{ fontSize: 11.5, marginTop: 5 }}>{sym} · {t(TYPE_L[a.asset_type] || a.asset_type || "其他")}</div>
        {watch && <div className="muted" style={{ fontSize: 10.5, marginTop: 8 }}>{t("觀察倉 · 只跟蹤行情,不參與記賬")}</div>}
      </div>
      <div style={{ padding: 18, maxHeight: "calc(100vh - 280px)", overflowY: "auto" }}>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14, marginBottom: 18 }}>
          {cells.map(([k, v]) => (
            <div key={k} className="col g4" style={{ borderTop: "1px solid var(--hair)", paddingTop: 8 }}>
              <LB dim style={{ fontSize: 8.5 }}>{k}</LB>
              <span className="num" style={{ fontSize: 14, fontWeight: 650, color: k === t("浮動盈虧") || k === t("今日漲跌") ? toneOf(k === t("今日漲跌") ? a.last_change_pct : a.unrealized_pnl_cny) : "var(--ink)" }}>{v}</span>
            </div>
          ))}
        </div>
        {a.last_quote_at && (
          <div className="row g8" style={{ marginBottom: 16 }}>
            <LB dim style={{ fontSize: 8.5 }}>{t("行情更新")}</LB>
            <span className="num muted" style={{ fontSize: 11 }}>{qtime(a.last_quote_at)}</span>
          </div>
        )}
        <LB dim style={{ fontSize: 8.5, marginBottom: 8 }}>{t("直接吩咐秘書")}</LB>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
          {acts.map(([icon, label, prompt]) => (
            <button key={label} className="btn" style={{ height: 40, justifyContent: "flex-start", fontSize: 12.5 }} onClick={() => ask(prompt)}>
              <I name={icon} size={14}/>{t(label)}
            </button>
          ))}
        </div>
        <div className="muted" style={{ fontSize: 10.5, marginTop: 12, lineHeight: 1.6 }}>{t("2.0 約定:頁面只讀,改動經秘書確認執行,全程留痕。")}</div>
      </div>
    </div>
  );
};

/* ── 09 · 資產 ── */
const Page = ({ boot }) => {
  const [assets, setAssets] = _s(null);      // /api/assets → {assets:[]}
  const [pf, setPf] = _s(null);              // /api/assets/portfolio
  const [listings, setListings] = _s(null);  // /api/digital-assets/listings
  const [trades, setTrades] = _s(null);      // /api/digital-assets/trades
  const [rev, setRev] = _s(null);            // /api/digital-assets/revenue
  const [scope, setScope] = _s("all");
  const [sel, setSel] = _s(null);

  _e(() => {
    W2.json("/api/assets").then(d => setAssets((d && d.assets) || [])).catch(() => setAssets([]));
    W2.json("/api/assets/portfolio").then(d => setPf(d || {})).catch(() => setPf({}));
    W2.json("/api/digital-assets/listings?status=listed&limit=100").then(d => setListings((d && d.listings) || [])).catch(() => setListings([]));
    W2.json("/api/digital-assets/trades?limit=50").then(d => setTrades(d || {})).catch(() => setTrades({}));
    W2.json("/api/digital-assets/revenue?limit=50").then(d => setRev(d || {})).catch(() => setRev({}));
    const h = (e) => { if (e.key === "Escape") setSel(null); };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, []);

  const all = assets || [];
  const P = pf || {};
  const holdings = all.filter(a => !a.watch_only);
  const watching = all.filter(a => !!a.watch_only);
  const list = scope === "hold" ? holdings : scope === "watch" ? watching : all;
  const live = listings || [];
  const tradeRows = (trades && trades.trades) || [];
  const revRows = (rev && rev.events) || [];

  const pnl = fin(P.unrealized_pnl_cny) ? Number(P.unrealized_pnl_cny) : null;
  const retPct = pnl != null && fin(P.total_cost_cny) && Number(P.total_cost_cny) ? pnl / Number(P.total_cost_cny) * 100 : null;
  const [mvV, mvU] = kfmt(P.total_value_cny);
  const [pnlV, pnlU] = kfmt(pnl);
  const [trdV, trdU] = kfmt(trades && trades.total_amount_cny);
  const distTotal = rev && rev.total_distributed_cny;

  const stack = _mm(() => (Array.isArray(P.allocation) ? P.allocation : [])
    .filter(s => num(s.value_cny) > 0)
    .map((s, i) => ({ value: num(s.value_cny), color: W2.CHART_COLORS[i % W2.CHART_COLORS.length], label: t(TYPE_L[s.type] || s.label || s.type || "其他"), pct: s.pct })), [pf]);

  const askListing = (l, buy) => ask(buy
    ? t("我想購買上架《{title}》(單價 {p}):請追問買方名稱、實名聯繫方式和份數,登記訂單並講解受理 → 付款申報 → 收款確認 → 結算交付的流程", { title: l.title || "—", p: fin(l.price_cny) ? cny(l.price_cny) : t("面議") })
    : t("數字市場上架《{title}》(資產「{a}」,{r},單價 {p}):請調出完整檔案與 AI 評估,幫我判斷值不值得買", { title: l.title || "—", a: l.asset_name || "—", r: t(RIGHT_L[l.listing_type] || l.listing_type || "—"), p: fin(l.price_cny) ? cny(l.price_cny) : t("面議") }));

  return (<>
    <Folio no="09" en="ASSETS" title={t("資產")}
      sub={t("金融資產組合 + 數字資產市場 · 頁面只讀,交易與上架全交秘書")}
      right={<>
        <B icon="plus" onClick={() => ask(t("我要記一筆金融資產交易(買入/賣出/分紅),請按資產、數量、成交價或總額、手續費、賬戶、日期逐項追問,確認後登記並生成記賬憑證"))}>{t("記一筆交易")}</B>
        <B kind="primary" icon="sparkle" onClick={() => ask(t("資產這塊現在有什麼要我拍板的?組合異動、缺代碼缺行情的資產、市場待處理訂單和待付分潤都列出來"))}>{t("問秘書")}</B>
      </>}/>

    <div className="kpi-band">
      <Kpi label={t("金融資產市值")} value={mvV} unit={mvU} delay={0}
        foot={all.length
          ? <span className="muted" style={{ fontSize: 11.5 }}>{t("持倉 {h} 項 · 觀察 {w} 項", { h: holdings.length, w: watching.length })}</span>
          : <span className="muted" style={{ fontSize: 11.5 }}>{t("尚未登記金融資產")}</span>}/>
      <Kpi label={t("浮動盈虧")} value={pnlV} unit={pnlU} red={pnl != null && pnl < 0} delay={.05}
        foot={retPct != null
          ? <T tone={retPct < 0 ? "bad" : "ok"} dot>{t("回報率 {p}", { p: pctf(retPct) })}</T>
          : <span className="muted" style={{ fontSize: 11.5 }}>—</span>}/>
      <Kpi label={t("市場在售")} value={live.length} unit={t("檔")} delay={.1}
        foot={live.length
          ? <span className="muted" style={{ fontSize: 11.5 }}>{t("數字資產可上架交易")}</span>
          : <button className="tag inv" style={{ cursor: "pointer" }} onClick={() => ask(t("我想把一項數字資產上架交易:請列出已登記資產讓我選,先出 AI 評估與合規預審,再和我確定權益類型與定價,確認後上架"))}>{t("讓秘書上架 →")}</button>}/>
      <Kpi label={t("累計成交")} value={trdV} unit={trdU} delay={.15}
        foot={fin(distTotal) && Number(distTotal) > 0
          ? <span className="muted num" style={{ fontSize: 11.5 }}>{t("已分潤 {v}", { v: cny(distTotal) })}</span>
          : <span className="muted" style={{ fontSize: 11.5 }}>{tradeRows.length ? "" : t("暫無成交")}</span>}/>
    </div>

    {/* ═══ Band 01 · 金融資產組合 ═══ */}
    <Band no="01" title={t("金融資產組合")} sub={t("行情來自公開接口,可能延遲 · 買賣分紅自動生成記賬憑證")} delay={.1}
      right={<div className="seg">
        {[["all", "全部"], ["hold", "持倉"], ["watch", "觀察"]].map(([id, label]) => (
          <button key={id} className={scope === id ? "on" : ""} onClick={() => { setScope(id); setSel(null); }}>{t(label)}</button>
        ))}
      </div>}>
      {!all.length ? (
        <EM icon="chart" title={t("還沒有登記金融資產")} sub={t("對秘書說「我買了 100 股◯◯,幫我登記」即可開始。")}
          action={<B icon="sparkle" size="sm" onClick={() => ask(t("我要登記一種金融資產(股票/基金/黃金/加密),請追問名稱、代碼、數量、總成本,確認後登記建檔"))}>{t("讓秘書登記")}</B>}/>
      ) : (<>
        <div className="row g24 wrap" style={{ marginBottom: 18, alignItems: "stretch" }}>
          {[
            [t("總成本"), cny(P.total_cost_cny), "var(--ink)"],
            [t("已實現+分紅"), cny(fin(P.realized_pnl_cny) || fin(P.dividends_cny) ? (Number(P.realized_pnl_cny) || 0) + (Number(P.dividends_cny) || 0) : null), toneOf(P.realized_pnl_cny)],
            [t("今日波動"), cny(P.day_change_cny), toneOf(P.day_change_cny)],
          ].map(([k, v, tone]) => (
            <div key={k} className="col g4" style={{ borderTop: "1px solid var(--hair)", paddingTop: 8, minWidth: 130 }}>
              <LB dim style={{ fontSize: 8.5 }}>{k}</LB>
              <span className="num" style={{ fontSize: 17, fontWeight: 700, color: tone }}>{v}</span>
            </div>
          ))}
          {!!stack.length && (
            <div className="col g8" style={{ flex: 1, minWidth: 260, borderTop: "1px solid var(--hair)", paddingTop: 8 }}>
              <LB dim style={{ fontSize: 8.5 }}>{t("資產配置")}</LB>
              <StackBar data={stack}/>
              <div className="row g12 wrap" style={{ fontSize: 11.5 }}>
                {stack.map(s => (
                  <span key={s.label} className="row g6">
                    <span style={{ width: 9, height: 9, background: s.color, flexShrink: 0 }}/>
                    <span className="ink2">{s.label}</span>
                    <span className="num muted">{fin(s.pct) ? s.pct + "%" : ""}</span>
                  </span>
                ))}
              </div>
            </div>
          )}
        </div>

        <div style={{ display: "flex", gap: 24, alignItems: "flex-start" }}>
          <div style={{ flex: 1, minWidth: 0, overflowX: "auto" }}>
            <table className="tbl2">
              <thead><tr>
                <th style={{ width: 34 }}>#</th><th>{t("資產")}</th><th>{t("類型")}</th><th>{t("數量")}</th><th>{t("現價")}</th><th>{t("漲跌")}</th><th>{t("市值 CNY")}</th><th>{t("浮動盈虧")}</th><th style={{ width: 128 }}>{t("交給秘書")}</th>
              </tr></thead>
              <tbody>
                {list.map((a, i) => {
                  const watch = !!a.watch_only;
                  const sym = a.symbol || t("未填代碼");
                  return (
                    <tr key={a.id || i} className={sel && sel.id === a.id ? "on" : ""} style={{ cursor: "pointer" }} onClick={() => setSel(a)}>
                      <td className="num muted" style={{ fontSize: 11 }}>{pad2(i + 1)}</td>
                      <td>
                        <div className="col g4">
                          <span className="row g8" style={{ fontWeight: 650 }}>{a.name || "—"}{watch && <T tone="plain">{t("觀察")}</T>}</span>
                          <span className="num muted" style={{ fontSize: 11 }}>{sym}</span>
                        </div>
                      </td>
                      <td className="muted">{t(TYPE_L[a.asset_type] || a.asset_type || "其他")}</td>
                      <td className="num">{watch ? "—" : nfmt(a.quantity)}</td>
                      <td>
                        {!a.symbol ? <T tone="warn">{t("待補代碼")}</T>
                          : !fin(a.last_price) ? <T tone="plain">{t("待刷新")}</T>
                          : <div className="col g2">
                              <span className="num" style={{ fontWeight: 600 }}>{nfmt(a.last_price)} <span className="muted" style={{ fontSize: 10.5 }}>{a.last_price_currency || ""}</span></span>
                              {a.last_quote_at && <span className="num muted" style={{ fontSize: 10 }}>{qtime(a.last_quote_at)}</span>}
                            </div>}
                      </td>
                      <td className="num" style={{ fontWeight: 700, color: toneOf(a.last_change_pct) }}>{pctf(a.last_change_pct)}</td>
                      <td className="num" style={{ fontWeight: 650 }}>{watch ? "—" : cny(a.market_value_cny)}</td>
                      <td className="num" style={{ fontWeight: 700, color: toneOf(a.unrealized_pnl_cny) }}>
                        {watch ? "—" : <>{cny(a.unrealized_pnl_cny)}{fin(a.unrealized_pnl_pct) ? <span className="muted" style={{ fontWeight: 400, fontSize: 11 }}> ({pctf(a.unrealized_pnl_pct)})</span> : null}</>}
                      </td>
                      <td onClick={e => e.stopPropagation()}>
                        <div className="row g4">
                          <button className="btn sm" style={{ padding: "0 9px" }} title={t("記買入")}
                            onClick={() => ask(watch
                              ? t("「{name}」是觀察倉,我想登記買入轉為持倉:請追問數量、成交價、手續費、賬戶和日期後執行", { name: a.name })
                              : t("我買入了「{name}」({sym}),請追問數量、成交價/總額、手續費、支付賬戶和日期,然後登記並記賬", { name: a.name, sym }))}>{t("買")}</button>
                          {!watch && <button className="btn sm" style={{ padding: "0 9px" }} title={t("記賣出")}
                            onClick={() => ask(t("我賣出了「{name}」({sym}),請追問數量、成交價/總額、手續費、收款賬戶和日期,計算已實現盈虧並記賬", { name: a.name, sym }))}>{t("賣")}</button>}
                          {!watch && <button className="btn sm" style={{ padding: "0 9px" }} title={t("記分紅")}
                            onClick={() => ask(t("「{name}」有分紅/派息,請追問金額、稅費、到賬賬戶和日期,登記並記賬", { name: a.name }))}>{t("息")}</button>}
                          <button className="btn sm" style={{ padding: "0 8px" }} title={t("深度解讀")}
                            onClick={() => ask(t("請對「{name}」({sym})做深度解讀:先查最新行情與走勢,再跑量化與風險分析,用人話講結論和風險", { name: a.name, sym }))}><I name="sparkle" size={12}/></button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
            {!list.length && <EM icon="search" title={t("當前篩選下沒有資產")} sub={t("換個範圍,或直接吩咐秘書。")}/>}
            <div className="muted" style={{ fontSize: 10.5, marginTop: 12 }}>{t("行情僅供參考,不構成投資建議 · 買賣分紅自動生成記賬憑證,可在財務模塊查賬")}</div>
          </div>
          {sel && <AssetDrawer a={sel} onClose={() => setSel(null)}/>}
        </div>
      </>)}
    </Band>

    {/* ═══ Band 02 · 數字資產市場 ═══ */}
    <Band no="02" title={t("數字資產市場")} sub={t("條款鋼印 · 擔保交付 · 平台不碰資金")} delay={.15}
      right={<B size="sm" icon="sparkle" onClick={() => ask(t("我想把一項數字資產上架交易:請列出已登記資產讓我選,先出 AI 評估與合規預審,再和我確定權益類型與定價,確認後上架"))}>{t("上架諮詢")}</B>}>
      {!live.length ? (
        <EM icon="layers" title={t("市場虛位以待")} sub={t("確權 → 估值 → 合規 → 上架,秘書全程代辦。")}
          action={<B icon="sparkle" size="sm" onClick={() => ask(t("我想把一項數字資產上架交易:請列出已登記資產讓我選,先出 AI 評估與合規預審,再和我確定權益類型與定價,確認後上架"))}>{t("交給秘書上架")}</B>}/>
      ) : (
        <div style={{ overflowX: "auto" }}>
          <table className="tbl2">
            <thead><tr>
              <th style={{ width: 34 }}>#</th><th>{t("上架")}</th><th>{t("權益")}</th><th>{t("AI 評估")}</th><th>{t("單價")}</th><th>{t("剩餘")}</th><th>{t("已售")}</th><th style={{ width: 150 }}>{t("交給秘書")}</th>
            </tr></thead>
            <tbody>
              {live.map((l, i) => {
                const as = l.assessment;
                const soldPct = fin(l.units_offered) && Number(l.units_offered) > 0
                  ? Math.min(100, Math.round(100 * (Number(l.units_sold) || 0) / Number(l.units_offered))) : null;
                return (
                  <tr key={l.id || i}>
                    <td className="num muted" style={{ fontSize: 11 }}>{pad2(i + 1)}</td>
                    <td>
                      <div className="col g4" style={{ minWidth: 0 }}>
                        <span style={{ fontWeight: 650 }}>{t("《{ti}》", { ti: l.title || "—" })}</span>
                        <span className="num muted" style={{ fontSize: 11 }}>{l.asset_no ? l.asset_no + " · " : ""}{l.asset_name || "—"}</span>
                      </div>
                    </td>
                    <td><T tone="plain">{t(RIGHT_L[l.listing_type] || l.listing_type || "—")}</T></td>
                    <td>{as && as.grade
                      ? <T tone="inv">AI·{as.grade}{fin(as.overall_score) ? " · " + as.overall_score : (fin(as.score) ? " · " + as.score : "")}</T>
                      : <span className="muted" style={{ fontSize: 11.5 }}>{t("未評估")}</span>}</td>
                    <td className="num" style={{ fontWeight: 700 }}>{fin(l.price_cny) ? cny(l.price_cny) : t("面議")}</td>
                    <td className="num">{l.units_remaining == null ? t("不限") : t("{n} 份", { n: nfmt(l.units_remaining) })}</td>
                    <td>
                      {soldPct == null ? <span className="muted" style={{ fontSize: 11 }}>—</span>
                        : <div className="col g4" style={{ width: 90 }}>
                            <div className="bar"><i style={{ width: soldPct + "%", background: "var(--ink)" }}/></div>
                            <span className="num muted" style={{ fontSize: 10 }}>{soldPct}%</span>
                          </div>}
                    </td>
                    <td>
                      <div className="row g4">
                        <button className="btn sm" onClick={() => askListing(l, false)}>{t("詳情")}</button>
                        <button className="btn sm" onClick={() => askListing(l, true)}><I name="sparkle" size={11}/>{t("購買")}</button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}
    </Band>

    {/* ═══ Band 03 · 成交與分潤 ═══ */}
    <Band no="03" title={t("成交與分潤")}
      sub={fin(trades && trades.total_amount_cny) && Number(trades.total_amount_cny) > 0 ? t("累計 {v}", { v: cny(trades.total_amount_cny) }) : null} delay={.2}
      right={<B size="sm" icon="plus" onClick={() => ask(t("我要登記一筆數字資產收益並分潤:請追問是哪個資產、金額、收益來源,登記後把每位持有人的分潤明細列給我"))}>{t("記一筆收益")}</B>}>
      <div style={{ display: "grid", gridTemplateColumns: "1.15fr 1fr", gap: 0 }}>
        <div style={{ paddingRight: 28 }}>
          <div className="row spread" style={{ borderBottom: "2px solid var(--rule)", paddingBottom: 8 }}>
            <LB>{t("最近成交")}</LB>
            <span className="num muted" style={{ fontSize: 11 }}>{tradeRows.length}</span>
          </div>
          {!tradeRows.length && <div className="muted" style={{ fontSize: 12, padding: "16px 0" }}>{t("暫無成交。結算後自動出現在這裡。")}</div>}
          {tradeRows.slice(0, 8).map((tr, i) => {
            const st = ACCEPT_L[tr.acceptance_status];
            return (
              <div key={tr.id || i} className="ledger-row">
                <span className="lr-idx">{pad2(i + 1)}</span>
                <div className="col g4" style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ fontWeight: 650, fontSize: 13, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                    {tr.asset_name || "—"}{t("《{ti}》", { ti: tr.listing_title || "—" })}{fin(tr.units) ? " × " + nfmt(tr.units) : ""}
                  </span>
                  <span className="muted num" style={{ fontSize: 11 }}>
                    {t("買方 {c}", { c: tr.counterparty_name || "—" })} · {(tr.settled_at || tr.created_at || "").slice(0, 10) || "—"}
                    {tr.voucher_id ? " · " + t("憑證 #{n}", { n: tr.voucher_id }) : ""}
                  </span>
                </div>
                {st && <T tone={tr.acceptance_status === "disputed" ? "bad" : tr.acceptance_status === "accepted" ? "ok" : "plain"} dot={tr.acceptance_status === "disputed"}>{t(st)}</T>}
                <span className="num" style={{ fontWeight: 700 }}>{cny(tr.amount_cny)}</span>
                <button className="btn sm" style={{ padding: "0 8px" }} title={t("問秘書")}
                  onClick={() => ask(t("成交 #{id}「{a}」《{ti}》× {u},買方 {c},金額 {amt}:請查交付與驗收狀態,需要我跟進的列出來",
                    { id: tr.id || "—", a: tr.asset_name || "—", ti: tr.listing_title || "—", u: nfmt(tr.units), c: tr.counterparty_name || "—", amt: cny(tr.amount_cny) }))}>
                  <I name="sparkle" size={12}/>
                </button>
              </div>
            );
          })}
        </div>
        <div style={{ paddingLeft: 28, borderLeft: "1px solid var(--hair)" }}>
          <div className="row spread" style={{ borderBottom: "2px solid var(--rule)", paddingBottom: 8 }}>
            <LB>{t("收益與分潤")}</LB>
            {fin(distTotal) && Number(distTotal) > 0 && <span className="num muted" style={{ fontSize: 11 }}>{t("已分潤")} {cny(distTotal)}</span>}
          </div>
          {!revRows.length && <div className="muted" style={{ fontSize: 12, padding: "16px 0" }}>{t("暫無收益事件。")}</div>}
          {revRows.slice(0, 8).map((ev, i) => {
            const alloc = ev.allocation || {};
            const hasAlloc = Array.isArray(alloc.allocations) && alloc.allocations.length > 0;
            return (
              <div key={ev.id || i} className="ledger-row">
                <span className="lr-idx">{pad2(i + 1)}</span>
                <div className="col g4" style={{ flex: 1, minWidth: 0 }}>
                  <span className="row g8" style={{ fontWeight: 650, fontSize: 13 }}>
                    <T tone={ev.event_type === "cost" ? "warn" : "plain"}>{t(EVENT_L[ev.event_type] || ev.event_type || "收入")}</T>
                    <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{ev.asset_name || "—"}</span>
                  </span>
                  <span className="muted num" style={{ fontSize: 11 }}>{(ev.created_at || "").slice(0, 10) || "—"}{ev.source_ref ? " · " + ev.source_ref : ""}</span>
                </div>
                {hasAlloc && (alloc.paid ? <T tone="ok" dot>{t("已分潤")}</T> : <T tone="bad" dot>{t("待付分潤")}</T>)}
                <span className="num" style={{ fontWeight: 700, color: ev.event_type === "cost" ? "var(--red)" : "var(--ink)" }}>{cny(ev.amount_cny)}</span>
                <button className="btn sm" style={{ padding: "0 8px" }} title={t("問秘書")}
                  onClick={() => ask(t("收益事件 #{id}({a},{ty},{amt}):請帶出分潤明細與支付狀態,未付的列出應付名單",
                    { id: ev.id || "—", a: ev.asset_name || "—", ty: t(EVENT_L[ev.event_type] || ev.event_type || "收入"), amt: cny(ev.amount_cny) }))}>
                  <I name="sparkle" size={12}/>
                </button>
              </div>
            );
          })}
        </div>
      </div>
    </Band>
  </>);
};

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