// ============================================================
// stages.jsx — Workflow stage views
// ============================================================
// Stages:
//   home       — Agent hero/intro
//   analyzing  — 商品分析进行中
//   analyzed   — 商品分析完成 + 11 种出图类型选择
//   supplement — 资料补充表单
//   replanning — 图片内容分析（短暂）
//   plans      — 出图方案已生成 (9 plans, 21 imgs)
//   model      — 选择生图模型
//   generating — 批量生成
// ============================================================

const { useState: _useState, useEffect: _useEffect } = React;

// ---------- Step Progress (调度→思考→构建→完成) ----------
function StepProgress({ active, done }) {
  const STEPS = ['调度', '思考', '构建', '完成'];
  const progress = active === 0 ? 0 : active === 1 ? 33 : active === 2 ? 66 : 100;
  return (
    <div className="stepper" style={{'--progress': progress + '%'}}>
      {STEPS.map((s, i) => {
        let cls = '';
        if (i < active) cls = 'done';
        else if (i === active) cls = 'active';
        return (
          <div key={s} className={'step-node ' + cls}>
            <div className="step-dot"></div>
            <div className="step-label">{s}</div>
          </div>
        );
      })}
    </div>
  );
}

// ============================================================
// HOME — Agent intro hero with feature carousel
// ============================================================

const HOME_FEATURES = [
  { num: '01', title: '商品智能分析', desc: '上传图片+描述，AI 自动识别商…', icon: <Ico.Image />, color: 'amber' },
  { num: '02', title: '出图需求智能推荐', desc: 'AI 按类目推荐 · 主图 / 详情页 / 营…', icon: <Ico.Grid />, color: 'amber' },
  { num: '03', title: '风格方案 · 逐张可控', desc: '选风格 · 定方案 · 每张图的画面和…', icon: <Ico.Layers />, color: 'amber' },
  { num: '04', title: '批量生成 · 审阅微调', desc: '并发出图 · 质量自检 · 不满意一键…', icon: <Ico.Wave />, color: 'amber' },
];

function HomeStage({ onStart, mode, setMode }) {
  const [active, setActive] = _useState(1);
  const f = HOME_FEATURES[active];
  return (
    <>
      <div className="hero">
        <div className="hero-features">
          {HOME_FEATURES.map((feat, i) => (
            <div key={i}
                 className={'feature-pill ' + (i === active ? 'active' : '')}
                 onClick={() => setActive(i)}>
              <div className="feature-pill-num">{feat.num}</div>
              <div className="feature-pill-body">
                <div className="feature-pill-title">{feat.title}</div>
                <div className="feature-pill-desc">{feat.desc}</div>
              </div>
              <div className="feature-pill-arrow"><Ico.ArrowRight /></div>
            </div>
          ))}
        </div>
        <div className="hero-stage">
          <div className="hero-tagline">AI 智能体 · 多轮对话 · 每步可控</div>
          <h1 className="hero-title">电商一键生图</h1>
          <p className="hero-subtitle">上传商品图片和信息，AI 自动识别商品、规划出图方案、并发出图并质量自检 — 一站完成主图、详情页、白底、种草等全套素材。</p>
          <div className="hero-capabilities">
            <span className="capability-pill"><Ico.ArrowUp /> 上传商品 · AI 自动识别</span>
            <span className="capability-pill"><Ico.Chat /> 多轮对话 · 精准补全</span>
            <span className="capability-pill"><Ico.Spark /> 智能推荐 · 自由选择</span>
            <span className="capability-pill"><Ico.Check /> 每步可控 · 一键出图</span>
          </div>
          <div className="hero-preview">
            <div className="hero-preview-num">{f.num}</div>
            <div className="hero-preview-tag">
              <Ico.Spark /> AI 驱动
            </div>
            <div className="hero-preview-icon">{f.icon}</div>
            <div className="hero-preview-body">
              <div className="hero-preview-title">{f.title}</div>
              <div className="hero-preview-chips">
                <span className="preview-chip">类目推荐</span>
                <span className="preview-chip">自由勾选</span>
                <span className="preview-chip">数量可调</span>
                <span className="preview-chip">全类型覆盖</span>
              </div>
            </div>
          </div>
          <div className="hero-dots">
            {HOME_FEATURES.map((_, i) =>
              <div key={i} className={'hero-dot ' + (i === active ? 'active' : '')} onClick={() => setActive(i)}/>
            )}
          </div>
        </div>
      </div>
      <Composer mode={mode} setMode={setMode} showStack={false} />
    </>
  );
}

// ============================================================
// ANALYZING — 商品分析中 (stepper card)
// ============================================================

function AnalyzingStage({ productThumbs }) {
  return (
    <div className="stepper-card">
      <div className="stepper-card-label">商品分析 · 智能解读</div>
      <div className="stepper-card-title">
        <span className="equalizer"><span></span><span></span><span></span></span>
        正在构建商品分析方案…
      </div>
      <StepProgress active={2} />
    </div>
  );
}

// ============================================================
// ANALYZED — 商品分析结果 + 出图类型选择 (11 types)
// ============================================================

const TYPE_CARDS = [
  { id: 'main', tags: [['必选','tag-must'],['高转化','tag-conv']], priority: 'high',
    title: '商品主图（多角度轮播）',
    desc: '采用正方形 1:1 构图，制作多张轮播主图，分别展示角色正面全身、半身近景、眨眼动态款及干净留白款；整体保持软萌、治愈、二次元感强的视觉风格，突出角色完整轮廓与高颜值设定。',
    insight: '该商品的核心吸引力首先来自角色形象本身，主图必须把银白长发、黑色蝴蝶结、白裙和黑兔玩偶这些记忆点完整呈现出来。',
    channels: [['全平台','all'],['淘宝/天猫','tmall'],['京东','jd'],['+5','']],
    note: '点击率提升关键' },
  { id: 'white', tags: [['必选','tag-must'],['平台必需','tag-platform']], priority: 'high',
    title: '白底图',
    desc: '纯白背景、主体居中、边缘干净，优先展示完整角色立绘或成品单体，不加复杂装饰与文案；确保发丝、裙摆、黑兔玩偶等细节清楚可辨，适合平台审核与搜索展示。',
    insight: '这类二次元周边商品在多数平台都需要标准化展示图，白底图能清晰交代角色外轮廓、配色和主体完整度。',
    channels: [['淘宝/天猫','tmall'],['京东','jd'],['拼多多','pdd'],['+2','']],
    note: '搜索流量入口' },
  { id: 'variant', tags: [['推荐','tag-rec'],['高转化','tag-conv']], priority: 'high',
    title: '款式版本对比图',
    desc: '将眨眼挥手款、抱黑兔正视款、全身款等不同画面统一排版，对比展示可选图案/姿势/裁切比例；若商品有单张、多张套组、不同编号，也应在此图中明确区分。',
    insight: '当前素材里已出现不同姿态与构图，买家会非常在意是否只有单一图案，版本展示能直接降低咨询成本。',
    channels: [['全平台','all'],['淘宝/天猫','tmall'],['拼多多','pdd'],['+2','']],
    note: '减少决策犹豫，提升下单效率' },
  { id: 'detail', tags: [['推荐','tag-rec'],['高转化','tag-conv']], priority: 'high', selected: true,
    title: '角色细节特写图',
    desc: '对角色面部表情、银白发丝、黑色蝴蝶结、白裙褶皱、黑兔玩偶进行局部特写放大；画面可搭配简洁标注，强调线条干净、色彩柔和、印刷/呈现细腻。',
    insight: '该角色卖点高度依赖画风精致度，必须通过局部放大证明眼睛高光、发丝层次、裙褶和玩偶细节足够精美。',
    channels: [['全平台','all'],['淘宝/天猫','tmall'],['京东','jd'],['+2','']],
    note: '详情页转化核心' },
  { id: 'size', tags: [['推荐','tag-rec'],['平台必需','tag-platform']], priority: 'mid',
    title: '尺寸规格说明图',
    desc: '用统一标尺或人物手持比例展示商品长宽厚度，多 SKU 则做对比图；标明可定制尺寸范围、最小/最大尺寸；用极简版式避免与角色主视觉冲突。',
    insight: '尺寸和材质是二次元周边的高频询单问题，"图大不大、能挂书包不能"在二次元周边里属于刚需决策信息。',
    channels: [['淘宝/天猫','tmall'],['京东','jd'],['抖店','dy'],['+1','']],
    note: '降低咨询率、提升转化' },
  { id: 'mat', tags: [['推荐','tag-rec'],['平台必需','tag-platform']], priority: 'mid',
    title: '材质工艺展示图',
    desc: '根据实际商品材质展示对应工艺，如 PET 亮膜防水贴纸、亚克力厚度透光质感、徽章金属边光泽、布艺纹理细节；以微距构图突出工艺。',
    insight: '"画质好不好、会不会褪色、会不会粘到水就坏"是二次元周边买家最关心的问题，工艺展示能直接转化犹豫客户。',
    channels: [['全平台','all'],['淘宝/天猫','tmall'],['小红书','xhs'],['+2','']],
    note: '感知价值溢价' },
  { id: 'scene', tags: [['推荐','tag-rec']], priority: 'mid',
    title: '使用场景种草图',
    desc: '结合实际商品形态制作场景图，如贴纸在笔记本/水杯/手机壳上的应用，挂件挂在书包/痛包上的实拍感，配以浅色调治愈氛围，突出"日常陪伴"。',
    insight: '场景图把"想象中如何用"变成"我也想要"，对二次元用户尤其有效。',
    channels: [['淘宝/天猫','tmall'],['小红书','xhs'],['抖店','dy'],['+1','']],
    note: '提升加购率与种草指数' },
  { id: 'pack', tags: [['推荐','tag-rec'],['平台必需','tag-platform']], priority: 'mid',
    title: '包装与赠品展示图',
    desc: '展示包装袋、背卡、封套、保护膜、赠品小卡等内容；若有随机赠送贴纸、明信片、防刮包装等，也应整合呈现，风格保持干净可爱。',
    insight: '二次元周边消费中，开箱感和送礼感会显著影响好评与复购，尤其适合礼赠、收藏和社交分享。',
    channels: [['全平台','all'],['淘宝/天猫','tmall'],['抖店','dy'],['+2','']],
    note: '提升感知价值和晒单率' },
  { id: 'rules', tags: [['推荐','tag-rec'],['平台必需','tag-platform']], priority: 'mid',
    title: '购买须知 / 定制说明图',
    desc: '清晰说明购买内容、单张/套组区别、是否含配件、是否支持改尺寸或改底材、发货方式与注意事项；信息分区排版，避免与角色主视觉冲突。',
    insight: '若该商品支持不同尺寸、不同底材或定制组合，提前讲清规则能减少客服沟通并避免误拍。',
    channels: [['淘宝/天猫','tmall'],['拼多多','pdd'],['抖店','dy'],['+1','']],
    note: '减少咨询成本、提升成交效率' },
  { id: 'compare', tags: [['差异化','tag-diff'],['提升点击率','tag-click']], priority: 'low',
    title: '同类差异化卖点图',
    desc: '用简洁图表或关键词形式，对比普通二次元图案与本款在发丝细节、角色辨识度、配色统一度、留白干净度上的优势，避免夸张宣传。',
    insight: '对于二次元受众，横向比较"可爱度、精致度、场景适配性"有助于突出本款更软萌、更适合做头像/周边的优势。',
    channels: [['淘宝/天猫','tmall'],['京东','jd'],['小红书','xhs'],['+1','']],
    note: '强化记忆点、提高转化说服力' },
  { id: 'promo', tags: [['差异化','tag-diff'],['提升点击率','tag-click']], priority: 'low',
    title: '节日 / 联名促销主视觉',
    desc: '围绕季节、节日或 IP 联名做定制视觉，保持角色记忆点不变，叠加节日元素如雪花、樱花、烟花等，作为活动主图与社媒投放素材。',
    insight: '节日热点能短期提升流量峰值，叠加 IP 联名进一步抬升客单价。',
    channels: [['淘宝/天猫','tmall'],['抖店','dy'],['小红书','xhs'],['+1','']],
    note: '助攻大促与节日转化' },
];

function AnalyzedStage({ selected, onToggle, onConfirm }) {
  return (
    <>
      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot active">!</div>
          <div>
            <div className="stage-marker-title">商品分析完成</div>
            <div className="stage-marker-sub">已为您规划 11 种出图类型，请勾选需要的类型</div>
          </div>
        </div>
        <div className="analysis-block">
          <p>从图片信息看，这款商品的核心并不是通用人物插画，而是以<span className="hl">"穹妹"Q 版萌系形象</span>为卖点的二次元周边视觉内容。角色特征非常明确：<strong>银白长发、黑色蝴蝶结、白色裙装、黑兔玩偶</strong>，整体气质偏软萌、治愈、轻哥特感，视觉识别度高。</p>
          <p>目前素材里既有<strong>正面抱兔款</strong>，也有<strong>眨眼挥手款</strong>和<strong>全身站立款</strong>，说明该商品天然适合做"多版本/多姿态"展示，而不是只放一张单图。对于二次元用户来说，决定下单的关键通常是<strong>角色还原度、细节精致度、可选款式和成品适配场景</strong>。</p>
          <p>因此推荐方案会把<span className="hl">主图、白底图、版本对比图、细节特写图、尺寸规格图</span>放在优先级最高的位置，先解决点击与转化；再补充<strong>材质工艺、场景种草、包装赠品、设定氛围</strong>等内容，放大这类萌系 IP/角色周边的情绪价值与收藏属性。</p>
          <p>如果该商品最终落地为<strong>贴纸、挂件、徽章、立牌、印花类定制品</strong>，这套出图逻辑都能直接适配，只需把尺寸、材质和佩戴/摆放场景替换成对应实物即可。</p>
        </div>
      </div>

      <div className="row-between" style={{margin: '24px 0 12px'}}>
        <div style={{fontSize: 15, fontWeight: 600}}>选择需要生成的图片类型</div>
        <div className="row" style={{gap: 8}}>
          <button className="btn btn-outline" style={{padding: '7px 14px'}}>
            <Ico.Lamp /> 智能推荐
          </button>
          <button className="btn btn-ghost" style={{padding: '7px 14px'}}>
            <Ico.X /> 清空选择
          </button>
          <span style={{fontSize: 12, color: 'var(--text-2)'}}>已选 {selected.size} / 11</span>
        </div>
      </div>

      <div className="type-grid">
        {TYPE_CARDS.map(c => (
          <div key={c.id}
               className={'type-card ' + (selected.has(c.id) ? 'selected' : '')}
               onClick={() => onToggle(c.id)}>
            <div className="type-card-check">{selected.has(c.id) && <Ico.Check />}</div>
            <div className="type-card-tags">
              {c.tags.map(([t, cls], i) => <span key={i} className={'tag ' + cls}>{t}</span>)}
            </div>
            <div className="type-card-title">{c.title}</div>
            <div className="type-card-desc">{c.desc}</div>
            <div className="type-card-insight">{c.insight}</div>
            <div className="type-card-footer">
              <div className="type-card-channels">
                {c.channels.map(([t, cls], i) => <span key={i} className={'channel-chip ' + cls}>{t}</span>)}
              </div>
              <span className={'priority-pill ' + c.priority}>
                {c.priority === 'high' ? '高' : c.priority === 'mid' ? '中' : '低'}
              </span>
            </div>
            <div className="type-card-note">{c.note}</div>
          </div>
        ))}
      </div>

      <div className="stage-section" style={{marginTop: 24}}>
        <div className="row-between" style={{alignItems: 'flex-start'}}>
          <div style={{flex: 1}}>
            <div style={{fontSize: 13, color: 'var(--text-2)', marginBottom: 6}}>有其他想法？</div>
            <input
              className="form-textarea"
              style={{minHeight: 44, padding: '12px 14px'}}
              placeholder="输入建议后按回车重新分析…"
            />
          </div>
          <div className="row" style={{gap: 8, marginLeft: 16, marginTop: 22}}>
            <button className="btn btn-outline"><Ico.Lamp /> 智能推荐</button>
            <button className="btn btn-ghost"><Ico.X /> 清空选择</button>
            <button className="btn btn-primary" onClick={onConfirm}>
              确认选择并继续 <Ico.ArrowRight />
            </button>
          </div>
        </div>
      </div>
    </>
  );
}

// ============================================================
// SUPPLEMENT — Resource补充表单
// ============================================================

const SUPPLEMENT_QUESTIONS = {
  product: [
    ['A', '贴纸/标签类', '适合延展白底图、尺寸图、使用场景图和购买须知图。', true],
    ['B', '亚克力挂件/钥匙扣类', '需要重点展示挂孔、扣件、厚度和包挂场景。', false],
    ['C', '亚克力立牌/摆件类', '需要展示底座、站立效果和桌面摆放场景。', false],
    ['D', '徽章/胸章类', '需要突出金属边缘、别针结构和痛包佩戴场景。', false],
    ['E', '服饰/布艺印花类', '需要体现布面纹理、印花范围和上身/平铺效果。', false],
    ['F', '其他，请在下方文字补充说明', '便于我按你的商品结构定制后续画面逻辑。', false],
  ],
  scenes: [
    ['A', '奶白治愈系桌面/收藏场景', '更适合小红书、抖店等种草氛围，画面会更柔和治愈。', true],
    ['B', '书包/痛包/钥匙等随身挂饰场景', '适合贴纸、挂件、徽章等二次元周边的常见展示方式。', true],
    ['C', '电脑/平板/水杯等物品装饰场景', '适合贴纸、水杯贴、电脑贴等商品的实用代入感展示。', false],
    ['D', '礼物/开箱分享场景', '更偏送礼与开箱展示，适合包装与赠品图。', false],
    ['E', '极简电商陈列场景', '整体更偏货架展示与电商成交效率。', false],
  ],
  size: [
    ['A', '单一固定尺寸', '方便制作标准化尺寸规格图，适合固定商品。', true],
    ['B', '多个尺寸可选', '需要做多规格分档展示，适合不同尺寸可选商品。', false],
    ['C', '支持定制尺寸', '需在购买须知中突出"可定制范围与起订量"。', false],
  ],
};

function SupplementStage({ onSubmit, selected }) {
  const [answers, setAnswers] = _useState({
    product: 'A', scenes: ['A', 'B'], size: 'A',
    spec: '', pack: '',
  });
  const setSingle = (k, v) => setAnswers({ ...answers, [k]: v });
  const toggleMulti = (k, v) => {
    const set = new Set(answers[k]);
    set.has(v) ? set.delete(v) : set.add(v);
    setAnswers({ ...answers, [k]: [...set] });
  };

  // Build the summary card showing selections
  const selectedTypes = TYPE_CARDS.filter(c => selected.has(c.id));

  return (
    <>
      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot success"><Ico.Check /></div>
          <div style={{flex: 1}}>
            <div className="stage-marker-title">已选择出图类型</div>
            <div className="summary-card success" style={{marginTop: 12}}>
              <div className="summary-head">
                <div className="summary-icon"><Ico.Grid /></div>
                <div style={{flex: 1}}>
                  <div className="summary-confirm-pill"><Ico.Check /> 已确认</div>
                  <div className="summary-title">出图类型方案</div>
                  <div className="summary-stats">
                    <span><Ico.Grid /> {selectedTypes.length}种类型</span>
                    <span><Ico.Target /> 8 个平台</span>
                    <span><Ico.Spark /> {selectedTypes.filter(t => t.priority === 'high').length} 项高优</span>
                  </div>
                </div>
              </div>
              <div className="summary-chips">
                {selectedTypes.slice(0, 9).map((t, i) => (
                  <div key={t.id} className={'summary-chip c-' + ['cyan','green','violet','amber','rose','blue','pink','orange','cyan'][i % 9]}>
                    <div className="summary-chip-title">{t.title}</div>
                    <div className="summary-chip-desc">{t.desc.slice(0, 18)}…</div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot active">!</div>
          <div style={{flex: 1}}>
            <div className="stage-marker-title row-between">
              <span>请补充商品资料</span>
              <button className="btn btn-ghost" style={{padding: '6px 12px', fontSize: 12}}>
                <Ico.Refresh /> 回退
              </button>
            </div>
            <div className="stage-marker-sub">共 5 个选择题、1 个补充图片、2 个文本输入</div>
            <div className="analysis-block" style={{marginTop: 12, fontSize: 13}}>
              <p>当前素材已经足够支撑<span className="hl-cyan">角色视觉类</span>图片制作，比如主图、白底图、版本对比和细节特写；角色形象也比较统一，基础风格判断没有问题。</p>
              <p>但你这次选择的 {selectedTypes.length} 种出图里，包含了<strong>尺寸规格、材质工艺、使用场景、包装赠品、购买须知/定制说明</strong>等强依赖商品实物信息的内容。现有图片更像角色图案素材，尚无法准确判断它最终是贴纸、挂件、立牌还是其他周边，也缺少规格、材质和包装规则。</p>
              <p>为了后续一次性把整套图片做准，我建议你补充下面这些关键信息；填完后就能直接进入更稳定的生图执行。</p>
            </div>
          </div>
        </div>
      </div>

      <div className="form-question">
        <div className="form-question-title">
          <span className="form-question-num">1</span>
          这组"穹妹"图案最终要做成哪一类商品？
          <span className="form-question-type">单选</span>
        </div>
        {SUPPLEMENT_QUESTIONS.product.map(([letter, title, desc, rec]) => (
          <div key={letter}
               className={'form-option ' + (answers.product === letter ? 'selected' : '')}
               onClick={() => setSingle('product', letter)}>
            <div className="form-option-radio">
              {answers.product === letter && <Ico.Check />}
            </div>
            <div className="form-option-letter">{letter}</div>
            <div className="form-option-body">
              <div className="form-option-title">
                {title}
                {rec && <span className="form-option-rec">推荐</span>}
              </div>
              <div className="form-option-desc">{desc}</div>
            </div>
          </div>
        ))}
        <input className="form-textarea" style={{minHeight: 38, marginTop: 6}} placeholder="补充输入（可选）…" />
      </div>

      <div className="form-question">
        <div className="form-question-title">
          <span className="form-question-num">2</span>
          你希望"使用场景种草图"重点往哪些场景方向出？
          <span className="form-question-type" style={{background: 'var(--cyan-dim)', color: 'var(--cyan)'}}>多选</span>
        </div>
        {SUPPLEMENT_QUESTIONS.scenes.map(([letter, title, desc, rec]) => (
          <div key={letter}
               className={'form-option ' + (answers.scenes.includes(letter) ? 'selected' : '')}
               onClick={() => toggleMulti('scenes', letter)}>
            <div className="form-option-radio">
              {answers.scenes.includes(letter) && <Ico.Check />}
            </div>
            <div className="form-option-letter">{letter}</div>
            <div className="form-option-body">
              <div className="form-option-title">
                {title}
                {rec && <span className="form-option-rec">推荐</span>}
              </div>
              <div className="form-option-desc">{desc}</div>
            </div>
          </div>
        ))}
      </div>

      <div className="form-question">
        <div className="form-question-title">
          <span className="form-question-num">3</span>
          这款商品的规格模式是哪个方向？
          <span className="form-question-type">单选</span>
        </div>
        {SUPPLEMENT_QUESTIONS.size.map(([letter, title, desc, rec]) => (
          <div key={letter}
               className={'form-option ' + (answers.size === letter ? 'selected' : '')}
               onClick={() => setSingle('size', letter)}>
            <div className="form-option-radio">
              {answers.size === letter && <Ico.Check />}
            </div>
            <div className="form-option-letter">{letter}</div>
            <div className="form-option-body">
              <div className="form-option-title">
                {title}
                {rec && <span className="form-option-rec">推荐</span>}
              </div>
              <div className="form-option-desc">{desc}</div>
            </div>
          </div>
        ))}
      </div>

      <div className="form-question">
        <div className="form-question-title">
          <Ico.Image /> 补充图片
          <span className="form-question-type" style={{background: 'rgba(255,255,255,0.05)', color: 'var(--text-2)'}}>可跳过</span>
        </div>
        <div style={{display: 'grid', gridTemplateColumns: '300px 1fr', gap: 16}}>
          <div className="image-dropzone">
            <div className="image-dropzone-inner">
              <div className="image-dropzone-icon"><Ico.Plus /></div>
              <div style={{fontSize: 12}}>点击上传</div>
            </div>
          </div>
          <div style={{fontSize: 12, color: 'var(--text-2)', lineHeight: 1.7}}>
            <div style={{color: 'var(--text-0)', fontWeight: 600, marginBottom: 6, fontSize: 13}}>补充 1 张商品成品实拍图</div>
            请补充 1 张<strong style={{color: 'var(--text-1)'}}>商品成品实拍图</strong>，优先选择能看出材质、边缘、厚度或结构的图片。它将用于准确生成<strong style={{color: 'var(--text-1)'}}>材质工艺展示图、尺寸规格说明图、包装展示图</strong>，也能避免把纯角色图误做成错误品类。
          </div>
        </div>
      </div>

      <div className="form-question">
        <div className="form-question-title">
          <Ico.Edit /> 文本输入
          <span className="form-question-type" style={{background: 'rgba(255,255,255,0.05)', color: 'var(--text-2)'}}>可跳过</span>
        </div>
        <div style={{marginBottom: 18}}>
          <div className="form-option-title" style={{marginBottom: 4, display: 'flex', gap: 8, alignItems: 'center'}}>
            <span className="form-question-num">7</span>
            请补充商品规格与材质信息
          </div>
          <div style={{fontSize: 12, color: 'var(--text-2)', marginBottom: 8, lineHeight: 1.6}}>
            请直接填写商品的关键参数：<strong style={{color: 'var(--text-1)'}}>商品类型、尺寸/多个尺寸、材质、表面工艺、是否防水、是否含配件、单张还是套组</strong>。若有多个规格，请分行写清楚。
          </div>
          <textarea
            className="form-textarea"
            value={answers.spec}
            onChange={e => setSingle('spec', e.target.value)}
            placeholder="参考示例：贴纸，单张 6×8cm；材质 PET+亮膜；防水；一套 3 张；基础 OPP 袋包装。"
          />
        </div>
        <div>
          <div className="form-option-title" style={{marginBottom: 4, display: 'flex', gap: 8, alignItems: 'center'}}>
            <span className="form-question-num">8</span>
            请补充包装、赠品与购买说明文案
          </div>
          <div style={{fontSize: 12, color: 'var(--text-2)', marginBottom: 8, lineHeight: 1.6}}>
            请填写你希望展示在"包装与赠品展示图"以及"购买须知/定制说明图"里的具体内容，包括：<strong style={{color: 'var(--text-1)'}}>包装组成、赠品内容、发货时效、定制说明、注意事项</strong>。
          </div>
          <textarea
            className="form-textarea"
            value={answers.pack}
            onChange={e => setSingle('pack', e.target.value)}
            placeholder="参考示例：每份含 1 个挂件 + 1 张背卡 + 1 个独立袋；赠送小贴纸 1 张；下单后 3 天内发货。"
          />
        </div>
      </div>

      <div className="row-between" style={{marginTop: 18, alignItems: 'flex-end'}}>
        <div style={{flex: 1, marginRight: 16}}>
          <div style={{fontSize: 13, color: 'var(--text-2)', marginBottom: 6}}>有其他想法？</div>
          <input
            className="form-textarea"
            style={{minHeight: 44, padding: '12px 14px'}}
            placeholder="输入建议后按回车重新分析…"
          />
        </div>
        <button className="btn btn-outline" style={{padding: '12px 28px'}} onClick={onSubmit}>
          提交并继续 <Ico.ArrowRight />
        </button>
      </div>
    </>
  );
}

// ============================================================
// REPLANNING — 图片内容分析 + AI 正在生成出图方案
// ============================================================

function ReplanningStage() {
  return (
    <>
      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot success"><Ico.Check /></div>
          <div style={{flex: 1}}>
            <div className="stage-marker-title">图片内容已分析</div>
            <div className="summary-card success" style={{marginTop: 12}}>
              <div className="summary-head">
                <div className="summary-icon"><Ico.Image /></div>
                <div style={{flex: 1}}>
                  <div className="summary-confirm-pill"><Ico.Check /> 已确认</div>
                  <div className="summary-title">图片内容分析</div>
                  <div className="summary-stats">
                    <span><Ico.Image /> 2 张图片已分析</span>
                    <span><Ico.ArrowUp /> 6 张初始上传</span>
                  </div>
                </div>
              </div>
              <div style={{display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 8}}>
                {[0,1,2,3].map(i => (
                  <div key={i} style={{display: 'flex', gap: 10, alignItems: 'center', padding: '8px 10px', borderRadius: 8, background: 'rgba(255,255,255,0.03)', border: '1px solid var(--border)'}}>
                    <div style={{width: 32, height: 32, borderRadius: 6, overflow: 'hidden', flexShrink: 0}}>
                      {i === 2 ? <RocketDoodle size={32} /> : <ChibiPlaceholder kind={i} size={32} />}
                    </div>
                    <div style={{fontSize: 11.5, color: 'var(--text-2)'}}>未命名</div>
                  </div>
                ))}
                <div style={{gridColumn: 'span 2', display: 'flex', gap: 10, alignItems: 'center', padding: '8px 10px', borderRadius: 8, background: 'rgba(255,255,255,0.03)', border: '1px solid var(--border)'}}>
                  <div style={{width: 32, height: 32, borderRadius: 6, overflow: 'hidden', flexShrink: 0}}>
                    <ChibiPlaceholder kind={1} size={32} />
                  </div>
                  <div style={{minWidth: 0}}>
                    <div style={{fontSize: 11.5, fontWeight: 600}}>Q版银发女孩立绘正面…</div>
                    <div style={{fontSize: 10.5, color: 'var(--text-2)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>主体为Q版二次元女孩正面立绘，白皙肤色…</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="stepper-card">
        <div style={{display: 'flex', alignItems: 'center', gap: 14, marginBottom: 4}}>
          <div className="stage-marker-dot pending" style={{borderColor: 'var(--amber)', color: 'var(--amber)', background: 'var(--amber-dim)'}}>
            <span style={{
              display: 'inline-block', width: 8, height: 8, borderRadius: 50, background: 'var(--amber)',
              animation: 'pulse-dot 1.5s ease-in-out infinite'
            }}/>
          </div>
          <div>
            <div style={{fontSize: 16, fontWeight: 700}}>出图方案规划中</div>
            <div style={{fontSize: 12, color: 'var(--text-2)'}}>AI 正在为 9 个分类制定出图方案</div>
          </div>
        </div>
        <div className="stepper-card-label" style={{marginLeft: 42, marginTop: 16}}>出图方案规划</div>
        <div className="stepper-card-title" style={{marginLeft: 42}}>
          <span className="equalizer"><span></span><span></span><span></span></span>
          正在构建出图方案规划方案…
        </div>
        <div style={{marginLeft: 42}}>
          <StepProgress active={2} />
        </div>
      </div>
    </>
  );
}

// ============================================================
// PLANS — 出图方案已生成 (9 个分类, 21 张图片)
// ============================================================

const FINAL_PLANS = [
  { id: 'main', priority: '高', priorityClass: 'high', title: '商品主图（多角度轮播）',
    desc: '采用正方形 1:1 构图，制作多张轮播主图，分别展示角色正面全身、半身近景、眨眼动态款及干净留白款；整体保持软萌、治愈、二次元感强的视觉风格，突出角色完整轮廓与高颜值设定。',
    meta: [['点击率提升关键','ico'],['全平台','sep'],['淘宝/天猫','sep'],['京东','sep'],['拼多多','sep'],['抖店','sep'],['小红书','sep'],['1688','sep'],['快手','sep'],['必选',null,'tag-must'],['高转化',null,'tag-conv']],
    count: '3 张',
    summary: '以 软萌治愈的二次元贴纸视觉 为主线，突出穹妹角色的高识别度与收藏感，让主图兼顾点击率与平台适配性。',
    bullets: [
      ['拍摄思路', '围绕正面立绘、近景表情、留白陈列三类核心画面展开'],
      ['配色方案', '白底 + 浅灰奶白辅助，保留角色低饱和柔和色调'],
      ['光线建议', '均匀柔光质感，避免强阴影干扰贴纸轮廓'],
      ['构图风格', '1:1 居中大主体，强调完整外形与可爱细节'],
    ],
    sub: [
      { num: 1, title: '正面全身主图', desc: '正方形 1:1，角色完整居中展示，留白干净，发丝和裙摆细节清晰可见，软萌系视觉作为首图首选。' },
      { num: 2, title: '半身近景主图', desc: '剪裁到胸口以上，强化面部表情与黑色蝴蝶结，作为商品形象点击转化的二屏。' },
      { num: 3, title: '留白陈列主图', desc: '角色靠左居中，右侧大量留白用于平台文案或营销词覆盖，适配主图搜索流量场景。' },
    ]
  },
  { id: 'white', priority: '高', priorityClass: 'high', title: '白底图',
    desc: '纯白背景、主体居中、边缘干净，优先展示完整角色立绘或成品单体，不加复杂装饰与文案；确保发丝、裙摆、黑兔玩偶等细节清楚可辨，适合平台审核与搜索展示。',
    meta: [['搜索流量入口','ico'],['淘宝/天猫','sep'],['京东','sep'],['拼多多','sep'],['抖店','sep'],['1688','sep'],['必选',null,'tag-must'],['平台必需',null,'tag-platform']],
    count: '2 张',
    summary: '以 标准化白底电商图 呈现贴纸本体，重点解决平台审核、搜索展示和买家快速识别的问题。',
    bullets: [
      ['拍摄思路', '单张成品为主，统一比例展示不同款式'],
      ['配色方案', '纯白背景，不加入氛围道具'],
      ['光线建议', '平整柔光，确保边缘与图案细节清楚'],
      ['构图风格', '主体居中、边距一致、版面干净利落'],
    ],
    sub: [
      { num: 1, title: '单张白底标准图', desc: '纯白背景下展示单张穹妹贴纸成品，主体居中完整，轮廓边缘清晰利落，发丝、裙摆和黑兔玩偶均完整可见，不叠加复杂元素，满足平台白底审核与搜索展示需求。' },
      { num: 2, title: '款式白底展示图', desc: '在纯白底上展示另一版抱兔立绘贴纸，保持统一比例与边缘净空，突出图案完整度和贴纸外轮廓，适合用于 SKU 展示或搜索列表，让买家快速识别款式差异。' },
    ]
  },
  { id: 'rules', priority: '中', priorityClass: 'mid', title: '购买须知 / 定制说明图',
    desc: '清晰说明购买内容、单张/套组区别、是否含配件、是否支持改尺寸或改底材、发货方式与注意事项；信息分区排版，避免与角色主视觉冲突。',
    meta: [['减少咨询成本、提升成交效率','ico'],['淘宝/天猫','sep'],['拼多多','sep'],['抖店','sep'],['1688','sep'],['推荐',null,'tag-rec'],['促销必备',null,'tag-promo']],
    count: '2 张',
    summary: '以 少废话、强分区的信息说明 为核心，把买家最关心的购买结构和定制方向讲清楚，同时保持二次元贴纸页面的美观度。',
    bullets: [
      ['拍摄思路', '总览图先讲规则，第二张补充套组结构'],
      ['配色方案', '白底 + 浅灰分栏，少量黑色文字说明'],
      ['光线建议', '偏平面信息图风格，无需复杂光影'],
      ['构图风格', '模块化排版，文字与缩略图搭配清晰易读'],
    ],
    sub: [
      { num: 1, title: '购买规则总览图', desc: '将购买内容分为"单张/套组/可定制"三个信息模块，结合穹妹贴纸缩略图做清晰说明，版面整洁，重点提示多款可选与支持定制方向，帮助买家下单前快速理解规则。' },
      { num: 2, title: '套组内容说明图', desc: '针对多张套组做示意说明，展示套组包含的贴纸数量、组合展示方式与适合用途，文字尽量简短清楚，避免因说明过多压住角色视觉，适合作为详情页尾部说明图。' },
    ]
  },
];

function PlansStage({ onConfirm }) {
  return (
    <>
      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot success"><Ico.Check /></div>
          <div style={{flex: 1}}>
            <div className="stage-marker-title">图片内容已分析</div>
            <div className="summary-card success" style={{marginTop: 12}}>
              <div className="summary-head">
                <div className="summary-icon"><Ico.Image /></div>
                <div style={{flex: 1}}>
                  <div className="summary-confirm-pill"><Ico.Check /> 已确认</div>
                  <div className="summary-title">图片内容分析</div>
                  <div className="summary-stats">
                    <span><Ico.Image /> 2 张图片已分析</span>
                    <span><Ico.ArrowUp /> 6 张初始上传</span>
                  </div>
                </div>
              </div>
              <div style={{display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: 8}}>
                {[0,1,2,3].map(i => (
                  <div key={i} style={{display: 'flex', gap: 10, alignItems: 'center', padding: '8px 10px', borderRadius: 8, background: 'rgba(255,255,255,0.03)', border: '1px solid var(--border)'}}>
                    <div style={{width: 32, height: 32, borderRadius: 6, overflow: 'hidden', flexShrink: 0}}>
                      {i === 2 ? <RocketDoodle size={32} /> : <ChibiPlaceholder kind={i} size={32} />}
                    </div>
                    <div style={{fontSize: 11.5, color: 'var(--text-2)'}}>未命名</div>
                  </div>
                ))}
                <div style={{gridColumn: 'span 2', display: 'flex', gap: 10, alignItems: 'center', padding: '8px 10px', borderRadius: 8, background: 'rgba(255,255,255,0.03)', border: '1px solid var(--border)'}}>
                  <div style={{width: 32, height: 32, borderRadius: 6, overflow: 'hidden', flexShrink: 0}}>
                    <ChibiPlaceholder kind={1} size={32} />
                  </div>
                  <div style={{minWidth: 0}}>
                    <div style={{fontSize: 11.5, fontWeight: 600}}>Q版银发女孩立绘正面…</div>
                    <div style={{fontSize: 10.5, color: 'var(--text-2)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>主体为Q版二次元女孩正面立绘，白皙肤色…</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot active">!</div>
          <div style={{flex: 1}}>
            <div className="row-between">
              <div>
                <div className="stage-marker-title">出图方案已生成</div>
                <div className="stage-marker-sub">共 9 个分类、21 张图片</div>
              </div>
              <button className="btn btn-ghost" style={{padding: '6px 12px', fontSize: 12}}>
                <Ico.Refresh /> 回退
              </button>
            </div>
          </div>
        </div>
      </div>

      {FINAL_PLANS.map(p => (
        <div key={p.id} className="plan-detail">
          <div className="plan-detail-head">
            <span className="plan-detail-title">{p.title}</span>
            <span className={'priority-pill ' + p.priorityClass}>{p.priority}</span>
            <div className="spacer"></div>
            <button className="model-row-x"><Ico.X /></button>
          </div>
          <div className="plan-detail-desc">{p.desc}</div>
          <div className="plan-detail-meta">
            {p.meta.map((m, i) => {
              if (m[2]) return <span key={i} className={'tag ' + m[2]}>{m[0]}</span>;
              if (m[1] === 'ico') return <span key={i} className="ico" style={{display: 'inline-flex', alignItems: 'center', gap: 4}}><Ico.Target /> {m[0]}</span>;
              return <React.Fragment key={i}><span className="sep">·</span> <span>{m[0]}</span></React.Fragment>;
            })}
            <div className="spacer"></div>
            <span style={{color: 'var(--amber)', fontWeight: 600, display: 'inline-flex', alignItems: 'center', gap: 4}}>
              <Ico.Image /> {p.count}
            </span>
          </div>
          <div className="plan-bullets">
            <div style={{fontSize: 13, color: 'var(--text-1)', lineHeight: 1.7, marginBottom: 10}}>
              <Ico.Edit style={{marginRight: 6, color: 'var(--amber)'}} />
              <span style={{color: 'var(--amber)', fontWeight: 600}}>方案文案</span>
            </div>
            <div style={{fontSize: 13.5, color: 'var(--text-0)', lineHeight: 1.75, marginBottom: 14, paddingLeft: 20, paddingRight: 8, textAlign: 'justify'}}>
              以<span className="hl" style={{color: 'var(--amber)', fontWeight: 600}}> {p.summary.split(' ')[1]} </span>{p.summary.split(' ').slice(2).join(' ')}
            </div>
            {p.bullets.map(([k, v]) => (
              <div key={k} className="plan-bullet"><b>{k}：</b>{v}</div>
            ))}
          </div>
          <div className="plan-subimages">
            {p.sub.map(s => (
              <div key={s.num} className="plan-subimage">
                <div className="plan-subimage-head">
                  <div className="plan-subimage-num">{s.num}</div>
                  <div className="plan-subimage-title">{s.title}</div>
                  <button className="plan-subimage-x"><Ico.X /></button>
                </div>
                <div className="plan-subimage-desc">{s.desc}</div>
              </div>
            ))}
          </div>
          <div className="row" style={{justifyContent: 'flex-end', gap: 8, marginTop: 14}}>
            <button className="btn btn-outline" style={{padding: '7px 12px', fontSize: 12}}>
              <Ico.Spark /> AI 添加图片规划
            </button>
            <button className="btn btn-ghost" style={{padding: '7px 12px', fontSize: 12}}>
              <Ico.Plus /> 手动添加图片规划
            </button>
            <button className="btn btn-ghost" style={{padding: '7px 12px', fontSize: 12}}>
              <Ico.Check /> 保存修改
            </button>
          </div>
        </div>
      ))}

      <div className="row" style={{justifyContent: 'flex-end', marginTop: 24}}>
        <button className="btn btn-primary" style={{padding: '12px 28px'}} onClick={onConfirm}>
          确认出图方案并继续 <Ico.ArrowRight />
        </button>
      </div>
    </>
  );
}

// ============================================================
// MODEL — 选择生图模型
// ============================================================

function ModelStage({ onConfirm }) {
  const [lang, setLang] = _useState('中文');
  const LANGS = ['中文','English','Español','Français','Deutsch','日本語','한국어','Português','Italiano','Русский'];
  return (
    <>
      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot success"><Ico.Check /></div>
          <div style={{flex: 1}}>
            <div className="stage-marker-title">出图方案已确认</div>
            <div className="summary-card success" style={{marginTop: 12}}>
              <div className="summary-head">
                <div className="summary-icon"><Ico.Edit /></div>
                <div style={{flex: 1}}>
                  <div className="summary-confirm-pill"><Ico.Check /> 已确认</div>
                  <div className="summary-title">出图方案</div>
                  <div className="summary-stats">
                    <span><Ico.Grid /> 9 个分类</span>
                    <span><Ico.Image /> 21 张图片</span>
                    <span><Ico.Spark /> 5 项高优</span>
                  </div>
                </div>
              </div>
              <div className="summary-chips" style={{gridTemplateColumns: 'repeat(4, 1fr)'}}>
                {[
                  ['c-amber', '商品主图（多角度轮播）', '3张'],
                  ['c-cyan', '白底图', '2张'],
                  ['c-pink', '款式版本对比图', '3张'],
                  ['c-violet', '角色细节特写图', '3张'],
                  ['c-rose', '尺寸规格说明图', '3张'],
                  ['c-green', '材质工艺展示图', '2张'],
                  ['c-blue', '使用场景种草图', '2张'],
                  ['c-orange', '包装与赠品展示图', '1张'],
                  ['c-violet', '购买须知/定制说明图', '2张'],
                ].map(([cls, title, count], i) => (
                  <div key={i} className={'summary-chip ' + cls}>
                    <div className="summary-chip-title">{title}</div>
                    <div className="summary-chip-desc">{count}</div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot active">!</div>
          <div style={{flex: 1}}>
            <div className="row-between">
              <div>
                <div className="stage-marker-title">选择生图模型</div>
              </div>
              <button className="btn btn-ghost" style={{padding: '6px 12px', fontSize: 12}}>
                <Ico.Refresh /> 回退
              </button>
            </div>
          </div>
        </div>
      </div>

      <div className="plan-detail">
        <div style={{display: 'flex', gap: 10, alignItems: 'center', padding: '10px 14px', borderRadius: 8, background: 'var(--amber-dim)', border: '1px solid var(--border-amber)', marginBottom: 18}}>
          <span style={{fontSize: 14}}>🔒</span>
          <span style={{fontSize: 13, color: 'var(--text-1)'}}>确认后模型将锁定到本任务，后续无法更改（除非回退此节点）</span>
        </div>
        <div style={{marginBottom: 16}}>
          <div style={{fontSize: 13, fontWeight: 600, color: 'var(--text-1)', marginBottom: 10, display: 'flex', alignItems: 'center', gap: 8}}>
            <Ico.Spark /> 图片模型
          </div>
          <div className="row" style={{gap: 10}}>
            <button className="select-control">
              <span style={{width: 18, height: 18, display: 'grid', placeItems: 'center', background: '#FFF3C4', borderRadius: 4, fontSize: 12}}>🍌</span>
              Nano Banana Pro
              <Ico.Caret className="caret" />
            </button>
            <button className="select-control">
              <Ico.Frame />
              2K 高清
              <Ico.Caret className="caret" />
            </button>
          </div>
        </div>
        <div>
          <div style={{fontSize: 13, fontWeight: 600, color: 'var(--text-1)', marginBottom: 10, display: 'flex', alignItems: 'center', gap: 8}}>
            <Ico.Target /> 提示词语言
          </div>
          <div className="lang-pills">
            {LANGS.map(l => (
              <button key={l}
                      className={'lang-pill ' + (l === lang ? 'active' : '')}
                      onClick={() => setLang(l)}>
                {l}
              </button>
            ))}
            <button className="lang-pill"><Ico.Plus /> 其他</button>
          </div>
        </div>
      </div>

      <div className="row" style={{justifyContent: 'flex-end', marginTop: 24}}>
        <button className="btn btn-primary" style={{padding: '12px 28px'}} onClick={onConfirm}>
          确认模型并继续 <Ico.ArrowRight />
        </button>
      </div>
    </>
  );
}

// ============================================================
// GENERATING — 批量生成
// ============================================================

const BATCH_TILES = [
  { cat: '商品主图（多角度轮播）', count: 3, items: [
    { num: 1, title: '正面全身主图', stage: 'thinking' },
    { num: 2, title: '半身近景主图', stage: 'pending' },
    { num: 3, title: '留白陈列主图', stage: 'pending' },
  ]},
  { cat: '白底图', count: 2, items: [
    { num: 1, title: '单张白底标准图', stage: 'done', img: 0 },
    { num: 2, title: '款式白底展示图', stage: 'done', img: 1 },
  ]},
  { cat: '款式版本对比图', count: 3, items: [
    { num: 1, title: '三款式对比图', stage: 'building' },
    { num: 2, title: '姿态对比图', stage: 'pending' },
    { num: 3, title: '尺寸对比图', stage: 'pending' },
  ]},
];

function GeneratingStage() {
  return (
    <>
      <div className="stage-section">
        <div className="stage-marker">
          <div className="stage-marker-dot active">!</div>
          <div style={{flex: 1}}>
            <div className="row-between">
              <div>
                <div className="stage-marker-title row" style={{gap: 12}}>
                  图片批处理
                  <span style={{display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 10px', borderRadius: 6, background: 'var(--amber-dim)', color: 'var(--amber)', border: '1px solid var(--border-amber)', fontSize: 12, fontWeight: 600}}>
                    <Ico.Image /> 21 张图片
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="plan-detail" style={{padding: '18px 22px'}}>
        <div style={{fontSize: 13.5, fontWeight: 600, color: 'var(--amber)', marginBottom: 14, display: 'flex', alignItems: 'center', gap: 8}}>
          <span className="equalizer" style={{height: 12}}>
            <span style={{height: 6, width: 2, background: 'var(--amber)', display: 'inline-block', borderRadius: 1, animation: 'eq 1.2s ease-in-out infinite'}}></span>
            <span style={{height: 10, width: 2, background: 'var(--amber)', display: 'inline-block', borderRadius: 1, marginLeft: 2, animation: 'eq 1.2s ease-in-out 0.15s infinite'}}></span>
            <span style={{height: 8, width: 2, background: 'var(--amber)', display: 'inline-block', borderRadius: 1, marginLeft: 2, animation: 'eq 1.2s ease-in-out 0.3s infinite'}}></span>
          </span>
          提示词生成中 <span style={{color: 'var(--text-1)'}}>21 个</span>
        </div>
        <div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14}}>
          <div style={{padding: '12px 14px', borderRadius: 8, background: 'rgba(255,255,255,0.02)', border: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 10, opacity: 0.5}}>
            <span style={{width: 22, height: 22, borderRadius: 50, background: 'rgba(255,255,255,0.06)', display: 'grid', placeItems: 'center', fontSize: 11, color: 'var(--text-3)', fontWeight: 700}}>1</span>
            <span style={{fontSize: 13, color: 'var(--text-2)'}}>生成提示词</span>
          </div>
          <div style={{padding: '12px 14px', borderRadius: 8, background: 'rgba(255,255,255,0.02)', border: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 10, opacity: 0.4}}>
            <span style={{width: 22, height: 22, borderRadius: 50, background: 'rgba(255,255,255,0.06)', display: 'grid', placeItems: 'center', fontSize: 11, color: 'var(--text-3)', fontWeight: 700}}>2</span>
            <span style={{fontSize: 13, color: 'var(--text-2)'}}>批量生成图片</span>
          </div>
        </div>
      </div>

      {BATCH_TILES.map(sec => (
        <div key={sec.cat} className="batch-section">
          <div className="batch-section-head">
            <div className="batch-section-title">{sec.cat}</div>
            <div className="batch-section-count">{sec.count} 张</div>
          </div>
          <div className="batch-grid">
            {sec.items.map(it => (
              <BatchTile key={it.num} item={it} />
            ))}
          </div>
        </div>
      ))}
    </>
  );
}

function BatchTile({ item }) {
  const STAGE_MAP = {
    pending: { label: '调度中', activeIdx: 0 },
    thinking: { label: '深度分析中…', activeIdx: 1 },
    building: { label: '模型调度中…', activeIdx: 2 },
    done: { label: '已完成', activeIdx: 4 },
    failed: { label: 'AI 调用失败', activeIdx: -1 },
  };
  const m = STAGE_MAP[item.stage] || STAGE_MAP.pending;
  const SEGS = ['调度', '思考', '构建', '完成'];

  return (
    <div className="batch-tile">
      <div className="batch-tile-head">
        <div className="batch-tile-num">{item.num}</div>
        <div className="batch-tile-title">{item.title}</div>
        <div className={'batch-tile-status ' + item.stage}>
          {item.stage === 'done' ? '已完成' : '生成中'}
        </div>
      </div>
      <div className={'batch-tile-preview ' + (item.stage === 'done' ? 'has-img' : '')}>
        {item.stage === 'done' ? (
          <ChibiPlaceholder kind={item.img || 0} size={140} />
        ) : item.stage === 'failed' ? (
          <div style={{color: 'var(--rose)', fontSize: 12}}>AI 调用失败 · 余额不足</div>
        ) : (
          <div style={{color: 'var(--text-3)', fontSize: 12, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6}}>
            <Ico.Image />
            等待提示词
          </div>
        )}
      </div>
      <div>
        <div className="batch-tile-mini-stepper">
          {SEGS.map((_, i) => (
            <div key={i} className={'seg ' + (
              i < m.activeIdx ? 'done' : i === m.activeIdx ? 'active' : ''
            )}/>
          ))}
        </div>
        <div className="batch-tile-stage-labels">
          {SEGS.map(s => <span key={s}>{s}</span>)}
        </div>
        <div style={{textAlign: 'center', fontSize: 11.5, marginTop: 6, color: 'var(--amber)'}}>{m.label}</div>
      </div>
    </div>
  );
}

// ============================================================
// Exports
// ============================================================

Object.assign(window, {
  HomeStage, AnalyzingStage, AnalyzedStage, SupplementStage,
  ReplanningStage, PlansStage, ModelStage, GeneratingStage,
  TYPE_CARDS, StepProgress,
});
