// Agent Workspace — 3-column layout · V4 朱砂版色系
// 可拖拽分栏 / Tab 切换 / Scenario 联动 / 真实 AI 对话（worker.xlh1997.com）

// ── AI 后端接入点 ─────────────────────────────────────────────
// 走薪领航现有 Worker（DeepSeek V3.2）。CORS 允许任意 origin。
// 返回结构：{ answer: string } 或 { error: { message } }
const AI_ENDPOINT = 'https://worker.xlh1997.com/api/chat';

async function callAI(system, question) {
  const resp = await fetch(AI_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ system, question }),
  });
  let data;
  try { data = await resp.json(); } catch { throw new Error('AI 响应解析失败'); }
  if (!resp.ok) throw new Error(data?.error?.message || ('AI HTTP ' + resp.status));
  if (data?.error?.message) throw new Error(data.error.message);
  const answer = (data?.answer || '').trim();
  if (!answer) throw new Error('AI 无返回内容');
  return answer;
}

const C = {
  bg: '#FBF6F0',
  bg2: '#FFFFFF',
  bgSoft: '#F7F0E1',
  panel: '#FFFFFF',
  line: '#ECE2D4',
  line2: '#D6C8B4',
  lineSoft: '#F7F0E1',
  fg: '#1A130E',
  fgDim: '#574C42',
  fgMute: '#988A7A',
  fgFaint: '#BAA98A',
  accent: '#C5392E',
  accentInk: '#FFFFFF',
  accentSoft: '#FBE5DC',
  pop: '#E04E1A',
  popInk: '#FFFFFF',
  // risk colors (retuned to fit warm cream palette)
  hiBg: '#FBE5DC', hiFg: '#A92E22', hiLn: '#D85A4A',
  mdBg: '#FAEDDF', mdFg: '#94701F', mdLn: '#C49A4A',
  loBg: '#E8EFDE', loFg: '#4A7B3A', loLn: '#7B9F5E',
  userBubble: 'rgb(19, 59, 116)',
  glow: 'rgba(224,78,26,0.32)'
};
const sans = '"DM Sans","Noto Sans SC",system-ui,sans-serif';
const mono = '"JetBrains Mono",ui-monospace,monospace';

// Agent sphere (与首页同款品牌符号)
const SPHERE_BG = `
  radial-gradient(circle at 30% 24%, rgba(255,225,200,0.55) 0%, rgba(255,200,170,0) 26%),
  radial-gradient(circle at 50% 50%, #F05A35 0%, #BC2A20 30%, #6E2370 72%, #2A1F66 100%)
`;

function AgentSphere({ size = 32, label }) {
  return (
    <div style={{
      position: 'relative', width: size, height: size, borderRadius: '50%',
      background: SPHERE_BG, overflow: 'hidden', flexShrink: 0,
      boxShadow: `0 ${size * 0.06}px ${size * 0.25}px rgba(110,38,112,0.32),0 0 ${size * 0.4}px rgba(229,69,48,0.18)`,
      display: 'flex', alignItems: 'center', justifyContent: 'center'
    }}>
      <div style={{ position: 'absolute', top: '15%', right: '22%', width: Math.max(3, size * 0.14), height: Math.max(3, size * 0.14), borderRadius: '50%', background: 'rgba(255,255,255,0.95)' }} />
      {label &&
      <span style={{
        position: 'relative', color: '#FFF', fontFamily: sans, fontWeight: 800,
        fontSize: size * 0.42, letterSpacing: -0.5, textShadow: '0 1px 3px rgba(0,0,0,0.4)'
      }}>{label}</span>
      }
    </div>);

}

// ─────────────────────────────────────────────────────────────────────────────
// LEFT PANEL
// ─────────────────────────────────────────────────────────────────────────────
function LeftPanel({ stage, setStage, scenarioId, setScenarioId, search, setSearch, onTransfer }) {
  const stageData = STAGES[stage];
  const filtered = search ?
  stageData.groups.map((g) => ({
    ...g, items: g.items.filter((it) => (it.name + it.code).toLowerCase().includes(search.toLowerCase()))
  })).filter((g) => g.items.length) :
  stageData.groups;

  return (
    <aside style={{
      background: C.bg2, borderRight: `1px solid ${C.line}`,
      display: 'flex', flexDirection: 'column', overflow: 'hidden', height: '100%'
    }}>
      {/* Brand */}
      <div style={{ padding: '18px 18px 16px', borderBottom: `1px solid ${C.line}`, display: 'flex', alignItems: 'center', gap: 11 }}>
        <AgentSphere size={34} />
        <div style={{ lineHeight: 1.25 }}>
          <div style={{ fontFamily: sans, fontWeight: 700, fontSize: 15, color: C.fg, letterSpacing: -0.2 }}>AI HR Agent</div>
          <div style={{ fontFamily: mono, fontSize: 10, color: C.accent, letterSpacing: 1.5, marginTop: 2 }}>小薪 · 合规咨询</div>
        </div>
      </div>

      {/* Stage tabs — horizontal segmented control */}
      <div style={{ padding: '12px 12px 8px' }}>
        <div style={{
          display: 'flex', gap: 3, padding: 3, background: C.bg, border: `1px solid ${C.line}`, borderRadius: 10
        }}>
          {Object.entries(STAGES).map(([key, s]) => {
            const a = stage === key;
            return (
              <button key={key} onClick={() => setStage(key)} style={{
                flex: 1, padding: '8px 4px', border: 0, borderRadius: 7, cursor: 'pointer',
                background: a ? C.accent : 'transparent', color: a ? C.accentInk : C.fgDim,
                fontFamily: sans, fontSize: 13, fontWeight: 600, letterSpacing: 0.2,
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 1,
                boxShadow: a ? `0 1px 3px ${C.accent}55` : 'none', transition: 'all .15s'
              }}>
                <span>{s.label}</span>
                <span style={{ fontFamily: mono, fontSize: 9, opacity: a ? 0.85 : 0.55, letterSpacing: 1 }}>{s.count} 个场景</span>
              </button>);

          })}
        </div>
        <div style={{ fontFamily: mono, fontSize: 9, color: C.fgMute, letterSpacing: 1.5, marginTop: 10, padding: '0 4px' }}>
          {stageData.en}
        </div>
      </div>

      {/* Scenario list */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '4px 8px 12px' }} key={stage /* animate on swap */}>
        <style>{`@keyframes lp-list-in{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:translateX(0)}}`}</style>
        {filtered.map((g, gi) =>
        <div key={g.title} style={{ marginBottom: 14, animation: `lp-list-in .25s ease-out ${gi * 0.04}s both` }}>
            <div style={{
            display: 'flex', alignItems: 'center', gap: 8, padding: '8px 6px 6px',
            fontFamily: mono, fontSize: 10, color: C.fgMute, letterSpacing: 1.5
          }}>
              <span>{g.title.toUpperCase()}</span>
              <span style={{ flex: 1, height: 1, background: C.line }} />
            </div>
            {g.items.map((it) => {
            const cur = scenarioId === it.code;
            return (
              <button key={it.code} onClick={() => setScenarioId(it.code)} style={{
                width: '100%', display: 'flex', alignItems: 'center', gap: 10,
                padding: '9px 10px', marginBottom: 1,
                border: 0, borderRadius: 8, cursor: 'pointer', textAlign: 'left',
                background: cur ? C.accentSoft : 'transparent',
                color: cur ? C.accent : C.fgDim,
                fontFamily: sans, fontWeight: cur ? 600 : 400, fontSize: 13, transition: 'all .12s',
                position: 'relative'
              }}
              onMouseOver={(e) => {if (!cur) e.currentTarget.style.background = C.bgSoft;}}
              onMouseOut={(e) => {if (!cur) e.currentTarget.style.background = 'transparent';}}>
                
                  {cur && <span style={{ position: 'absolute', left: 0, top: 6, bottom: 6, width: 2, background: C.accent, borderRadius: 1 }} />}
                  <span style={{ fontFamily: mono, fontSize: 10, color: cur ? C.accent : C.fgMute, letterSpacing: 0.5, minWidth: 50 }}>{it.code}</span>
                  <span style={{ flex: 1, lineHeight: 1.35 }}>{it.name}</span>
                  {cur && <span style={{ color: C.accent }}>›</span>}
                </button>);

          })}
          </div>
        )}
        {!filtered.length &&
        <div style={{ padding: '24px 12px', textAlign: 'center', color: C.fgMute, fontSize: 13 }}>
            没找到匹配的场景<br />
            <span style={{ fontSize: 11, color: C.fgFaint }}>试试直接问小薪</span>
          </div>
        }
      </div>

      {/* Bottom: search + 转人工 */}
      <div style={{ padding: '12px 14px', borderTop: `1px solid ${C.line}`, background: C.bgSoft }}>
        <div style={{ position: 'relative', marginBottom: 10 }}>
          <span style={{ position: 'absolute', left: 11, top: '50%', transform: 'translateY(-50%)', color: C.fgMute, fontSize: 12 }}>⌕</span>
          <input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="不知道在哪？问小薪" style={{
            width: '100%', padding: '8px 12px 8px 30px', border: `1px solid ${C.line2}`,
            background: C.bg2, fontSize: 12, fontFamily: sans, color: C.fg,
            borderRadius: 8, outline: 'none'
          }} />
        </div>
        <button onClick={onTransfer} style={{
          width: '100%', padding: '9px 12px', border: `1px dashed ${C.line2}`, background: C.bg2,
          color: C.fgDim, fontSize: 12, fontFamily: sans, cursor: 'pointer', borderRadius: 8,
          display: 'flex', alignItems: 'center', gap: 8, transition: 'all .15s'
        }}
        onMouseOver={(e) => {e.currentTarget.style.borderColor = C.accent;e.currentTarget.style.color = C.accent;}}
        onMouseOut={(e) => {e.currentTarget.style.borderColor = C.line2;e.currentTarget.style.color = C.fgDim;}}>
          
          <span style={{ width: 6, height: 6, background: C.loFg, borderRadius: '50%', animation: 'lp-pulse 2s ease-in-out infinite' }} />
          <span style={{ flex: 1, textAlign: 'left' }}>处理不了？转人工顾问</span>
          <span style={{ color: C.fgMute }}>→</span>
        </button>
        <style>{`@keyframes lp-pulse{0%,100%{opacity:1}50%{opacity:0.35}}`}</style>
      </div>
    </aside>);

}

// ─────────────────────────────────────────────────────────────────────────────
// CHAT PANEL
// ─────────────────────────────────────────────────────────────────────────────
function ChatPanel({ scenarioId, messages, sending, mode = 'agent', onSend, onChipFill, onToast, onTransfer }) {
  const scenario = findScenario(scenarioId);
  const [input, setInput] = React.useState('');
  const scrollRef = React.useRef(null);

  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages, sending]);

  const send = () => {
    const text = input.trim();
    if (!text || sending) return;
    setInput('');
    onSend(text);
  };

  return (
    <main style={{ background: C.bg, display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden', minWidth: 0 }}>
      {/* Header */}
      <div style={{
        padding: '14px 28px', background: C.bg2, borderBottom: `1px solid ${C.line}`,
        display: 'flex', alignItems: 'center', gap: 18
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14, minWidth: 0 }}>
          {mode==='human' ? (
            <div style={{position:'relative'}}>
              <div style={{
                width:42,height:42,borderRadius:'50%',
                background:`linear-gradient(135deg,${C.accent},${C.pop})`,color:'#FFF',
                display:'flex',alignItems:'center',justifyContent:'center',
                fontFamily:sans,fontWeight:800,fontSize:18,letterSpacing:-0.5,
                boxShadow:`0 2px 8px ${C.glow}`,
              }}>李</div>
              <span style={{position:'absolute',right:-1,bottom:-1,width:11,height:11,borderRadius:'50%',background:C.loFg,border:`2px solid ${C.bg2}`}}/>
            </div>
          ) : (
            <div style={{ position: 'relative' }}>
              <AgentSphere size={42} />
              <span style={{
                position: 'absolute', right: -1, bottom: -1, width: 11, height: 11, borderRadius: '50%',
                background: C.loFg, border: `2px solid ${C.bg2}`
              }} />
            </div>
          )}
          <div style={{ lineHeight: 1.3, minWidth: 0 }}>
            <div style={{ fontFamily: sans, fontWeight: 700, fontSize: 16, color: C.fg, letterSpacing: -0.2 }}>
              {mode==='human' ? '李顾问' : '小薪'}
            </div>
            <div style={{ fontSize: 11, color: C.fgMute, marginTop: 1 }}>
              {mode==='human' ? '薪领航 · 资深人工 HR 顾问 · 在线' : '薪领航 · 资深 HR Agent · 在线'}
            </div>
          </div>
        </div>

        {/* context pill */}
        {scenario &&
        <div style={{
          display: 'inline-flex', alignItems: 'center', gap: 8, padding: '5px 12px',
          background: C.accentSoft, color: C.accent,
          fontSize: 12, fontFamily: sans, border: `1px solid ${C.accent}33`, borderRadius: 99,
          animation: 'cp-pill-in .35s ease-out'
        }} key={scenarioId}>
            <span style={{ fontFamily: mono, fontWeight: 700, fontSize: 11, letterSpacing: 0.5 }}>{scenario.code}</span>
            <span>{scenario.name}</span>
          </div>
        }
        <style>{`
          @keyframes cp-pill-in{from{opacity:0;transform:scale(0.92)}to{opacity:1;transform:scale(1)}}
          @keyframes cp-msg-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
          @keyframes cp-typing{0%,80%,100%{transform:scale(0.5);opacity:0.4}40%{transform:scale(1);opacity:1}}
          @keyframes cp-toast{0%{opacity:0;transform:translateY(-8px)}10%,90%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(-8px)}}
        `}</style>

        <div style={{ flex: 1 }} />

        <div style={{ display: 'flex', gap: 6 }}>
          <IconBtn title="重新开始">↻</IconBtn>
          <IconBtn title="导出对话">⤓</IconBtn>
          <IconBtn title="分享">↗</IconBtn>
        </div>
      </div>

      {/* Messages */}
      <div ref={scrollRef} style={{ flex: 1, overflowY: 'auto', padding: '24px 28px 12px' }}>
        <DayDivider />
        {messages.map((m) =>
        <MessageBubble key={m.id} msg={m} onChipFill={onChipFill} onToast={onToast} />
        )}
        {sending && <AgentTyping />}
      </div>

      {/* Composer */}
      <div style={{ padding: '12px 28px 18px', borderTop: `1px solid ${C.line}`, background: C.bg2 }}>
        <div style={{ display: 'flex', gap: 6, marginBottom: 10, flexWrap: 'wrap' }}>
          {['我想看其他销售岗的案例', '合同需要哪些附件？', '如果员工不愿意签怎么办？', '给我对照表'].map((h) =>
          <button key={h} onClick={() => setInput(h)} style={{
            padding: '5px 12px', fontSize: 11, color: C.fgDim,
            background: C.bgSoft, border: `1px solid ${C.line}`, borderRadius: 99,
            cursor: 'pointer', fontFamily: sans, transition: 'all .15s'
          }}
          onMouseOver={(e) => {e.currentTarget.style.color = C.accent;e.currentTarget.style.borderColor = C.accent;}}
          onMouseOut={(e) => {e.currentTarget.style.color = C.fgDim;e.currentTarget.style.borderColor = C.line;}}>
            {h}</button>
          )}
        </div>

        <div style={{
          display: 'flex', alignItems: 'flex-end', gap: 10, background: C.bgSoft,
          border: `1px solid ${C.line2}`, borderRadius: 12, padding: '10px 12px',
          transition: 'all .15s'
        }} onFocus={(e) => {e.currentTarget.style.borderColor = C.accent;e.currentTarget.style.background = C.bg2;}}
        onBlur={(e) => {e.currentTarget.style.borderColor = C.line2;e.currentTarget.style.background = C.bgSoft;}}>
          <textarea
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={(e) => {if (e.key === 'Enter' && !e.shiftKey) {e.preventDefault();send();}}}
            placeholder={sending ? '小薪在思考…' : '继续问小薪，或粘贴合同模板让它帮你查漏…'}
            disabled={sending}
            rows={1}
            style={{
              flex: 1, border: 0, background: 'transparent', outline: 'none',
              fontFamily: sans, fontSize: 14, color: C.fg, resize: 'none', lineHeight: 1.5,
              maxHeight: 120, minHeight: 24
            }} />
          
          <button onClick={send} disabled={!input.trim() || sending} style={{
            width: 36, height: 36, border: 0, borderRadius: 10, cursor: input.trim() && !sending ? 'pointer' : 'not-allowed',
            background: input.trim() && !sending ? C.pop : C.line2, color: '#FFF',
            fontSize: 16, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center',
            boxShadow: input.trim() && !sending ? `0 4px 12px ${C.glow}` : 'none',
            transition: 'all .15s', flexShrink: 0
          }}>↑</button>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, fontSize: 10, color: C.fgFaint, fontFamily: mono, letterSpacing: 0.5 }}>
          <span>小薪基于薪领航 25+ 年实战经验 · 不替代律师建议</span>
          <span>ENTER 发送 · SHIFT+ENTER 换行</span>
        </div>
      </div>
    </main>);

}

function DayDivider() {
  return (
    <div style={{ textAlign: 'center', margin: '6px 0 22px', position: 'relative' }}>
      <span style={{
        position: 'relative', background: C.bg, padding: '0 14px',
        fontFamily: mono, fontSize: 10, color: C.fgMute, letterSpacing: 2
      }}>今天 · 14:32</span>
      <div style={{ position: 'absolute', left: 0, right: 0, top: '50%', height: 1, background: C.line, zIndex: -1 }} />
    </div>);

}

function IconBtn({ children, title }) {
  return (
    <button title={title} style={{
      width: 32, height: 32, border: `1px solid ${C.line}`, background: C.bg2,
      color: C.fgMute, cursor: 'pointer', borderRadius: 8, fontSize: 14,
      display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all .15s'
    }}
    onMouseOver={(e) => {e.currentTarget.style.color = C.accent;e.currentTarget.style.borderColor = C.accent;}}
    onMouseOut={(e) => {e.currentTarget.style.color = C.fgMute;e.currentTarget.style.borderColor = C.line;}}>
      {children}</button>);

}

function AgentTyping() {
  return (
    <div style={{ display: 'flex', gap: 12, marginBottom: 18, animation: 'cp-msg-in .3s ease-out' }}>
      <AgentSphere size={32} />
      <div style={{
        padding: '14px 18px', background: C.bg2, border: `1px solid ${C.line}`,
        borderRadius: '4px 14px 14px 14px', display: 'flex', alignItems: 'center', gap: 5
      }}>
        {[0, 1, 2].map((i) =>
        <span key={i} style={{
          width: 7, height: 7, borderRadius: '50%', background: C.accent,
          animation: `cp-typing 1.4s ease-in-out ${i * 0.16}s infinite`
        }} />
        )}
      </div>
    </div>);

}

// Inline-markdown lite: **bold**
function fmt(s) {
  if (!s) return null;
  const parts = s.split(/(\*\*[^*]+\*\*)/g);
  return parts.map((p, i) => {
    if (p.startsWith('**') && p.endsWith('**'))
    return <strong key={i} style={{ color: C.fg, fontWeight: 700 }}>{p.slice(2, -2)}</strong>;
    return <React.Fragment key={i}>{p}</React.Fragment>;
  });
}

function MessageBubble({ msg, onChipFill, onToast }) {
  // System handover divider
  if (msg.role === 'system') {
    return (
      <div style={{
        display:'flex',alignItems:'center',gap:12,margin:'14px 0 22px',
        animation:'cp-msg-in .3s ease-out',
      }}>
        <div style={{flex:1,height:1,background:`linear-gradient(90deg,transparent,${C.line2})`}}/>
        <div style={{
          padding:'5px 14px',background:C.accentSoft,border:`1px solid ${C.accent}33`,borderRadius:99,
          fontFamily:mono,fontSize:11,color:C.accent,letterSpacing:1,
          display:'flex',alignItems:'center',gap:8,
        }}>
          <span style={{width:5,height:5,borderRadius:'50%',background:C.accent,boxShadow:`0 0 6px ${C.accent}`}}/>
          {msg.text}
          <span style={{fontFamily:mono,color:C.fgMute,marginLeft:4}}>{msg.time}</span>
        </div>
        <div style={{flex:1,height:1,background:`linear-gradient(90deg,${C.line2},transparent)`}}/>
      </div>
    );
  }

  const isUser = msg.role === 'user';
  const isHuman = msg.role === 'human';
  return (
    <div style={{
      display: 'flex', gap: 12, marginBottom: 18,
      flexDirection: isUser ? 'row-reverse' : 'row',
      animation: 'cp-msg-in .3s ease-out'
    }}>
      {isUser ?
      <div style={{
        width: 32, height: 32, borderRadius: '50%', flexShrink: 0,
        background: C.bgSoft, border: `1px solid ${C.line2}`, color: C.fgDim,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: sans, fontWeight: 700, fontSize: 12
      }}>您</div> :
      isHuman ?
      <div style={{
        width:32,height:32,borderRadius:'50%',flexShrink:0,
        background:`linear-gradient(135deg,${C.accent},${C.pop})`,color:'#FFF',
        display:'flex',alignItems:'center',justifyContent:'center',
        fontFamily:sans,fontWeight:800,fontSize:13,letterSpacing:-0.3,
        boxShadow:`0 2px 6px ${C.glow}`,
      }}>李</div> :
      <AgentSphere size={32} />}

      <div style={{ maxWidth: '78%', textAlign: isUser ? 'right' : 'left' }}>
        {!isUser && (
          <div style={{ fontSize: 11, color: isHuman?C.accent:C.fgMute, marginBottom: 5, fontWeight: isHuman?600:500, display:'flex', alignItems:'center', gap:6 }}>
            {isHuman ? <>李顾问 <span style={{fontFamily:mono,fontSize:9,color:C.fgMute,letterSpacing:1,fontWeight:400}}>HUMAN AGENT</span></> : '小薪'}
          </div>
        )}

        <div style={{
            display: 'inline-block', padding: '12px 18px',
            background: isUser ? C.userBubble : isHuman ? C.bgSoft : C.bg2,
            color: isUser ? '#FFF' : C.fg,
            border: isUser ? 0 : isHuman ? `1px solid ${C.accent}44` : `1px solid ${C.line}`,
            borderRadius: isUser ? '14px 4px 14px 14px' : '4px 14px 14px 14px',
            fontFamily: sans, fontSize: 14, lineHeight: 1.65, textAlign: 'left', maxWidth: '100%',
            boxShadow: isHuman ? `0 1px 0 ${C.line}` : 'none',
          }}>
          {fmt(msg.text)}

          {msg.intro && <div style={{ marginTop: 10, color: C.fgDim, fontSize: 13.5 }}>{fmt(msg.intro)}</div>}

          {msg.quickForm &&
          <div style={{
            display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 12
          }}>
              {msg.quickForm.map((q, i) =>
            <button key={i} onClick={() => onChipFill(`${q.label}：${q.value}`)} style={{
              padding: '8px 12px', background: C.bg2, border: `1px solid ${C.line2}`,
              borderRadius: 8, fontSize: 12, color: C.fgDim, fontFamily: sans, cursor: 'pointer',
              display: 'flex', alignItems: 'center', gap: 8, textAlign: 'left', transition: 'all .15s'
            }}
            onMouseOver={(e) => {e.currentTarget.style.borderColor = C.accent;e.currentTarget.style.color = C.accent;e.currentTarget.style.background = C.accentSoft;}}
            onMouseOut={(e) => {e.currentTarget.style.borderColor = C.line2;e.currentTarget.style.color = C.fgDim;e.currentTarget.style.background = C.bg2;}}>
              
                  <span style={{ fontFamily: mono, fontSize: 10, color: C.fgMute, letterSpacing: 0.5 }}>{q.label}</span>
                  <span>{q.value}</span>
                </button>
            )}
            </div>
          }

          {msg.blockWarn &&
          <div style={{
            marginTop: 12, padding: '12px 16px', background: C.hiBg,
            borderLeft: `3px solid ${C.accent}`, borderRadius: '2px 8px 8px 2px',
            fontSize: 13, lineHeight: 1.7, color: C.fg
          }}>
              <div style={{ fontWeight: 700, color: C.accent, fontFamily: sans }}>{msg.blockWarn.title}</div>
              <div style={{ marginTop: 6 }}>{fmt(msg.blockWarn.body)}</div>
              <div style={{ marginTop: 8, fontFamily: mono, fontSize: 11, color: C.fgMute, letterSpacing: 0.3 }}>{msg.blockWarn.legal}</div>
            </div>
          }

          {msg.outro && <div style={{ marginTop: 12 }}>{fmt(msg.outro)}</div>}

          {msg.riskCard && <RiskCard card={msg.riskCard} />}

          {msg.actionCard &&
          <div style={{
            marginTop: 10, background: C.bg2, border: `1px solid ${C.line2}`, borderRadius: 10, overflow: 'hidden'
          }}>
              <div style={{ padding: '10px 16px', background: C.bgSoft, borderBottom: `1px solid ${C.line}`,
              fontWeight: 700, fontSize: 13, fontFamily: sans }}>{msg.actionCard.title}</div>
              <div style={{ padding: '12px 16px' }}>
                {msg.actionCard.items.map(([k, v], i) =>
              <div key={i} style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: 12, padding: '6px 0', fontSize: 13, lineHeight: 1.6 }}>
                    <span style={{
                  fontFamily: mono, fontSize: 10, fontWeight: 700, letterSpacing: 0.5,
                  padding: '2px 7px', borderRadius: 4,
                  background: k === '必做' ? C.hiBg : k === '建议' ? C.mdBg : C.loBg,
                  color: k === '必做' ? C.hiFg : k === '建议' ? C.mdFg : C.loFg,
                  alignSelf: 'start', marginTop: 2
                }}>{k}</span>
                    <span style={{ color: C.fg }}>{v}</span>
                  </div>
              )}
              </div>
            </div>
          }

          {msg.deliverables &&
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 14 }}>
              {msg.deliverables.map((d, i) =>
            <button key={i} onClick={() => onToast(`正在生成「${d.label}」…`)} style={{
              padding: '9px 14px', fontSize: 12, fontWeight: 600, fontFamily: sans, cursor: 'pointer',
              borderRadius: 8, display: 'inline-flex', alignItems: 'center', gap: 7,
              background: d.kind === 'primary' ? C.pop : C.bg2,
              color: d.kind === 'primary' ? '#FFF' : C.accent,
              border: d.kind === 'primary' ? 0 : `1px solid ${C.accent}`,
              boxShadow: d.kind === 'primary' ? `0 4px 12px ${C.glow}` : 'none',
              transition: 'all .15s'
            }}>{d.icon} {d.label}</button>
            )}
            </div>
          }
        </div>

        <div style={{ fontSize: 10, color: C.fgFaint, marginTop: 4, fontFamily: mono }}>{msg.time}</div>
      </div>
    </div>);

}

function RiskCard({ card }) {
  const tagBg = card.level === 'high' ? C.hiBg : card.level === 'mid' ? C.mdBg : C.loBg;
  const tagFg = card.level === 'high' ? C.hiFg : card.level === 'mid' ? C.mdFg : C.loFg;
  return (
    <div style={{
      marginTop: 12, background: C.bg2, border: `1px solid ${C.line2}`, borderRadius: 10, overflow: 'hidden'
    }}>
      <div style={{
        padding: '10px 16px', background: C.bgSoft, borderBottom: `1px solid ${C.line}`,
        display: 'flex', alignItems: 'center', gap: 10, fontWeight: 700, fontSize: 13, fontFamily: sans
      }}>
        <span>{card.title}</span>
        <span style={{ flex: 1 }} />
        <span style={{
          fontFamily: mono, fontSize: 10, fontWeight: 600, letterSpacing: 1, padding: '2px 8px',
          background: tagBg, color: tagFg, borderRadius: 4, border: `1px solid ${tagFg}33`
        }}>RISK · {card.level.toUpperCase()}</span>
      </div>
      {card.rows.map((r, i) => {
        const rBg = r.level === 'high' ? C.hiBg : r.level === 'mid' ? C.mdBg : C.loBg;
        const rFg = r.level === 'high' ? C.hiFg : r.level === 'mid' ? C.mdFg : C.loFg;
        return (
          <div key={i} style={{
            display: 'flex', gap: 12, padding: '12px 16px',
            borderBottom: i < card.rows.length - 1 ? `1px solid ${C.lineSoft}` : 0,
            fontSize: 13
          }}>
            <span style={{
              fontFamily: mono, fontSize: 10, fontWeight: 700, letterSpacing: 1,
              padding: '3px 8px', background: rBg, color: rFg, borderRadius: 4,
              border: `1px solid ${rFg}33`, minWidth: 38, textAlign: 'center', height: 'fit-content'
            }}>{r.level === 'high' ? '高' : r.level === 'mid' ? '中' : '低'}</span>
            <div style={{ flex: 1, lineHeight: 1.6 }}>
              <div style={{ color: C.fg, fontWeight: 500 }}>{r.main}</div>
              {r.sub && <div style={{ color: C.fgMute, fontSize: 12, marginTop: 3 }}>{r.sub}</div>}
            </div>
          </div>);

      })}
    </div>);

}

// ─────────────────────────────────────────────────────────────────────────────
// REFS PANEL
// ─────────────────────────────────────────────────────────────────────────────
function RefsPanel({ scenarioId, refs, onToast }) {
  const scenario = findScenario(scenarioId);
  const empty = !refs.laws.length && !refs.cases.length;

  return (
    <aside style={{
      background: C.bgSoft, borderLeft: `1px solid ${C.line}`,
      display: 'flex', flexDirection: 'column', overflow: 'hidden', height: '100%'
    }}>
      <div style={{ padding: '16px 18px 12px', borderBottom: `1px solid ${C.line}`, background: C.bg2 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontWeight: 700, fontSize: 14, color: C.fg, fontFamily: sans }}>
          <span style={{ fontSize: 14 }}>📎</span> 配套资料
        </div>
        <div style={{ fontSize: 11, color: C.fgMute, marginTop: 2 }}>小薪在对话中调用的依据 · 实时更新</div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '14px 16px 20px' }} key={scenarioId}>
        <style>{`@keyframes rp-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}`}</style>

        {/* Focus card */}
        {scenario &&
        <div style={{
          position: 'relative', background: C.accent, color: '#FFF', padding: '16px 18px',
          borderRadius: 10, marginBottom: 18, marginTop: 6, animation: 'rp-in .35s ease-out',
          boxShadow: `0 8px 24px ${C.glow}`
        }}>
            <span style={{
            position: 'absolute', top: -9, left: 14, background: C.pop, color: '#FFF',
            fontFamily: mono, fontSize: 9, letterSpacing: 2, padding: '3px 8px',
            borderRadius: 4, fontWeight: 700
          }}>FOCUS</span>
            <div style={{ fontFamily: mono, fontSize: 12, fontWeight: 700, opacity: 0.85, marginBottom: 4, letterSpacing: 0.5 }}>{scenario.code}</div>
            <div style={{ fontFamily: sans, fontWeight: 700, fontSize: 16, lineHeight: 1.3, marginBottom: 10 }}>{scenario.name}</div>
            <div style={{ display: 'flex', gap: 6, fontSize: 10, fontFamily: mono, letterSpacing: 0.5 }}>
              <span style={{ padding: '2px 8px', background: 'rgba(255,255,255,0.14)', border: '1px solid rgba(255,255,255,0.22)', borderRadius: 4 }}>{STAGES[scenario.code.slice(0, 2).toLowerCase()]?.label || ''}</span>
              <span style={{ padding: '2px 8px', background: 'rgba(255,255,255,0.14)', border: '1px solid rgba(255,255,255,0.22)', borderRadius: 4 }}>P2 制度画像</span>
            </div>
          </div>
        }

        {empty &&
        <div style={{ textAlign: 'center', padding: '40px 16px', color: C.fgMute, fontSize: 13, lineHeight: 1.7 }}>
            <div style={{ fontSize: 24, marginBottom: 8 }}>📂</div>
            这个场景的引用资料正在补充<br />
            <span style={{ fontSize: 11, color: C.fgFaint }}>选 ON-201 看完整内容示例</span>
          </div>
        }

        {refs.laws.length > 0 &&
        <RefGroup title="法规依据" icon="⚖️" count={refs.laws.length}>
            {refs.laws.map((r) =>
          <RefItem key={r.__k} live={r.live} tag={r.tag} main={r.main} sub={r.sub} />
          )}
          </RefGroup>
        }

        {refs.cases.length > 0 &&
        <RefGroup title="注意事项" icon="⚠️" count={refs.cases.length}>
            {refs.cases.map((r) =>
          <RefItem key={r.__k} tag={r.tag} main={r.main} sub={r.sub} />
          )}
          </RefGroup>
        }

        {refs.templates.length > 0 &&
        <RefGroup title="配套模板" icon="📋" count={refs.templates.length}>
            {refs.templates.map((t, i) =>
          <button key={i} onClick={() => onToast(`正在下载「${t.name}」…`)} style={{
            width: '100%', textAlign: 'left',
            background: C.bg2, border: `1px solid ${C.line}`, borderRadius: 8, padding: '10px 12px',
            marginBottom: 6, display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer',
            fontFamily: sans, transition: 'all .15s'
          }}
          onMouseOver={(e) => {e.currentTarget.style.borderColor = C.accent;}}
          onMouseOut={(e) => {e.currentTarget.style.borderColor = C.line;}}>
            
                <div style={{
              width: 32, height: 38, background: C.accent, color: '#FFF',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: mono, fontSize: 9, fontWeight: 700, borderRadius: 3, flexShrink: 0
            }}>{t.kind}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 500, color: C.fg, marginBottom: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{t.name}</div>
                  <div style={{ fontFamily: mono, fontSize: 10, color: C.fgMute, letterSpacing: 0.3 }}>{t.sub}</div>
                </div>
                <span style={{ color: C.accent, fontSize: 16 }}>↓</span>
              </button>
          )}
          </RefGroup>
        }

        {refs.related.length > 0 &&
        <RefGroup title="相关场景" icon="🔗" count={refs.related.length}>
            {refs.related.map((r, i) =>
          <div key={i} style={{
            background: C.bg2, border: `1px solid ${C.line}`, borderRadius: 8, padding: '9px 12px', marginBottom: 6,
            display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer', fontFamily: sans, transition: 'all .15s'
          }}
          onMouseOver={(e) => {e.currentTarget.style.borderColor = C.accent;}}
          onMouseOut={(e) => {e.currentTarget.style.borderColor = C.line;}}>
            
                <span style={{ fontFamily: mono, fontSize: 10, color: C.fgMute, background: C.bgSoft, padding: '2px 7px', borderRadius: 4, letterSpacing: 0.5, flexShrink: 0 }}>{r.code}</span>
                <span style={{ flex: 1, fontSize: 12.5, color: C.fg }}>{r.name}</span>
                <span style={{ color: C.fgFaint, fontSize: 14 }}>→</span>
              </div>
          )}
          </RefGroup>
        }

        {/* Report CTA */}
        <button onClick={() => onToast('正在导出咨询报告…')} style={{
          marginTop: 18, width: '100%', padding: '14px 16px', border: 0, cursor: 'pointer', borderRadius: 12,
          background: `linear-gradient(135deg,${C.accent},${C.pop})`, color: '#FFF',
          display: 'flex', alignItems: 'center', gap: 14, textAlign: 'left',
          boxShadow: `0 8px 24px ${C.glow}`, fontFamily: sans
        }}>
          <span style={{ fontSize: 22, flexShrink: 0 }}>📊</span>
          <div style={{ flex: 1, lineHeight: 1.3 }}>
            <div style={{ fontWeight: 700, fontSize: 13.5 }}>导出完整咨询报告</div>
            <div style={{ fontSize: 11, opacity: 0.85, marginTop: 2 }}>PDF · 含所有结论与材料</div>
          </div>
        </button>
      </div>
    </aside>);

}

function RefGroup({ title, icon, count, children }) {
  return (
    <div style={{ marginBottom: 20, animation: 'rp-in .35s ease-out' }}>
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10,
        paddingBottom: 6, borderBottom: `1px solid ${C.line}`
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontWeight: 700, fontSize: 13, color: C.fg, fontFamily: sans }}>
          <span style={{
            width: 22, height: 22, background: C.bg2, border: `1px solid ${C.line}`, borderRadius: 6,
            display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 11
          }}>{icon}</span>
          {title}
        </div>
        <span style={{ fontFamily: mono, fontSize: 10, color: C.fgMute, background: C.bg2, padding: '2px 8px', border: `1px solid ${C.line}`, borderRadius: 99 }}>{count}</span>
      </div>
      {children}
    </div>);

}

function RefItem({ live, tag, main, sub }) {
  const [hl, setHl] = React.useState(live);
  React.useEffect(() => {
    if (hl) {const t = setTimeout(() => setHl(false), 1800);return () => clearTimeout(t);}
  }, [hl]);
  return (
    <div style={{
      background: hl ? C.accentSoft : C.bg2,
      borderTop: `1px solid ${hl ? C.accent + '66' : C.line}`,
      borderRight: `1px solid ${hl ? C.accent + '66' : C.line}`,
      borderBottom: `1px solid ${hl ? C.accent + '66' : C.line}`,
      borderLeft: live ? `3px solid ${C.accent}` : `1px solid ${hl ? C.accent + '66' : C.line}`,
      borderRadius: 8, padding: '10px 12px', marginBottom: 6, fontFamily: sans,
      transition: 'background 1.4s,border-color 1.4s', cursor: 'pointer'
    }}>
      <div style={{ fontFamily: mono, fontSize: 9, color: C.fgMute, marginBottom: 4, letterSpacing: 0.8 }}>{tag}</div>
      <div style={{ fontSize: 12.5, color: C.fg, lineHeight: 1.5 }}>{fmt(main)}
        {sub && <div style={{ color: C.fgMute, fontSize: 11.5, marginTop: 3, lineHeight: 1.55 }}>{sub}</div>}
      </div>
    </div>);

}

// ─────────────────────────────────────────────────────────────────────────────
// TRANSFER MODAL — 转人工流程
// ─────────────────────────────────────────────────────────────────────────────
function TransferModal({ open, onClose, onJoined }) {
  const [step, setStep] = React.useState(0);
  React.useEffect(() => {
    if (!open) { setStep(0); return; }
    const t1 = setTimeout(() => setStep(1), 2400);
    const t2 = setTimeout(() => setStep(2), 4800);
    return () => { clearTimeout(t1); clearTimeout(t2); };
  }, [open]);
  if (!open) return null;

  return (
    <div onClick={onClose} style={{
      position:'fixed',inset:0,zIndex:200,
      background:'rgba(26,19,14,0.45)',backdropFilter:'blur(6px)',
      display:'flex',alignItems:'center',justifyContent:'center',
      animation:'tm-fade .2s ease-out',
    }}>
      <style>{`
        @keyframes tm-fade{from{opacity:0}to{opacity:1}}
        @keyframes tm-card{from{opacity:0;transform:translateY(12px) scale(0.98)}to{opacity:1;transform:translateY(0) scale(1)}}
        @keyframes tm-spin{to{transform:rotate(360deg)}}
        @keyframes tm-step{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
      `}</style>
      <div onClick={e=>e.stopPropagation()} style={{
        background:C.bg2,border:`1px solid ${C.line}`,borderRadius:16,padding:'28px 32px',
        width:420,maxWidth:'92vw',boxShadow:'0 30px 60px rgba(26,19,14,0.35),0 8px 24px rgba(110,38,112,0.18)',
        animation:'tm-card .28s cubic-bezier(.2,.7,.3,1)',position:'relative',
      }}>
        {step < 2 && (
          <button onClick={onClose} style={{
            position:'absolute',top:14,right:14,width:28,height:28,border:0,
            background:'transparent',color:C.fgMute,cursor:'pointer',fontSize:18,borderRadius:8,
          }}>×</button>
        )}

        {step === 0 && (
          <div style={{animation:'tm-step .25s ease-out'}}>
            <div style={{display:'flex',alignItems:'center',gap:14,marginBottom:18}}>
              <div style={{
                width:46,height:46,borderRadius:'50%',border:`2px solid ${C.accentSoft}`,borderTopColor:C.accent,
                animation:'tm-spin 1s linear infinite',
              }}/>
              <div>
                <div style={{fontSize:17,fontWeight:700,color:C.fg,letterSpacing:-0.2}}>正在为您转接专家</div>
                <div style={{fontSize:12,color:C.fgMute,marginTop:2}}>薪领航资深 HR 顾问 · 7×12 在岗</div>
              </div>
            </div>
            <div style={{padding:'14px 16px',background:C.bgSoft,border:`1px dashed ${C.line2}`,borderRadius:10,fontSize:13,color:C.fgDim,lineHeight:1.7}}>
              排队中 · <b style={{color:C.accent,fontFamily:mono}}>您是第 2 位</b><br/>
              预计等待 <b style={{color:C.fg}}>约 1 分钟</b>，请保持页面打开
            </div>
            <div style={{marginTop:18,fontSize:11,color:C.fgFaint,fontFamily:mono,letterSpacing:1}}>
              SYSTEM · 转接已建立 · 等待顾问应答
            </div>
          </div>
        )}

        {step === 1 && (
          <div style={{animation:'tm-step .25s ease-out'}}>
            <div style={{fontSize:11,color:C.accent,fontFamily:mono,letterSpacing:1.5,marginBottom:14}}>● 顾问已应答 · 准备接入</div>
            <div style={{display:'flex',alignItems:'center',gap:14,padding:'14px 16px',background:C.bgSoft,borderRadius:10,border:`1px solid ${C.line}`}}>
              <div style={{
                width:52,height:52,borderRadius:'50%',background:`linear-gradient(135deg,${C.accent},${C.pop})`,color:'#FFF',
                display:'flex',alignItems:'center',justifyContent:'center',fontSize:20,fontWeight:800,fontFamily:sans,letterSpacing:-0.5,
                position:'relative',
              }}>李
                <span style={{position:'absolute',right:-2,bottom:-2,width:14,height:14,borderRadius:'50%',background:C.loFg,border:`2px solid ${C.bg2}`}}/>
              </div>
              <div style={{flex:1}}>
                <div style={{fontSize:15,fontWeight:700,color:C.fg,letterSpacing:-0.2}}>李顾问</div>
                <div style={{fontSize:12,color:C.fgDim,marginTop:1}}>12 年劳动关系经验 · 处理过 800+ 复杂工单</div>
                <div style={{fontSize:11,color:C.fgMute,marginTop:4,fontFamily:mono,letterSpacing:0.5}}>认证：高级人力资源管理师 · 劳动争议调解员</div>
              </div>
            </div>
            <div style={{marginTop:16,fontSize:13,color:C.fgDim,display:'flex',alignItems:'center',gap:8}}>
              <span style={{width:14,height:14,borderRadius:'50%',border:`2px solid ${C.accentSoft}`,borderTopColor:C.accent,animation:'tm-spin 1s linear infinite'}}/>
              正在拉取您和小薪的对话上下文…
            </div>
          </div>
        )}

        {step === 2 && (
          <div style={{animation:'tm-step .25s ease-out'}}>
            <div style={{textAlign:'center',marginBottom:18}}>
              <div style={{
                width:56,height:56,margin:'0 auto 14px',borderRadius:'50%',
                background:C.loBg,border:`2px solid ${C.loFg}`,color:C.loFg,
                display:'flex',alignItems:'center',justifyContent:'center',fontSize:26,fontWeight:700,
                animation:'tm-card .35s cubic-bezier(.2,.7,.3,1.2)',
              }}>✓</div>
              <div style={{fontSize:18,fontWeight:700,color:C.fg,letterSpacing:-0.3}}>已接入李顾问</div>
              <div style={{fontSize:13,color:C.fgDim,marginTop:6}}>小薪暂时退出对话，李顾问会基于刚才的上下文继续跟进。</div>
            </div>
            <button onClick={()=>{onJoined();onClose();}} style={{
              width:'100%',padding:'12px 18px',border:0,borderRadius:10,cursor:'pointer',
              background:C.pop,color:'#FFF',fontFamily:sans,fontSize:15,fontWeight:700,
              boxShadow:`0 6px 18px ${C.glow}`,
            }}>开始对话 →</button>
          </div>
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// APP — layout + state + resize
// ─────────────────────────────────────────────────────────────────────────────
function App() {
  const [stage, setStage] = React.useState('on');
  const [scenarioId, setScenarioId] = React.useState('ON-201');
  const [messages, setMessages] = React.useState(INITIAL_MESSAGES);
  const [sending, setSending] = React.useState(false);
  const [search, setSearch] = React.useState('');
  const [leftW, setLeftW] = React.useState(296);
  const [rightW, setRightW] = React.useState(360);
  const [toast, setToast] = React.useState(null);
  const [extraRefs, setExtraRefs] = React.useState({});      // { code: { laws: [...] } }
  const [transferOpen, setTransferOpen] = React.useState(false);
  const [mode, setMode] = React.useState('agent');           // 'agent' | 'human'
  const nextId = React.useRef(1000);

  // Stable __k on any ref item (static + dynamic)
  const mergedRefs = React.useMemo(() => {
    const base = getRefs(scenarioId);
    const extra = extraRefs[scenarioId];
    const tag = (arr, prefix) => (arr||[]).map((r,i)=>({...r,__k:r.__k || `${prefix}-${r.tag}-${r.main}-${i}`}));
    return {
      laws: [...tag(extra?.laws, 'dyn'), ...tag(base.laws, 'sta')],
      cases: tag(base.cases, 'case'),
      templates: base.templates,
      related: base.related,
    };
  }, [scenarioId, extraRefs]);

  // 切换 scenario 时构造开场白（优先 OPENERS 自定义）
  const initialOpener = React.useCallback((code) => {
    const s = findScenario(code);
    if (!s) return [];
    const text = OPENERS[code] ||
      `已切换到 **${s.code} · ${s.name}**。请把您具体的情况告诉我，我帮您一次性把合规边界、风险点、可落地材料都给您列清楚。`;
    return [{
      id: nextId.current++,
      role: 'agent',
      time: new Date().toTimeString().slice(0, 5),
      text,
    }];
  }, []);

  // 切换 stage 时把 scenarioId 重置为该 stage 的第一个
  React.useEffect(() => {
    const stageInfo = STAGES[stage];
    const first = stageInfo?.groups[0]?.items[0]?.code;
    if (first && findScenario(scenarioId)?.code.slice(0, 2).toLowerCase() !== stage) {
      setScenarioId(first);
    }
  }, [stage]);

  // 切换 scenario 时重置对话 · 同时切回 agent 模式
  // 注意：mountedRef 让首屏保持 INITIAL_MESSAGES 欢迎语，只有用户主动切场景才用 opener
  const mountedRef = React.useRef(false);
  React.useEffect(() => {
    if (!mountedRef.current) { mountedRef.current = true; return; }
    setMessages(initialOpener(scenarioId));
    setMode('agent');
  }, [scenarioId, initialOpener]);

  function pushToast(t) {
    setToast(t);
    setTimeout(() => setToast(null), 2400);
  }

  // 从 agent 回复里抓取法规引用，注入到右侧面板（高亮闪烁）
  function injectRefsFromReply(code, replyText) {
    const re = /《([^》]+)》\s*第\s*(\d+(?:\s*[、,，]\s*\d+)*)\s*条/g;
    const found = [];
    let m;
    while ((m = re.exec(replyText)) !== null) {
      const law = m[1].trim();
      const article = m[2].replace(/\s+/g, '');
      found.push({ law, article, key: `${law}-${article}` });
    }
    if (!found.length) return;
    setExtraRefs((prev) => {
      const existing = prev[code]?.laws || [];
      const existingKeys = new Set(existing.map(r => r.__rawKey));
      // 也跳过静态 REFS 里已经有的（防重）
      const staticLaws = getRefs(code).laws || [];
      const staticKeys = new Set(staticLaws.map(r => {
        const mm = /《?([^《》\s·]+).*第\s*(\d+(?:[、,，]\s*\d+)*)/.exec(r.tag + ' ' + r.main);
        return mm ? `${mm[1]}-${mm[2].replace(/\s+/g,'')}` : null;
      }).filter(Boolean));
      const toAdd = found
        .filter(c => !existingKeys.has(c.key) && !staticKeys.has(c.key))
        .map(c => ({
          tag: `REG · ${c.law}`,
          main: `第 ${c.article} 条`,
          sub: '小薪刚刚引用 · 点查看条文',
          live: true,
          __rawKey: c.key,
          __k: `dyn-${c.key}`,
        }));
      if (!toAdd.length) return prev;
      return { ...prev, [code]: { laws: [...toAdd, ...existing] } };
    });
  }

  async function sendMessage(text) {
    const now = new Date().toTimeString().slice(0, 5);
    const userMsg = { id: nextId.current++, role: 'user', time: now, text };
    setMessages((m) => [...m, userMsg]);
    setSending(true);

    const scenario = findScenario(scenarioId);
    const systemPrompt = mode === 'human'
      ? `你是"李顾问"——薪领航的资深人工 HR 顾问，12 年劳动关系经验。
你刚刚通过转人工通道接入了用户和小薪 AI 的对话。
当前场景：${scenario?.code} · ${scenario?.name}
回答要求：
- 用中文，更口语、更人性化、有同理心（不要像 AI 那样列条列）
- 不要用 markdown 列表；像同事在帮忙
- 100-180 字之间，可以反问以澄清
- 涉及法规可以提，但不必每次都引用`
      : `你是"小薪"，薪领航旗下的中国 AI 合规 HR 助手。
当前场景：${scenario?.code} · ${scenario?.name}
回答要求：
- 用中文，简短有结构（200 字以内），口语化但专业
- 涉及风险时用 **加粗** 强调
- 必要时引用具体法规条文（如《劳动合同法》第 X 条）
- 结尾给出 1-3 个可立即执行的建议，前缀 "→ "
- 如关键信息不足，先反问一句澄清`;

    try {
      const reply = await callAI(systemPrompt, text);
      const agentMsg = {
        id: nextId.current++,
        role: mode === 'human' ? 'human' : 'agent',
        time: new Date().toTimeString().slice(0, 5),
        text: reply,
      };
      setMessages((m) => [...m, agentMsg]);
      if (mode === 'agent') injectRefsFromReply(scenarioId, reply);
    } catch (e) {
      const agentMsg = {
        id: nextId.current++,
        role: mode === 'human' ? 'human' : 'agent',
        time: new Date().toTimeString().slice(0, 5),
        text: '暂时联系不上，请稍后重试。',
      };
      setMessages((m) => [...m, agentMsg]);
    } finally {
      setSending(false);
    }
  }

  function chipFill(content) {
    sendMessage(content);
  }

  function joinHuman() {
    setMode('human');
    setMessages((m) => [...m, {
      id: nextId.current++,
      role: 'system',
      time: new Date().toTimeString().slice(0, 5),
      text: '李顾问 已接入对话 · 小薪暂退',
    }]);
  }

  // Resize handle
  function startDrag(side) {
    return (e) => {
      e.preventDefault();
      const startX = e.clientX;
      const startW = side === 'left' ? leftW : rightW;
      const onMove = (ev) => {
        const dx = ev.clientX - startX;
        if (side === 'left') setLeftW(Math.min(420, Math.max(220, startW + dx)));else
        setRightW(Math.min(520, Math.max(280, startW - dx)));
      };
      const onUp = () => {
        document.removeEventListener('mousemove', onMove);
        document.removeEventListener('mouseup', onUp);
        document.body.style.userSelect = '';
        document.body.style.cursor = '';
      };
      document.addEventListener('mousemove', onMove);
      document.addEventListener('mouseup', onUp);
      document.body.style.userSelect = 'none';
      document.body.style.cursor = 'col-resize';
    };
  }

  return (
    <div style={{
      display: 'grid', gridTemplateColumns: `${leftW}px 5px 1fr 5px ${rightW}px`,
      height: '100vh', width: '100vw', overflow: 'hidden', background: C.bg, fontFamily: sans
    }}>
      <LeftPanel
        stage={stage} setStage={setStage}
        scenarioId={scenarioId} setScenarioId={setScenarioId}
        search={search} setSearch={setSearch}
        onTransfer={()=>setTransferOpen(true)} />
      

      <Divider onMouseDown={startDrag('left')} />

      <ChatPanel
        scenarioId={scenarioId}
        messages={messages}
        sending={sending}
        mode={mode}
        onSend={sendMessage}
        onChipFill={chipFill}
        onToast={pushToast}
        onTransfer={()=>setTransferOpen(true)} />
      

      <Divider onMouseDown={startDrag('right')} />

      <RefsPanel scenarioId={scenarioId} refs={mergedRefs} onToast={pushToast} />

      <TransferModal
        open={transferOpen}
        onClose={()=>setTransferOpen(false)}
        onJoined={joinHuman}
      />

      {/* Toast */}
      {toast &&
      <div style={{
        position: 'fixed', top: 18, left: '50%', transform: 'translateX(-50%)',
        padding: '10px 18px', background: C.fg, color: C.bg, borderRadius: 10,
        fontFamily: sans, fontSize: 13, fontWeight: 500, zIndex: 100,
        boxShadow: '0 12px 32px rgba(0,0,0,0.25)',
        animation: 'cp-toast 2.4s ease-in-out forwards'
      }}>{toast}</div>
      }
    </div>);

}

function Divider({ onMouseDown }) {
  const [hover, setHover] = React.useState(false);
  return (
    <div onMouseDown={onMouseDown}
    onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
    style={{
      cursor: 'col-resize', background: hover ? C.accent : 'transparent',
      transition: 'background .15s', position: 'relative', height: '100%'
    }}>
      {/* center grip indicator */}
      <div style={{
        position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%,-50%)',
        width: 2, height: 32, background: hover ? '#FFF' : C.line2, borderRadius: 1,
        transition: 'background .15s'
      }} />
    </div>);

}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);