/* ZY console — TikTok Shop COO 日报仪表盘（tiktok_shop_operations_daily_digest.v1）。
   Reminder-only：不代写业务，卡片动作只有「去 Seller Center 深链」+ 唯一例外 creator-invite（生成命令，不在 UI 执行）。
   null ≠ 0：null 渲染弱化「–」，0 渲染平静；attention 项按严重度上色。 */
const DSTT = window.ZYDesignSystem_d746df;

const TT_URGENT = new Set(["orders:ship_within_24h", "orders:auto_cancel_within_24h", "after_sales:respond_within_24h", "customer_service:urgent", "customer_service:expired", "affiliate:about_to_expire"]);
const TT_PENALTY = new Set(["store_health:needs_improvement", "store_health:product_violations"]);
// 枚举 → 中文：统一走共享 CN_LABELS（KitParts.jsx），不在本文件另起并行字典。
// ttL(k) 查不到中文时回退原键（宁可回退也不崩），但字典缺项应补进 CN_LABELS。
function ttL(k) { return (window.CN_LABELS && window.CN_LABELS[k]) || k; }
const TT_AREA_LABEL = { store_overview: "店铺总览", orders: "订单", after_sales: "售后", products: "商品", store_health: "店铺健康", customer_service: "客服", affiliate: "联盟", controlled_write_audit: "受控写审计", controlled_write: "受控写" };
const TT_AREA_ORDER = ["store_overview", "orders", "after_sales", "products", "store_health", "customer_service", "affiliate"];
const TT_BASE = "https://seller-my.tiktok.com";
// 受控写动作目录（v2 §7/§9）· 本 COO 店铺运营域真正能「动手」的写 = 2 笔（改价 / 上下架）。
// 退款＝读+提醒（不可逆，故意不自动化）；样品评审属达人 profile 域，皆不在本审计卡的动作集。
const TT_ACTION_LABEL = { tiktok_shop_price_change: "改价", tiktok_shop_listing_status_change: "上下架" };
const TT_WSTATUS_LABEL = { confirmed: "已确认", failed: "失败", unknown: "写态未知" };
// 改价 / 上下架 均可逆（回 before_price / before_status）；本 COO 无不可逆写动作。
const TT_IRREVERSIBLE = new Set();
function ttSev(area, key) {
  const full = area + ":" + key;
  if (TT_URGENT.has(full) || TT_PENALTY.has(full)) return "red";
  return "amber";
}
function ttLink(area, id) {
  switch (area) {
    case "store_overview": return TT_BASE + "/homepage";
    case "orders": return TT_BASE + "/order?tab=to_ship";
    case "after_sales": return TT_BASE + "/order/return";
    case "products": return TT_BASE + "/product";
    case "store_health": return TT_BASE + "/health-center";
    case "customer_service": return TT_BASE + "/chat/inbox/current?oec_seller_id=" + id;
    case "affiliate": return "https://affiliate.tiktok.com/connection/target-invitation?shop_id=" + id;
    default: return TT_BASE + "/homepage";
  }
}

// 计数 chip：null→「–」弱化；0→平静；attention 项上色。attention 项可点→深链 Seller Center
function TTCount({ area, k, v, attn, shopId }) {
  const isAtt = attn && attn.indexOf(k) >= 0 && (v || 0) > 0;
  const sev = isAtt ? ttSev(area, k) : null;
  const [flash, setFlash] = React.useState(false);
  const cls = "ttc" + (sev ? " ttc--" + sev : "") + (v === 0 ? " ttc--zero" : "");
  const inner = (
    <React.Fragment>
      <span className="ttc__v num">{v == null ? <span className="ttnull">–</span> : v}</span>
      <span className="ttc__l">{flash ? "已打开 ↗" : (ttL(k))}</span>
    </React.Fragment>
  );
  if (isAtt && shopId != null) {
    const go = () => { try { window.open(ttLink(area, shopId), "_blank", "noopener"); } catch (e) {} setFlash(true); setTimeout(() => setFlash(false), 1500); };
    return <button className={cls + " ttc--act"} onClick={go} title="去 Seller Center 处理该项 ↗">{inner}</button>;
  }
  return <div className={cls}>{inner}</div>;
}

function TTCard({ area, title, icon, time, shopId, children }) {
  const { Icon } = DSTT;
  const [flash, setFlash] = React.useState(false);
  const href = ttLink(area, shopId);
  const onGo = () => { setFlash(true); setTimeout(() => setFlash(false), 1700); };
  return (
    <div className="ttcard" id={"tt-" + area}>
      <div className="ttcard__h">
        <span className="ttcard__ic"><Icon name={icon} size={16} /></span>
        <span className="ttcard__title">{title}</span>
        <span className="ttcard__time"><Icon name="Clock" size={11} />{time}</span>
        <span className="ttcard__ro"><Icon name="Eye" size={11} />只读</span>
      </div>
      <div className="ttcard__body">{children}</div>
      <a className={"ttlink" + (flash ? " is-go" : "")} href={href} target="_blank" rel="noopener noreferrer" onClick={onGo} title={href}>
        {flash ? "已在新标签打开 Seller Center" : "去 Seller Center 处理"}<Icon name={flash ? "Check" : "ArrowUpRight"} size={13} />
      </a>
    </div>
  );
}

function KitTiktok() {
  const { Icon, Pill, Card } = DSTT;
  const K = window.KIT, D = K.tiktokDigest, A = D.areas;
  const cwa = A.controlled_write_audit;
  const rpt = K.tiktokCooDailyReport;
  const [invite, setInvite] = React.useState(false);
  const [openTask, setOpenTask] = React.useState(null);
  // Hermes 反馈本地乐观态（原型：真实 POST 在服务端逐日 09:30 生效；此处仅回显"已反馈✓明日生效"）。
  // §9 交付态：共享 feedback 路由「先 mock」，故不发真实网络写，仅本地记录被恢复的抑制项。
  const [restored, setRestored] = React.useState({});

  // read-model B（tiktok_shop_coo_daily_report.v1）→ 共享 KitHermesAssistantPanel 的 prop 形状。
  const hermes = React.useMemo(() => {
    if (!rpt || !rpt.exists) return null;
    const la = rpt.learning_applied || {};
    const supRaw = rpt.suppressed || [];
    return {
      summary: {
        learned_total: la.active_memory_total,
        suppressed_this_round: supRaw.length,
        resolved_history_count: la.resolution_hints,
        pending_candidates: (rpt.candidates_created || []).length,
        pending_candidates_cumulative: rpt.pending_review_total,
        suppressed_items: supRaw
          .filter(it => !restored[it.area + ":" + it.key])
          .map(it => ({ area: TT_AREA_LABEL[it.area] || it.area, key: ttL(it.key), reason: it.suppressed_reason })),
      },
      attentionItems: (rpt.attention || []).map(it => ({
        area: it.area, key: it.area + ":" + it.key,
        areaLabel: it.areaLabel || ((TT_AREA_LABEL[it.area] || it.area) + " · " + ttL(it.key)),
        recommended_action_from_history: it.recommended_action_from_history,
        knowledge_note: it.knowledge_note,
      })),
    };
  }, [rpt, restored]);

  const scrollTo = (area) => {
    const el = document.getElementById("tt-" + area);
    const sc = document.querySelector(".scroll");
    if (el && sc) sc.scrollTo({ top: el.offsetTop - 16, behavior: "smooth" });
    if (el) { el.classList.add("ttcard--flash"); setTimeout(() => el.classList.remove("ttcard--flash"), 1200); }
  };

  const caps = D.attention.map(full => {
    const [area, key] = full.split(":");
    const red = TT_URGENT.has(full) || TT_PENALTY.has(full) || /^controlled_write:(failed|unknown)/.test(full);
    return { full, area, key, red };
  }).sort((a, b) => (b.red - a.red));

  const so = A.store_overview, od = A.orders, as = A.after_sales, pr = A.products, sh = A.store_health, cs = A.customer_service, af = A.affiliate;
  const healthPct = Math.min(100, Math.round(sh.violation_score / sh.restriction_threshold * 100));
  const healthNear = sh.violation_score >= sh.restriction_threshold * 0.7;

  return (
    <div className="view viewfade">
      <Card className="ovstrip">
        <div className="ovstrip__head">
          <span className="ovstrip__orb"><Icon name="ShoppingBag" size={20} /></span>
          <div className="ovstrip__id">
            <div className="ovstrip__title">TikTok Shop COO · 日报{<span className="ovstrip__mode"><span className="ovstrip__dot" />读优先 · 受控写门控</span>}</div>
            <div className="ovstrip__judge">LIEE FLAT · {D.shop_region} 店 · 只读聚合快照（无明细 / 无 PII）· 2 笔受控写（改价 / 上下架）走引擎决策面（老板拍板），驾驶舱不放执行按钮，只以脱敏回执回显</div>
          </div>
          <div className="ovstrip__src">
            <span className="ovstrip__srclabel">数据源</span>
            <span className="ovstrip__srcval">TikTok Shop COO 日报（只读聚合）</span>
            <Pill tone="neutral" soft>先 mock（受控写审计已上线）</Pill>
            <Pill tone="good" soft>只读 · 无业务写</Pill>
          </div>
        </div>
        <div className="pqhead">
          <Icon name="Megaphone" size={16} />
          <span className="pqhead__t">{caps.length > 0 ? "现在该处理 " + caps.length + " 项" : "全部清空 ✅"}</span>
          <span className="pqhead__at"><Icon name="Clock" size={12} />快照 {D.captured_at} · {D.shop_region}</span>
        </div>
      </Card>

      {/* ATTENTION 条 */}
      <Card>
        <SectionHeadTT />
        {caps.length > 0 ? (
          <div className="ttatt">
            {caps.map(c => (
              <button key={c.full} className={"ttcap ttcap--" + (c.red ? "red" : "amber")} onClick={() => scrollTo(c.area)}>
                <span className="ttcap__dot" />
                <span className="ttcap__area">{TT_AREA_LABEL[c.area]}</span>
                <span className="ttcap__k">{ttL(c.key)}</span>
              </button>
            ))}
          </div>
        ) : <div className="emptyrow"><Icon name="CircleCheck" size={16} />全部清空，无需处理</div>}
      </Card>

      {/* Hermes 副手 · 复盘与建议（read-model B · advisory-only · 零业务写 · 与 🔒 受控写视觉分离） */}
      {hermes ? (
        <React.Fragment>
          <window.KitHermesAssistantPanel
            summary={hermes.summary}
            attentionItems={hermes.attentionItems}
            onTeach={() => { /* 原型：真实 POST 服务端生效；共享面板已本地回显「已反馈✓明日生效」 */ }}
            onRestore={(it) => {
              // 面板已中文化 area/key；靠原始 suppressed 逆查回原枚举键做去重标记。
              const raw = (rpt.suppressed || []).find(s => (TT_AREA_LABEL[s.area] || s.area) === it.area && ttL(s.key) === it.key);
              if (raw) setRestored(r => ({ ...r, [raw.area + ":" + raw.key]: true }));
            }}
          />
          <div className="powarn" style={{ margin: "-2px 0 2px", fontSize: 11.5 }}>
            <Icon name="Info" size={13} />副手为顾问角色（advisory）· 不做任何业务写 · 反馈次日 09:30 日报生效 · 共享 feedback 路由先 mock，此处仅本地乐观回显。
          </div>
        </React.Fragment>
      ) : (
        <Card>
          <div className="sechead"><div className="sechead__l"><span className="sechead__ic"><Icon name="Sparkles" size={15} /></span><div><div className="sechead__t">Hermes 副手 · 复盘与建议</div></div></div></div>
          <div className="emptyrow"><Icon name="Inbox" size={14} />尚无数据</div>
        </Card>
      )}

      {/* 7 张区域卡 */}
      <div className="ttgrid">
        <TTCard area="store_overview" title="店铺总览" icon="LayoutGrid" time={so.captured_at} shopId={D.shop_id}>
          <div className="ttcgrid">
            {Object.entries(so.exception_cards).map(([k, v]) => <TTCount key={k} area="store_overview" k={k} v={v} attn={so.attention} shopId={D.shop_id} />)}
          </div>
          <div className="ttperf">
            {[["gmv", "GMV"], ["customers", "客户数"], ["sku_orders", "SKU订单"], ["visitors", "访客数"]].map(([k, lab]) => (
              <div className="ttperf__i" key={k}><span className="ttperf__v num">{so.performance[k] == null ? "–" : so.performance[k]}</span><span className="ttperf__l">{lab}</span></div>
            ))}
          </div>
        </TTCard>

        <TTCard area="orders" title="订单" icon="ScrollText" time={od.captured_at} shopId={D.shop_id}>
          <div className="ttcgrid">
            {Object.entries(od.risk_counters).map(([k, v]) => <TTCount key={k} area="orders" k={k} v={v} attn={od.attention} shopId={D.shop_id} />)}
          </div>
          <div className="ttbadges">
            <span className="ttbadges__cap">状态分布</span>
            {Object.entries(od.status_tab_counts).map(([k, v]) => (
              <span className="ttbadge" key={k}>{ttL(k)}<b className="num">{v == null ? "–" : v}</b></span>
            ))}
            <span className="ttbadge ttbadge--stat">次日准时率<b className="num">{od.next_day_on_time_rate || "--%"}</b></span>
          </div>
        </TTCard>

        <TTCard area="after_sales" title="售后" icon="Undo2" time={as.captured_at} shopId={D.shop_id}>
          <div className="ttcgrid">
            {Object.entries(as.sla_cards).map(([k, v]) => <TTCount key={k} area="after_sales" k={k} v={v} attn={as.attention} shopId={D.shop_id} />)}
          </div>
          <div className="ttbadges">
            <span className="ttbadges__cap">状态分布</span>
            {Object.entries(as.status_tab_counts).map(([k, v]) => (
              <span className="ttbadge" key={k}>{ttL(k)}<b className="num">{v == null ? "–" : v}</b></span>
            ))}
          </div>
        </TTCard>

        <TTCard area="products" title="商品" icon="Package" time={pr.captured_at} shopId={D.shop_id}>
          <div className="ttbadges">
            <span className="ttbadges__cap">在售状态</span>
            {Object.entries(pr.listing_tab_counts).map(([k, v]) => {
              const att = pr.attention.indexOf(k) >= 0 && (v || 0) > 0;
              return <span className={"ttbadge" + (att ? " ttbadge--amber" : "")} key={k}>{ttL(k)}<b className="num">{v == null ? "–" : v}</b></span>;
            })}
          </div>
          <div className="ttcgrid" style={{ marginTop: 11 }}>
            <TTCount area="products" k="sold_out" v={pr.sold_out} attn={pr.sold_out > 0 ? ["sold_out"] : []} shopId={D.shop_id} />
          </div>
        </TTCard>

        <TTCard area="store_health" title="店铺健康" icon="ShieldCheck" time={sh.captured_at} shopId={D.shop_id}>
          <div className="tthealth">
            <div className="tthealth__top">
              <span className="tthealth__lab">违规分 / 限制阈值</span>
              <span className="tthealth__val num">{sh.violation_score} <span className="pqmuted">/ {sh.restriction_threshold}</span></span>
            </div>
            <div className="tthbar"><span className={"tthbar__fill" + (healthNear ? " is-near" : "")} style={{ width: healthPct + "%" }} /></div>
          </div>
          <div className="ttflags">
            {sh.needs_improvement && <span className="ttflag ttflag--red"><Icon name="Ban" size={12} />店铺处罚中</span>}
            <span className={"ttflag" + (sh.product_violations > 0 ? " ttflag--amber" : "")}><Icon name="AlertTriangle" size={12} />商品违规 {sh.product_violations}</span>
            {sh.unread_violation_record && <span className="ttflag ttflag--amber"><Icon name="Bell" size={12} />有未读违规记录</span>}
          </div>
        </TTCard>

        <TTCard area="customer_service" title="客服" icon="MessageSquare" time={cs.captured_at} shopId={D.shop_id}>
          <div className="ttscope"><Icon name="Filter" size={12} />口径：已分配给我</div>
          <div className="ttcgrid">
            {Object.entries(cs.status_filters).map(([k, v]) => <TTCount key={k} area="customer_service" k={k} v={v} attn={cs.attention} shopId={D.shop_id} />)}
          </div>
        </TTCard>

        <TTCard area="affiliate" title="联盟" icon="Users" time={af.captured_at} shopId={D.shop_id}>
          <div className="ttvol">
            <div className="ttvol__i"><span className="ttvol__v num">{af.invitation_counts.ongoing}</span><span className="ttvol__l">进行中</span></div>
            <div className="ttvol__i"><span className="ttvol__v num">{af.invitation_counts.completed}</span><span className="ttvol__l">已完成</span></div>
          </div>
          <div className="ttcgrid">
            <TTCount area="affiliate" k="about_to_expire" v={af.invitation_counts.about_to_expire} attn={af.attention} shopId={D.shop_id} />
            <TTCount area="affiliate" k="cancelling" v={af.invitation_counts.cancelling} attn={af.invitation_counts.cancelling > 0 ? ["cancelling"] : []} shopId={D.shop_id} />
          </div>
          <button className="ttinvite" onClick={() => setInvite(true)}><Icon name="UserPlus" size={14} />生成批量邀约命令<span className="ttinvite__note">唯一写动作 · operator 终端运行</span></button>
        </TTCard>
      </div>

      {/* 第 8 张卡 · 受控写回执审计（脱敏）— v2 §4末 / §9 */}
      <Card>
        <div className="sechead">
          <div className="sechead__l">
            <span className="sechead__ic"><Icon name="ClipboardCheck" size={15} /></span>
            <div><div className="sechead__t">受控写回执 · 审计（脱敏）</div></div>
          </div>
          <span className="spchip spchip--write" style={{ marginLeft: "auto" }}><Icon name="PenLine" size={11} />含受控写</span>
        </div>
        <div className="powarn powarn--warn" style={{ margin: "4px 0 12px" }}><Icon name="Info" size={14} />聚合器待建 · 以下为契约示例回执<span className="spsample" style={{ marginLeft: 6 }}>示例</span>。2 笔受控写（改价 / 上下架）在引擎 / 老板决策面真实产出，落盘聚合后接入本卡。</div>
        <div className="ttbadges">
          <span className="ttbadges__cap">本窗 {cwa.window}</span>
          <span className="ttbadge ttbadge--stat">今窗写入<b className="num">{cwa.writes_total}</b></span>
          <span className={"ttbadge" + (cwa.by_write_status.failed > 0 ? " ttbadge--red" : "")}>失败<b className="num">{cwa.by_write_status.failed}</b></span>
          <span className={"ttbadge" + (cwa.by_write_status.unknown > 0 ? " ttbadge--red" : "")}>写态未知<b className="num">{cwa.by_write_status.unknown}</b></span>
          <span className="ttbadge">已确认<b className="num">{cwa.by_write_status.confirmed}</b></span>
        </div>
        <div className="ttbadges" style={{ marginTop: 8 }}>
          <span className="ttbadges__cap">按动作</span>
          {Object.entries(cwa.by_action).map(([k, v]) => (
            <span className="ttbadge" key={k}>{TT_ACTION_LABEL[k] || k}<b className="num">{v}</b></span>
          ))}
        </div>
        {cwa.writes_total === 0
          ? <div className="emptyrow" style={{ marginTop: 11 }}><Icon name="Inbox" size={14} />尚无受控写记录</div>
          : <div className="spaudit" style={{ marginTop: 11 }}>
              {cwa.entries.map(e => {
                const open = openTask === e.task_id;
                const sev = (e.write_status === "failed" || e.write_status === "unknown") ? "red" : "green";
                const irr = TT_IRREVERSIBLE.has(e.action_key);
                return (
                  <div className={"spaudit__row spaudit__row--" + sev} key={e.task_id}>
                    <button className="spaudit__head" onClick={() => setOpenTask(open ? null : e.task_id)}>
                      <span className={"spaudit__light spaudit__light--" + sev} />
                      <span className="spaudit__lane">{TT_ACTION_LABEL[e.action_key] || e.action_key}</span>
                      <span className="spaudit__wt">{TT_WSTATUS_LABEL[e.write_status] || e.write_status}{e.readback_confirmed ? " · readback✓" : ""}</span>
                      {e.rolled_back && <span className="ttflag ttflag--amber" style={{ flexShrink: 0 }}>已回滚</span>}
                      {irr
                        ? <span className="ttflag" style={{ flexShrink: 0 }}>已落地不可撤</span>
                        : <span className="ttflag ttflag--ok" style={{ flexShrink: 0 }}>可回滚</span>}
                      <Icon name={open ? "ChevronDown" : "ChevronRight"} size={14} />
                    </button>
                    {open && (
                      <div className="spaudit__detail">
                        <div className="spaudit__kv"><span>action_key</span><b className="num">{e.action_key}</b></div>
                        <div className="spaudit__kv"><span>task_id</span><b className="num">{e.task_id}</b></div>
                        <div className="spaudit__kv"><span>decision_ref</span><b className="num">{e.decision_ref}</b></div>
                        <div className="spaudit__kv"><span>approved_by</span><b>{e.approved_by}</b></div>
                        <div className="spaudit__kv"><span>readback</span><b>{e.readback_confirmed ? "已回读确认" : "未确认"}</b></div>
                        <div className="spaudit__kv"><span>mutation_risk</span><b>{e.mutation_risk}</b></div>
                        <div className="spaudit__kv"><span>可逆性</span><b>{e.reversible ? "可回滚" : "不可逆"}</b></div>
                        <div className="spaudit__note"><Icon name="ShieldCheck" size={11} />脱敏：不含 product_id / sku_id / 现价新价 / 金额。逐产品明细在老板决策面（深链）。</div>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>}
      </Card>

      {invite && <window.KitCreatorInvite shopId={D.shop_id} onClose={() => setInvite(false)} />}
    </div>
  );
}

function SectionHeadTT() {
  const { Icon } = DSTT;
  return (
    <div className="sechead">
      <div className="sechead__l">
        <span className="sechead__ic"><Icon name="Megaphone" size={15} /></span>
        <div><div className="sechead__t">ATTENTION · 现在该处理什么</div><div className="sechead__s">由各区 attention 聚合 · 红=时间紧迫/处罚 · 琥珀=一般待办 · 点胶囊跳到对应卡</div></div>
      </div>
    </div>
  );
}
function KitCreatorInvite({ shopId, onClose }) {
  const { Icon } = DSTT;
  const [rate, setRate] = React.useState(15);
  const [adsRate, setAdsRate] = React.useState(10);
  const [levels, setLevels] = React.useState([8, 7, 6]);
  const [batches, setBatches] = React.useState(3);
  const [ignorePrev, setIgnorePrev] = React.useState(false);
  const [copied, setCopied] = React.useState(false);
  const ALL = [8, 7, 6, 5, 4];
  const toggleLv = (l) => setLevels(ls => ls.indexOf(l) >= 0 ? ls.filter(x => x !== l) : [...ls, l].sort((a, b) => b - a));
  const cmd = "node tools/invite2.js --rate " + rate + " --ads-rate " + adsRate
    + (levels.length ? " --level " + [...levels].sort((a, b) => b - a).join(",") : "")
    + " --batches " + batches + (ignorePrev ? " --ignore-prev" : "");
  const copy = () => { try { navigator.clipboard.writeText(cmd); } catch (e) {} setCopied(true); setTimeout(() => setCopied(false), 1500); };

  return (
    <div className="camodal__scrim" onClick={onClose}>
      <div className="camodal" onClick={e => e.stopPropagation()}>
        <div className="camodal__head">
          <span className="camodal__ic"><Icon name="UserPlus" size={20} /></span>
          <div><div className="camodal__t">生成批量邀约命令</div><div className="camodal__sub">creator_invite · skills/creator-invite（invite2）· 唯一写动作</div></div>
          <button className="camodal__x" onClick={onClose}><Icon name="X" size={17} /></button>
        </div>
        <div className="camodal__body">
          <div className="powarn powarn--warn"><Icon name="ShieldAlert" size={14} />UI 不直接发起真实邀约。此处仅生成命令，由 operator 在终端显式运行。</div>
          <div className="poinput"><span className="poinput__l">佣金率 commission_rate</span>
            <span className="poinput__in"><input className="poinput__i" type="number" value={rate} onChange={e => setRate(Number(e.target.value))} /><span className="poinput__u">%</span></span></div>
          <div className="poinput"><span className="poinput__l">广告佣金 ads_commission_rate</span>
            <span className="poinput__in"><input className="poinput__i" type="number" value={adsRate} onChange={e => setAdsRate(Number(e.target.value))} /><span className="poinput__u">%</span></span></div>
          <div>
            <div className="caphrase__l" style={{ marginBottom: 7 }}>达人等级 levels</div>
            <div className="ttlv">{ALL.map(l => <button key={l} className={"ttlvb" + (levels.indexOf(l) >= 0 ? " is-on" : "")} onClick={() => toggleLv(l)}>L{l}</button>)}</div>
          </div>
          <div className="poinput"><span className="poinput__l">批次数 batches</span>
            <span className="poinput__in"><input className="poinput__i" type="number" value={batches} onChange={e => setBatches(Number(e.target.value))} /><span className="poinput__u">批</span></span></div>
          <label className="ttchk"><input type="checkbox" checked={ignorePrev} onChange={e => setIgnorePrev(e.target.checked)} /><span>忽略历史已邀约（--ignore-prev）</span></label>
          <div className="popayload">
            <div className="popayload__cap"><Icon name="Terminal" size={12} />生成命令（在 operator 终端运行）</div>
            <pre>{cmd}</pre>
          </div>
        </div>
        <div className="camodal__foot">
          <span className="camodal__note"><Icon name="Info" size={13} />命令不在前端执行</span>
          <span style={{ display: "flex", gap: 8 }}>
            <button className="btn btn--ghost" onClick={onClose}>关闭</button>
            <button className="btn btn--solid" onClick={copy}>{copied ? "已复制 ✓" : "复制命令"}</button>
          </span>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { KitTiktok, KitCreatorInvite });
