// hr-screen.jsx — HR Desktop dashboard for 命運總覽 · 面談篩選後台
// Composes screens.jsx components + adds desktop-only table & detail panel.
// Designed to 1280x800. Reuses MultiRing / Radar / PotentialChart.
//
// TODO [BlockLib-extract]: HRDashboardScreen → 'Lead CRM Block' + 'Pipeline 管理 Block' candidates.
//   - CandidateTable / PipelineTabs / KPIStrip 為通用 CRM 元件，資料結構可抽換。
//   - STAGES pipeline 設定未來可由 block config 傳入（不限招募情境）。
//   - DetailPanel 的 actions / stage change 邏輯為通用 lead 跟進流程。

const { useState: useStateHR, useEffect: useEffectHR, useMemo: useMemoHR } = React;

// ── Stage / pipeline metadata ──────────────────────────────
const STAGES = [
  { id: 'all',      label: '全部',     color: 'var(--fg-2)'        },
  { id: 'new',      label: '新進',     color: 'var(--blue)'        },
  { id: 'meeting',  label: '面談中',   color: 'var(--purple)'      },
  { id: 'invited',  label: '已邀請',   color: 'var(--gold)'        },
  { id: 'joined',   label: '已加入',   color: 'var(--neon-green)'  },
  { id: 'observe',  label: '觀察組',   color: 'var(--neon-teal)'   },
  { id: 'rejected', label: '不適合',   color: 'var(--fg-3)'        },
];

const STAGE_BY_ID = Object.fromEntries(STAGES.map(s => [s.id, s]));

// ── Top-level HR screen ────────────────────────────────────
function HRDashboardScreen({ onOpenCandidate, tone }) {
  const [rows, setRows] = useStateHR(null);
  const [stage, setStage] = useStateHR('all');
  const [query, setQuery] = useStateHR('');
  const [selectedId, setSelectedId] = useStateHR(null);
  const [sortBy, setSortBy] = useStateHR('fit'); // fit | recent | name

  useEffectHR(() => { api.listReports().then(setRows); }, []);

  // KPI math (must be unconditional — runs before early return)
  const kpi = useMemoHR(() => {
    if (!rows) return null;
    const total = rows.length;
    const highFit = rows.filter(r => r.report.scores.fit >= 80).length;
    const meeting = rows.filter(r => r.report.pipelineStage === 'meeting').length;
    const joined  = rows.filter(r => r.report.pipelineStage === 'joined').length;
    const avgFit  = Math.round(rows.reduce((s, r) => s + r.report.scores.fit, 0) / total);
    return { total, highFit, meeting, joined, avgFit };
  }, [rows]);

  if (!rows) return <HRShell><div style={{ padding: 60, color: 'var(--fg-3)' }}>讀取中…</div></HRShell>;

  // Filter + sort
  const filtered = rows
    .filter(r => stage === 'all' || r.report.pipelineStage === stage)
    .filter(r => !query || r.profile.name.includes(query) || r.profile.id.includes(query) || (r.profile.mbti || '').includes(query.toUpperCase()))
    .sort((a, b) => {
      if (sortBy === 'fit')    return b.report.scores.fit - a.report.scores.fit;
      if (sortBy === 'recent') return b.report.completedAt.localeCompare(a.report.completedAt);
      return a.profile.name.localeCompare(b.profile.name);
    });

  const selected = rows.find(r => r.profile.id === selectedId);

  return (
    <HRShell>
      <HRTopBar/>

      <div style={{ display: 'grid', gridTemplateColumns: selected ? '1fr 440px' : '1fr',
                    gap: 16, padding: '16px 24px 24px', height: 'calc(100% - 56px)', overflow: 'hidden' }}>
        {/* main column */}
        <div style={{ overflow: 'auto', display: 'flex', flexDirection: 'column', gap: 16 }}>
          <KPIStrip kpi={kpi}/>

          {/* filter row */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
            <PipelineTabs value={stage} onChange={setStage} rows={rows}/>
            <div style={{ flex: 1 }}/>
            <SortSelect value={sortBy} onChange={setSortBy}/>
            <SearchBox value={query} onChange={setQuery}/>
          </div>

          {/* table */}
          <CandidateTable
            rows={filtered}
            selectedId={selectedId}
            onSelect={id => setSelectedId(id === selectedId ? null : id)}
            onOpen={onOpenCandidate}/>
        </div>

        {/* right panel */}
        {selected && (
          <DetailPanel
            data={selected}
            tone={tone}
            onClose={() => setSelectedId(null)}
            onOpen={() => onOpenCandidate(selected.profile.id)}
            onStageChange={async (stg) => {
              await api.updatePipelineStage(selected.profile.id, stg);
              api.listReports().then(setRows);
            }}/>
        )}
      </div>
    </HRShell>
  );
}

// ── Shell: page bg + global container ─────────────────────
function HRShell({ children }) {
  return (
    <div style={{
      width: '100%', height: '100%', minHeight: 800,
      background: 'radial-gradient(ellipse at top left, #14182B 0%, #06070D 60%)',
      color: 'var(--fg)', overflow: 'hidden', display: 'flex', flexDirection: 'column',
    }}>{children}</div>
  );
}

// ── Top bar ───────────────────────────────────────────────
function HRTopBar() {
  return (
    <div style={{
      height: 56, padding: '0 24px',
      display: 'flex', alignItems: 'center', gap: 24,
      borderBottom: '1px solid var(--line)',
      background: 'rgba(11,14,24,0.65)', backdropFilter: 'blur(12px)',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 28, height: 28, borderRadius: 8,
          background: 'linear-gradient(135deg, #B07CFF, #FF5DA2)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: '#fff', fontSize: 14, fontWeight: 700,
          boxShadow: '0 0 8px rgba(176,124,255,0.5)',
        }}>✦</div>
        <div>
          <div style={{ fontSize: 14, fontWeight: 600 }}>人生事業版圖</div>
          <div style={{ fontSize: 10, color: 'var(--fg-3)', letterSpacing: '0.2em' }}>面談篩選後台</div>
        </div>
      </div>

      <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
        <NavTab active label="候選人"/>
        <NavTab label="行動"/>
        <NavTab label="統計"/>
        <NavTab label="設定"/>
      </div>

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

      <div style={{ display: 'flex', alignItems: 'center', gap: 12, fontSize: 12, color: 'var(--fg-3)' }}>
        <span>2026 / 05 / 15</span>
        <span style={{ opacity: 0.5 }}>·</span>
        <span style={{ color: 'var(--neon-green)' }}>● 線上</span>
      </div>

      <div style={{
        width: 32, height: 32, borderRadius: '50%',
        background: 'linear-gradient(135deg, #5BA9FF, #B07CFF)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: '#fff', fontSize: 13, fontWeight: 600,
      }}>HR</div>
    </div>
  );
}

function NavTab({ label, active }) {
  return (
    <div style={{
      padding: '6px 14px', borderRadius: 99,
      fontSize: 13, fontWeight: active ? 600 : 400,
      color: active ? 'var(--fg)' : 'var(--fg-3)',
      background: active ? 'rgba(176,124,255,0.12)' : 'transparent',
      border: `1px solid ${active ? 'rgba(176,124,255,0.3)' : 'transparent'}`,
      cursor: 'pointer',
    }}>{label}</div>
  );
}

// ── KPI strip ─────────────────────────────────────────────
function KPIStrip({ kpi }) {
  const items = [
    { label: '候選人總數',  value: kpi.total,   delta: '+5 本週',       color: 'var(--fg)'         },
    { label: '高適配 ≥80',  value: kpi.highFit, delta: `${Math.round(kpi.highFit/kpi.total*100)}%`, color: 'var(--neon-green)' },
    { label: '面談中',      value: kpi.meeting, delta: '本週新進 2',    color: 'var(--purple)'     },
    { label: '已加入',      value: kpi.joined,  delta: '轉化率 25%',    color: 'var(--gold)'       },
    { label: '平均適配',    value: kpi.avgFit + '%', delta: '+4 vs. 上月', color: 'var(--magenta)'  },
  ];
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 12 }}>
      {items.map((it, i) => (
        <div key={i} style={{
          background: 'var(--bg-card)', border: '1px solid var(--line)',
          borderRadius: 16, padding: 16, position: 'relative', overflow: 'hidden',
        }}>
          <div style={{ position: 'absolute', top: -12, right: -12, width: 60, height: 60,
                        borderRadius: '50%', background: it.color, opacity: 0.10, filter: 'blur(18px)' }}/>
          <div style={{ fontSize: 11, color: 'var(--fg-2)', letterSpacing: '0.06em' }}>{it.label}</div>
          <div className="num" style={{ fontSize: 30, fontWeight: 600, marginTop: 4, color: it.color,
                                        textShadow: `0 0 12px ${it.color}33` }}>{it.value}</div>
          <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 4 }}>{it.delta}</div>
        </div>
      ))}
    </div>
  );
}

// ── Pipeline tabs ─────────────────────────────────────────
function PipelineTabs({ value, onChange, rows }) {
  const counts = STAGES.reduce((acc, s) => {
    acc[s.id] = s.id === 'all' ? rows.length : rows.filter(r => r.report.pipelineStage === s.id).length;
    return acc;
  }, {});
  return (
    <div style={{ display: 'flex', gap: 6, padding: 4,
                  background: 'var(--bg-card)', border: '1px solid var(--line)',
                  borderRadius: 14 }}>
      {STAGES.map(s => {
        const active = s.id === value;
        return (
          <button key={s.id} onClick={() => onChange(s.id)} style={{
            background: active ? `${s.color}1A` : 'transparent',
            border: `1px solid ${active ? `${s.color}55` : 'transparent'}`,
            borderRadius: 10, padding: '6px 12px', cursor: 'pointer',
            color: active ? s.color : 'var(--fg-3)',
            fontSize: 12, fontWeight: active ? 600 : 400,
            fontFamily: 'inherit',
            display: 'flex', alignItems: 'center', gap: 6,
          }}>
            <span>{s.label}</span>
            <span className="num" style={{
              fontSize: 10, padding: '1px 6px', borderRadius: 99,
              background: active ? `${s.color}33` : 'rgba(255,255,255,0.06)',
              color: active ? s.color : 'var(--fg-3)',
            }}>{counts[s.id]}</span>
          </button>
        );
      })}
    </div>
  );
}

function SortSelect({ value, onChange }) {
  const opts = [{value:'fit',label:'適配高→低'},{value:'recent',label:'最近完成'},{value:'name',label:'姓名'}];
  return (
    <select value={value} onChange={e => onChange(e.target.value)} style={{
      background: 'var(--bg-card)', border: '1px solid var(--line)',
      borderRadius: 10, padding: '8px 12px', color: 'var(--fg)',
      fontSize: 12, fontFamily: 'inherit', cursor: 'pointer',
    }}>{opts.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}</select>
  );
}

function SearchBox({ value, onChange }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 6,
      background: 'var(--bg-card)', border: '1px solid var(--line)',
      borderRadius: 10, padding: '0 12px', width: 220,
    }}>
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--fg-3)" strokeWidth="2" strokeLinecap="round">
        <circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/>
      </svg>
      <input value={value} onChange={e => onChange(e.target.value)}
             placeholder="搜尋姓名 / 命盤代號 / MBTI"
             style={{
               flex: 1, background: 'transparent', border: 'none',
               padding: '8px 0', color: 'var(--fg)', fontSize: 12,
               fontFamily: 'inherit', outline: 'none',
             }}/>
    </div>
  );
}

// ── Candidate table ───────────────────────────────────────
function CandidateTable({ rows, selectedId, onSelect, onOpen }) {
  return (
    <div style={{ background: 'var(--bg-card)', border: '1px solid var(--line)', borderRadius: 16, overflow: 'hidden' }}>
      <div style={{
        display: 'grid',
        gridTemplateColumns: '52px 1.4fr 76px 1.2fr 84px 1fr 70px 90px 100px',
        gap: 12, padding: '12px 18px',
        fontSize: 10, color: 'var(--fg-3)', letterSpacing: '0.16em',
        borderBottom: '1px solid var(--line)',
      }}>
        <span></span>
        <span>候選人</span>
        <span style={{ textAlign: 'center' }}>適配</span>
        <span>天時 · 地利 · 人和</span>
        <span>MBTI</span>
        <span>DISC</span>
        <span>動機</span>
        <span>流年</span>
        <span style={{ textAlign: 'right' }}>階段</span>
      </div>
      {rows.map(r => (
        <CandidateRow key={r.profile.id} data={r}
                      selected={r.profile.id === selectedId}
                      onClick={() => onSelect(r.profile.id)}
                      onOpen={() => onOpen(r.profile.id)}/>
      ))}
      {rows.length === 0 && (
        <div style={{ padding: 40, textAlign: 'center', color: 'var(--fg-3)', fontSize: 12 }}>
          沒有符合條件的候選人
        </div>
      )}
    </div>
  );
}

function CandidateRow({ data, selected, onClick, onOpen }) {
  const { profile, report } = data;
  const s = report.scores;
  const stage = STAGE_BY_ID[report.pipelineStage] || STAGE_BY_ID.new;

  return (
    <div onClick={onClick} style={{
      display: 'grid', alignItems: 'center',
      gridTemplateColumns: '52px 1.4fr 76px 1.2fr 84px 1fr 70px 90px 100px',
      gap: 12, padding: '14px 18px',
      borderBottom: '1px solid var(--line)',
      background: selected ? 'rgba(176,124,255,0.06)' : 'transparent',
      cursor: 'pointer',
      transition: 'background 120ms',
    }}
    onMouseOver={e => { if (!selected) e.currentTarget.style.background = 'rgba(255,255,255,0.02)'; }}
    onMouseOut={e => { if (!selected) e.currentTarget.style.background = 'transparent'; }}>
      {/* mini ring */}
      <div style={{ position: 'relative' }}>
        <MultiRing a={s.tianshi/100} b={s.dili/100} c={s.renhe/100} size={40}/>
      </div>

      {/* name + id */}
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 500, color: 'var(--fg)' }}>{profile.name}</div>
        <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 2 }} className="num">{profile.id}</div>
      </div>

      {/* fit score */}
      <div style={{ textAlign: 'center' }}>
        <span className="num" style={{
          fontSize: 22, fontWeight: 600,
          color: s.fit >= 80 ? 'var(--neon-green)' : s.fit >= 60 ? 'var(--gold)' : 'var(--fg-3)',
          textShadow: s.fit >= 80 ? '0 0 8px rgba(43,212,168,0.4)' : 'none',
        }}>{s.fit}</span>
        <div style={{ fontSize: 9, color: 'var(--fg-3)', letterSpacing: '0.2em' }}>FIT</div>
      </div>

      {/* 天地人 bars */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
        <TLine label="天" value={s.tianshi} color="var(--gold)"/>
        <TLine label="地" value={s.dili}    color="var(--neon-green)"/>
        <TLine label="人" value={s.renhe}   color="var(--magenta)"/>
      </div>

      {/* MBTI */}
      <div>
        <div style={{
          display: 'inline-block', fontSize: 12, padding: '4px 8px',
          background: 'rgba(91,169,255,0.15)', color: 'var(--blue)',
          borderRadius: 6, fontFamily: 'var(--font-mono)', fontWeight: 600,
          border: '1px solid rgba(91,169,255,0.3)', whiteSpace: 'nowrap',
        }}>{report.mbti}</div>
      </div>

      {/* DISC */}
      <div style={{ display: 'flex', gap: 4 }}>
        {['D','I','S','C'].map(k => {
          const v = profile.disc[k] || 0;
          return (
            <div key={k} style={{
              flex: 1, height: 30, borderRadius: 4,
              background: 'rgba(255,255,255,0.04)',
              border: '1px solid var(--line)',
              display: 'flex', flexDirection: 'column', alignItems: 'center',
              justifyContent: 'space-between', padding: '2px 0',
              position: 'relative', overflow: 'hidden',
            }}>
              <div style={{
                position: 'absolute', bottom: 0, left: 0, right: 0,
                height: `${v}%`,
                background: v >= 70 ? 'rgba(255,93,162,0.35)' : v >= 50 ? 'rgba(176,124,255,0.25)' : 'rgba(91,169,255,0.15)',
              }}/>
              <span style={{ fontSize: 8, color: 'var(--fg-3)', position: 'relative' }}>{k}</span>
              <span className="num" style={{ fontSize: 9, color: 'var(--fg-2)', position: 'relative' }}>{v}</span>
            </div>
          );
        })}
      </div>

      {/* motivation */}
      <div className="num" style={{ fontSize: 14, color: 'var(--gold)' }}>{s.motivation}</div>

      {/* bazi year */}
      <div style={{ fontSize: 11, color: 'var(--fg-2)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
        {report.bazi.year}
      </div>

      {/* stage */}
      <div style={{ textAlign: 'right' }}>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          fontSize: 11, padding: '4px 10px', borderRadius: 99,
          background: `${stage.color}1A`, color: stage.color,
          border: `1px solid ${stage.color}33`,
        }}>
          <span style={{ width: 5, height: 5, borderRadius: 99, background: stage.color,
                          boxShadow: `0 0 4px ${stage.color}` }}/>
          {stage.label}
        </span>
      </div>
    </div>
  );
}

function TLine({ label, value, color }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
      <span style={{ fontSize: 9, color: 'var(--fg-3)', width: 10 }}>{label}</span>
      <div style={{ flex: 1, height: 4, borderRadius: 99, background: 'rgba(255,255,255,0.05)' }}>
        <div style={{ width: `${value}%`, height: '100%', borderRadius: 99, background: color,
                       boxShadow: `0 0 4px ${color}` }}/>
      </div>
      <span className="num" style={{ fontSize: 10, color: 'var(--fg-2)', width: 22, textAlign: 'right' }}>{value}</span>
    </div>
  );
}

// ── Detail panel ──────────────────────────────────────────
function DetailPanel({ data, tone, onClose, onOpen, onStageChange }) {
  const { profile, report } = data;
  const s = report.scores;
  const stage = STAGE_BY_ID[report.pipelineStage];

  return (
    <div style={{
      background: 'var(--bg-card)', border: '1px solid var(--line)',
      borderRadius: 16, overflow: 'auto', height: '100%',
      animation: 'slideInRight 280ms cubic-bezier(.2,.8,.2,1)',
    }}>
      <div style={{ padding: 18, borderBottom: '1px solid var(--line)',
                    display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                    position: 'sticky', top: 0, background: 'var(--bg-card)', zIndex: 2 }}>
        <div>
          <div style={{ fontSize: 18, fontWeight: 600 }}>{profile.name}</div>
          <div style={{ fontSize: 11, color: 'var(--fg-3)' }} className="num">{profile.id}</div>
        </div>
        <button onClick={onClose} style={{
          background: 'transparent', border: 'none', color: 'var(--fg-3)',
          fontSize: 22, cursor: 'pointer', fontFamily: 'inherit',
        }}>×</button>
      </div>

      <div style={{ padding: 18 }}>
        {/* hero card */}
        <div style={{
          background: 'linear-gradient(165deg, #1F1A38 0%, #2B1F3D 100%)',
          border: '1px solid rgba(176,124,255,0.25)',
          borderRadius: 18, padding: 18, display: 'flex', alignItems: 'center', gap: 16,
        }}>
          <MultiRing a={s.tianshi/100} b={s.dili/100} c={s.renhe/100} size={110}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 10, color: 'var(--purple)', letterSpacing: '0.3em' }}>FIT SCORE</div>
            <div className="num" style={{ fontSize: 40, fontWeight: 600, lineHeight: 1, marginTop: 2,
                                          color: 'var(--fg)',
                                          background: 'linear-gradient(120deg, #FFFFFF, #B07CFF)',
                                          WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }}>{s.fit}</div>
            <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 4 }}>{report.mbti} · {report.bazi.dayMaster}</div>
          </div>
        </div>

        {/* verdict */}
        <div style={{ marginTop: 14, fontSize: 13, lineHeight: 1.7, color: 'var(--fg-2)' }}>
          {(report.interpretation && report.interpretation.verdict) || report.verdict}
        </div>

        {/* tone-flexed quote (only show in spiritual/hybrid) */}
        {tone !== 'data' && (
          <div style={{
            marginTop: 14, padding: 12, borderRadius: 14,
            background: 'linear-gradient(120deg, rgba(176,124,255,0.10), rgba(255,93,162,0.06))',
            border: '1px solid rgba(176,124,255,0.18)',
            fontSize: 12, lineHeight: 1.8, color: 'var(--fg)', whiteSpace: 'pre-line',
          }}>{(report.interpretation && report.interpretation.quote) || report.quote}</div>
        )}

        {/* 3 pillar cards */}
        <div style={{ marginTop: 14, display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
          <PanelStat label="天時" value={s.tianshi} color="var(--gold)" sub={report.bazi.year}/>
          <PanelStat label="地利" value={s.dili}    color="var(--neon-green)" sub="位能評估"/>
          <PanelStat label="人和" value={s.renhe}   color="var(--magenta)" sub={report.mbti}/>
        </div>

        {/* 地利 breakdown — the user's requested structure */}
        <div style={{ marginTop: 14 }}>
          <SectionLabel title="地利 · 單位資源匹配" subtitle="攝影棚 / 遊戲池 / 家庭支援"/>
          <div style={{ marginTop: 8, display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
            <ResourceCell label="攝影棚" sub="個人品牌" value={report.diliBreakdown.studio}     color="var(--purple)"/>
            <ResourceCell label="遊戲池" sub="業務隊伍" value={report.diliBreakdown.gamePool}   color="var(--neon-green)"/>
            <ResourceCell label="家庭支援" sub="原生需求" value={report.diliBreakdown.familySupport} color="var(--gold)"/>
          </div>
        </div>

        {/* Radar */}
        <div style={{ marginTop: 14 }}>
          <SectionLabel title="天賦解讀"/>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 8 }}>
            <Radar values={[
              { label:'動機', value: s.motivation/200 },
              { label:'天時', value: s.tianshi/100 },
              { label:'地利', value: s.dili/100 },
              { label:'人和', value: s.renhe/100 },
              { label:'貴人', value: s.benefactor/100 },
            ]} size={140}/>
            <div style={{ fontSize: 11, color: 'var(--fg-3)', lineHeight: 1.8 }}>
              天命覺醒 <span className="num" style={{ color: 'var(--neon-green)' }}>{s.tianMing}</span><br/>
              能量共振 <span className="num" style={{ color: 'var(--neon-teal)' }}>{s.resonance}</span><br/>
              事業轉折 <span className="num" style={{ color: 'var(--magenta)' }}>{s.careerTurn}</span><br/>
              貴人機遇 <span className="num" style={{ color: 'var(--neon-green)' }}>{s.benefactor}</span>
            </div>
          </div>
        </div>

        {/* Actions */}
        <div style={{ marginTop: 14 }}>
          <SectionLabel title="建議行動"/>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 8 }}>
            {report.actions.map((a, i) => (
              <div key={a.id} style={{
                background: 'rgba(255,255,255,0.03)', border: '1px solid var(--line)',
                borderRadius: 12, padding: '10px 12px',
              }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                  <span style={{ fontSize: 13, fontWeight: 500 }}>{a.title}</span>
                  <span style={{ fontSize: 10, color: 'var(--fg-3)' }}>{a.ctaLabel}</span>
                </div>
                <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 2 }}>{a.subtitle}</div>
                {a.reason && (
                  <div style={{ marginTop: 6, fontSize: 10, color: 'var(--purple)',
                                opacity: 0.85, fontStyle: 'normal' }}>↳ {a.reason}</div>
                )}
              </div>
            ))}
          </div>
        </div>

        {/* Stage actions */}
        <div style={{ marginTop: 18 }}>
          <SectionLabel title="變更階段"/>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 8 }}>
            {STAGES.filter(s => s.id !== 'all').map(s => (
              <button key={s.id} onClick={() => onStageChange(s.id)} style={{
                background: stage.id === s.id ? `${s.color}22` : 'rgba(255,255,255,0.04)',
                border: `1px solid ${stage.id === s.id ? `${s.color}66` : 'var(--line)'}`,
                color: stage.id === s.id ? s.color : 'var(--fg-2)',
                borderRadius: 8, padding: '6px 10px', cursor: 'pointer',
                fontSize: 11, fontFamily: 'inherit',
                fontWeight: stage.id === s.id ? 600 : 400,
              }}>{s.label}</button>
            ))}
          </div>
        </div>

        {/* CTAs */}
        <div style={{ marginTop: 18, display: 'flex', gap: 8 }}>
          <button onClick={onOpen} style={{
            flex: 1, background: 'linear-gradient(120deg, #B07CFF, #FF5DA2)',
            border: 'none', borderRadius: 12, padding: '12px 16px', cursor: 'pointer',
            color: '#fff', fontSize: 13, fontWeight: 600, fontFamily: 'inherit',
            boxShadow: '0 6px 18px rgba(176,124,255,0.3)',
          }}>查看完整報告</button>
          <button style={{
            background: 'rgba(255,255,255,0.04)', border: '1px solid var(--line)',
            borderRadius: 12, padding: '12px 16px', cursor: 'pointer',
            color: 'var(--fg-2)', fontSize: 13, fontFamily: 'inherit',
          }}>匯出 PDF</button>
        </div>
      </div>
    </div>
  );
}

function SectionLabel({ title, subtitle }) {
  return (
    <div style={{ padding: '0 2px' }}>
      <div style={{ fontSize: 11, color: 'var(--fg)', fontWeight: 600, letterSpacing: '0.16em' }}>{title}</div>
      {subtitle && <div style={{ fontSize: 10, color: 'var(--fg-3)', marginTop: 2 }}>{subtitle}</div>}
    </div>
  );
}

function PanelStat({ label, value, color, sub }) {
  return (
    <div style={{ background: 'rgba(255,255,255,0.04)', border: '1px solid var(--line)',
                  borderRadius: 12, padding: '10px 12px' }}>
      <div style={{ fontSize: 10, color: 'var(--fg-2)' }}>{label}</div>
      <div className="num" style={{ fontSize: 22, color, fontWeight: 600, marginTop: 2 }}>{value}</div>
      <div style={{ marginTop: 4, height: 3, borderRadius: 99, background: 'rgba(255,255,255,0.06)' }}>
        <div style={{ width: `${value}%`, height: '100%', borderRadius: 99, background: color,
                       boxShadow: `0 0 4px ${color}` }}/>
      </div>
      {sub && <div style={{ fontSize: 9, color: 'var(--fg-3)', marginTop: 4,
                              whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{sub}</div>}
    </div>
  );
}

function ResourceCell({ label, sub, value, color }) {
  const r = 28, cx = 32, cy = 32;
  const C = 2 * Math.PI * r;
  return (
    <div style={{ background: 'rgba(255,255,255,0.04)', border: '1px solid var(--line)',
                  borderRadius: 12, padding: 10, display: 'flex', alignItems: 'center', gap: 10 }}>
      <svg width="64" height="64" viewBox="0 0 64 64">
        <circle cx={cx} cy={cy} r={r} fill="none" stroke="rgba(255,255,255,0.06)" strokeWidth="5"/>
        <circle cx={cx} cy={cy} r={r} fill="none" stroke={color} strokeWidth="5" strokeLinecap="round"
                strokeDasharray={`${C * value/100} ${C}`}
                transform={`rotate(-90 ${cx} ${cy})`}
                style={{ filter: `drop-shadow(0 0 4px ${color})` }}/>
        <text x={cx} y={cy+4} textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--fg)" fontFamily="var(--font-mono)">
          {value}
        </text>
      </svg>
      <div>
        <div style={{ fontSize: 11, color: 'var(--fg)', fontWeight: 500 }}>{label}</div>
        <div style={{ fontSize: 9, color: 'var(--fg-3)' }}>{sub}</div>
      </div>
    </div>
  );
}

// expose
Object.assign(window, { HRDashboardScreen });
