/* ========== 命令室 v4：第一性原理 + AI 滲透 ========== */

function CommandRoom({ items, todos, onSelect, switchView }) {
  const { state, stats, record, reset } = useDecisions();
  const acceptedSet = useMemo(() => new Set(state.accepted), [state.accepted]);
  const skippedSet = useMemo(() => new Set(state.skipped), [state.skipped]);

  // 計算上下文
  const ctx = useMemo(() => buildContext(items, todos), [items, todos]);

  // AI 旁白
  const insightPrompt = useMemo(() => `你是 KaiOS 的 AI 助理，正在為紅茶巴士／阿檸的老闆 Kai 看內容生產儀表板。
以下是現在的真實狀態：
- 已上線 ${ctx.live} 支，🏆 高表現 ${ctx.high} 支（勝率 ${ctx.winRate}%）
- 卡關 ${ctx.stuck} 項（最久 ${ctx.maxStuck} 天）
- 待拍 ${ctx.ready} 支，靈感 ${ctx.inboxCount} 個未處理
- 最近一支：${ctx.recent ? `${ctx.recent.title || ctx.recent.topic}（${ctx.recent.b?.p === 'high' ? '高表現' : ctx.recent.b?.p === 'low' ? '啞彈' : '一般'}）` : '無'}
- Kai 本週已做 ${stats.week} 個決策

用一句話告訴 Kai「今天最該做什麼」。20-30 個中文字，繁體中文，口語有溫度，直接給結論，不要客套。`, [ctx.live, ctx.high, ctx.stuck, ctx.ready, ctx.recent?.id]);

  const cacheKey = `insight:${new Date().toDateString()}:${ctx.live}:${ctx.stuck}`;
  const { text: insightText, loading: insightLoading } = useAI(insightPrompt, cacheKey);

  // 軌跡 + 漂移
  const traj = useMemo(() => buildTrajectory(items), [items]);
  const drift = useMemo(() => detectDrift(items), [items]);

  // 推薦下一支
  const recommendation = useMemo(() => recommendNext(items, skippedSet, acceptedSet), [items, skippedSet, acceptedSet]);

  // 待回填
  const needBackfill = useMemo(() =>
    items.filter(i => i.status === '已上線' && !i.b && i.publish).slice(0, 3),
    [items]
  );

  // 卡關
  const stuckList = useMemo(() =>
    items.filter(isStuck).sort((a, b) => (b.age || 0) - (a.age || 0)).slice(0, 3),
    [items]
  );

  const handleAction = (kind, id, action) => {
    record(kind, id, action);
  };

  return (
    <div style={{ flex: 1, overflowY: 'auto' }}>
      {/* AI 旁白 Hero */}
      <section style={{
        padding: '32px 32px 24px',
        position: 'relative',
        background: 'linear-gradient(180deg, rgba(232,133,101,0.12) 0%, transparent 100%)',
        borderBottom: '1px solid var(--line-faint)',
      }}>
        <div style={{ maxWidth: 960 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
            <AIBadge size="md" />
            <span className="mono" style={{ fontSize: 11, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>
              {new Date().toLocaleDateString('zh-TW', { weekday: 'long', month: 'long', day: 'numeric' })} · 今日洞察
            </span>
            <div style={{ flex: 1 }} />
            <WeekSummary stats={stats} />
          </div>

          <h1 style={{
            fontSize: 28, fontWeight: 700, lineHeight: 1.4,
            letterSpacing: '-0.02em', color: 'var(--ink-0)', minHeight: 78,
          }}>
            {insightLoading || !insightText ? (
              <span style={{ color: 'var(--ink-3)' }}>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 9 }}>
                  <Icon name="cpu" size={20} />
                  分析 pipeline、表現公式、卡關狀態中…
                </span>
              </span>
            ) : (
              <span style={{ animation: 'slide-up 0.5s var(--ease-out)' }}>{insightText}</span>
            )}
          </h1>

          <div style={{ display: 'flex', gap: 24, marginTop: 22, flexWrap: 'wrap' }}>
            <VitalStat label="待拍" value={ctx.ready} hint="支" onClick={() => switchView('pipeline')} />
            <VitalStat label="卡關" value={ctx.stuck} hint="項" warn={ctx.stuck > 0} onClick={() => switchView('pipeline')} />
            <VitalStat label="待回填" value={needBackfill.length} hint="支" warn={needBackfill.length > 2} />
            <VitalStat label="靈感未篩" value={ctx.inboxCount} hint="個" />
            <VitalStat label="勝率" value={ctx.winRate} hint="%" good={ctx.winRate >= 25} />
          </div>
        </div>
      </section>

      <div style={{ padding: '24px 32px' }}>
        {/* 軌跡 */}
        <TrajectoryCard traj={traj} onSelect={onSelect} />

        {/* 漂移警示 */}
        <DriftCard drift={drift} items={items} onSelect={onSelect} />

        {/* 決策佇列 */}
        <SectionHead>今天的決策佇列</SectionHead>

        {/* 卡 1：下一支該拍 - 加 AI 標題 */}
        {recommendation && (
          <DecisionCard
            tone="primary"
            label="下一支該拍"
            time={`靈感放了 ${recommendation.idea.age} 天`}
            title={recommendation.idea.topic}
            subtitle={`配 ${recommendation.opening.code}（${recommendation.opening.name}）+ ${recommendation.cta.code}（${recommendation.cta.name}）  ·  公式勝率 ${Math.round(recommendation.opening.win_rate * 100)}% × ${Math.round(recommendation.cta.win_rate * 100)}%`}
            reason={recommendation.reason}
            evidence={recommendation.evidence}
            extra={<AITitleCandidates idea={recommendation.idea} opening={recommendation.opening} cta={recommendation.cta} />}
            primaryLabel="接受並開始"
            onPrimary={() => handleAction('shoot', recommendation.idea.id, 'accept')}
            onSkip={() => handleAction('shoot', recommendation.idea.id, 'skip')}
            onDetail={() => onSelect(recommendation.idea.id)}
            accepted={acceptedSet.has(recommendation.idea.id)}
          />
        )}

        {/* 卡 2：需要回填 */}
        {needBackfill.length > 0 && (
          <DecisionCard
            tone="info"
            label="需要回填"
            time={`已上線 ${getDays(needBackfill[0].publish)} 天`}
            title={needBackfill[0].title || needBackfill[0].topic}
            subtitle={`還有 ${needBackfill.length - 1} 支等 IG 後台數據`}
            reason="3 天內回填可觸發學習循環，自動提取贏家公式或風險模式"
            evidence={needBackfill.map(i => i.vid).filter(Boolean)}
            primaryLabel="開始回填"
            onPrimary={() => handleAction('backfill', needBackfill[0].id, 'accept')}
            onDetail={() => onSelect(needBackfill[0].id)}
            accepted={acceptedSet.has(needBackfill[0].id)}
          />
        )}

        {/* 卡 3：卡關決策 */}
        {stuckList.length > 0 && (
          <DecisionCard
            tone="warn"
            label="需要決策"
            time={`已卡 ${stuckList[0].age} 天`}
            title={stuckList[0].title || stuckList[0].topic}
            subtitle={`狀態：${STAGE_LABELS[stuckList[0].status]} · 時限 ${THRESHOLDS[stuckList[0].status] || '∞'} 天 · 超時 ${stuckList[0].age - (THRESHOLDS[stuckList[0].status] || 0)} 天`}
            reason={stuckList[0].notes || '長期停滯影響 pipeline 健康度，建議推進或封存'}
            evidence={stuckList.slice(0, 3).map(i => i.id)}
            primaryLabel="推進這個"
            onPrimary={() => handleAction('unblock', stuckList[0].id, 'accept')}
            onSkip={() => handleAction('unblock', stuckList[0].id, 'skip')}
            onDetail={() => onSelect(stuckList[0].id)}
            accepted={acceptedSet.has(stuckList[0].id)}
          />
        )}

        {!recommendation && needBackfill.length === 0 && stuckList.length === 0 && (
          <div style={{ padding: 50, textAlign: 'center', color: 'var(--ink-3)' }}>
            <div style={{ fontSize: 40, marginBottom: 12 }}>🎉</div>
            <div style={{ fontSize: 14 }}>沒有待決策的事項，Pipeline 健康。</div>
          </div>
        )}

        {/* Twins */}
        <div style={{ marginTop: 18 }}>
          <SectionHead>AI 發現的對比</SectionHead>
          <TwinsCard items={items} onSelect={onSelect} />
        </div>

        {/* 近期脈動 */}
        <div style={{ marginTop: 8 }}>
          <SectionHead action={
            <button onClick={() => switchView('performance')} style={{ fontSize: 11, color: 'var(--kai-bright)' }}>
              完整分析 →
            </button>
          }>近期脈動</SectionHead>
          <PulseRow items={items} onSelect={onSelect} />
        </div>

        {/* 本日決策 log */}
        {state.decisions.length > 0 && (
          <div style={{ marginTop: 24 }}>
            <SectionHead action={
              <button onClick={() => { if (confirm('清除所有決策記錄？')) reset(); }} style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>
                重置
              </button>
            }>決策歷史 · {state.decisions.length}</SectionHead>
            <DecisionLog decisions={state.decisions.slice(0, 8)} items={items} onSelect={onSelect} />
          </div>
        )}
      </div>
    </div>
  );
}

/* ===== 本週摘要 ===== */
function WeekSummary({ stats }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 10,
      padding: '6px 12px', background: 'var(--bg-2)',
      border: '1px solid var(--line)', borderRadius: 8,
      fontSize: 11,
    }}>
      <span style={{ color: 'var(--ink-3)' }}>本週決策</span>
      <span className="mono" style={{ fontWeight: 700, color: 'var(--ink-0)' }}>{stats.week}</span>
      <span style={{ color: 'var(--ink-4)' }}>·</span>
      <span style={{ color: 'var(--high)' }}>接受 {stats.weekAccepted}</span>
      <span style={{ color: 'var(--ink-4)' }}>·</span>
      <span style={{ color: 'var(--ink-2)' }}>跳過 {stats.week - stats.weekAccepted}</span>
    </div>
  );
}

/* ===== Vital Stat ===== */
function VitalStat({ label, value, hint, warn, good, onClick }) {
  const c = warn ? 'var(--low)' : good ? 'var(--high)' : 'var(--ink-0)';
  return (
    <button onClick={onClick} disabled={!onClick} style={{
      display: 'inline-flex', alignItems: 'baseline', gap: 6,
      background: 'none', padding: 0, cursor: onClick ? 'pointer' : 'default',
      transition: 'opacity 0.15s',
    }}
      onMouseEnter={e => { if (onClick) e.currentTarget.style.opacity = 0.7; }}
      onMouseLeave={e => { e.currentTarget.style.opacity = 1; }}>
      <span style={{ fontSize: 13, color: 'var(--ink-3)' }}>{label}</span>
      <span className="mono" style={{ fontSize: 19, fontWeight: 700, color: c, lineHeight: 1 }}>{value}</span>
      <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{hint}</span>
    </button>
  );
}

/* ===== Section Head ===== */
function SectionHead({ children, action }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12, marginTop: 4 }}>
      <div style={{ fontSize: 11, color: 'var(--ink-3)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.12em', fontFamily: 'var(--mono)' }}>
        {children}
      </div>
      {action}
    </div>
  );
}

/* ===== Decision Card ===== */
function DecisionCard({ tone, label, time, title, subtitle, reason, evidence, extra, primaryLabel, onPrimary, onSkip, onDetail, accepted }) {
  const tones = {
    primary: { c: 'var(--kai-bright)', bg: 'var(--kai-tint)', border: 'var(--kai-glow)' },
    info: { c: 'var(--info)', bg: 'var(--info-glow)', border: 'var(--info-glow)' },
    warn: { c: 'var(--warn)', bg: 'var(--warn-glow)', border: 'var(--warn-glow)' },
  };
  const tn = tones[tone] || tones.primary;

  return (
    <div style={{
      padding: 22,
      background: 'var(--bg-1)',
      border: `1px solid ${accepted ? tn.c : 'var(--line)'}`,
      borderRadius: 12, marginBottom: 12,
      position: 'relative', overflow: 'hidden',
      animation: 'slide-up 0.4s var(--ease-out)',
      opacity: accepted ? 0.65 : 1,
      transition: 'opacity 0.3s, border-color 0.2s',
    }}>
      <div style={{ position: 'absolute', top: 0, left: 0, bottom: 0, width: 3, background: tn.c }} />

      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
        <Pill color={tn.c} bg={tn.bg} border={tn.border} size="md">{label}</Pill>
        <span className="mono" style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>{time}</span>
        {accepted && <Pill color="var(--high)" bg="var(--high-tint)" border="var(--high-glow)" size="sm">✓ 已接受</Pill>}
      </div>

      <h3 style={{ fontSize: 18, fontWeight: 700, lineHeight: 1.35, marginBottom: 6, color: 'var(--ink-0)' }}>{title}</h3>
      <div style={{ fontSize: 12.5, color: 'var(--ink-1)', marginBottom: 12, lineHeight: 1.5 }}>{subtitle}</div>

      <div style={{
        padding: '10px 12px', background: 'var(--bg-2)', borderRadius: 7,
        fontSize: 12, color: 'var(--ink-2)', lineHeight: 1.55,
        marginBottom: 12, display: 'flex', gap: 9,
      }}>
        <Icon name="sparkle" size={12} color={tn.c} style={{ flexShrink: 0, marginTop: 2 }} />
        <span style={{ flex: 1 }}>{reason}</span>
      </div>

      {evidence && evidence.length > 0 && (
        <div style={{ display: 'flex', gap: 5, marginBottom: 12, flexWrap: 'wrap', alignItems: 'center' }}>
          <span style={{ fontSize: 10.5, color: 'var(--ink-3)', fontFamily: 'var(--mono)' }}>實證：</span>
          {evidence.slice(0, 4).map(e => <Pill key={e} color={tn.c} bg={tn.bg} size="sm">{e}</Pill>)}
        </div>
      )}

      {extra}

      {!accepted && (
        <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
          <button onClick={onPrimary} className="lift" style={{
            padding: '9px 18px', background: tn.c, color: '#fff',
            borderRadius: 7, fontSize: 12.5, fontWeight: 600,
            display: 'inline-flex', alignItems: 'center', gap: 7,
          }}>
            <Icon name="check" size={13} /> {primaryLabel}
          </button>
          {onSkip && (
            <button onClick={onSkip} style={{
              padding: '9px 16px', background: 'var(--bg-3)', color: 'var(--ink-2)',
              borderRadius: 7, fontSize: 12.5, border: '1px solid var(--line)',
            }}>跳過</button>
          )}
          <button onClick={onDetail} style={{
            padding: '9px 16px', background: 'transparent', color: 'var(--ink-2)',
            borderRadius: 7, fontSize: 12.5,
            display: 'inline-flex', alignItems: 'center', gap: 5,
          }}>
            細節 <Icon name="arrow_right" size={11} />
          </button>
        </div>
      )}
    </div>
  );
}

/* ===== Pulse Row ===== */
function PulseRow({ items, onSelect }) {
  const recent = items
    .filter(i => i.status === '已上線' && i.b && i.publish)
    .sort((a, b) => (b.publish || '').localeCompare(a.publish || ''))
    .slice(0, 10);

  return (
    <div style={{ display: 'flex', gap: 6, overflowX: 'auto', paddingBottom: 4 }}>
      {recent.map(it => {
        const c = it.b.p === 'high' ? 'var(--high)' : it.b.p === 'low' ? 'var(--low)' : 'var(--normal)';
        return (
          <button key={it.id} onClick={() => onSelect(it.id)}
            data-tip={`${it.title || it.topic} · ${fmtNum(it.b.v)} 觀看`}
            style={{
              width: 76, padding: 10, background: 'var(--bg-1)',
              border: '1px solid var(--line)', borderRadius: 8,
              display: 'flex', flexDirection: 'column', gap: 5, flexShrink: 0,
              transition: 'transform 0.12s, border-color 0.12s',
            }}
            onMouseEnter={e => { e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.borderColor = c; }}
            onMouseLeave={e => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.borderColor = 'var(--line)'; }}>
            <span className="mono" style={{ fontSize: 9, color: 'var(--ink-3)' }}>{it.vid}</span>
            <div style={{ height: 38, display: 'flex', alignItems: 'flex-end', gap: 2 }}>
              <div style={{ flex: 1, height: `${it.b.r}%`, background: c, borderRadius: 1, opacity: 0.55 }} />
              <div style={{ flex: 1, height: `${it.b.c}%`, background: c, borderRadius: 1 }} />
            </div>
            <span className="mono" style={{ fontSize: 10, color: c, fontWeight: 600 }}>{fmtNum(it.b.v)}</span>
          </button>
        );
      })}
    </div>
  );
}

/* ===== 決策歷史 ===== */
function DecisionLog({ decisions, items, onSelect }) {
  const today = new Date().toDateString();
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
      {decisions.map((d, i) => {
        const item = items.find(x => x.id === d.id);
        const isToday = new Date(d.time).toDateString() === today;
        const c = d.action === 'accept' ? 'var(--high)' : 'var(--ink-3)';
        return (
          <button key={i} onClick={() => item && onSelect(d.id)} style={{
            padding: '8px 12px', background: 'var(--bg-1)',
            border: '1px solid var(--line)', borderRadius: 6,
            display: 'flex', alignItems: 'center', gap: 10,
            fontSize: 12, color: 'var(--ink-1)', textAlign: 'left',
          }}>
            <Dot color={c} size={5} />
            <span className="mono" style={{ color: 'var(--ink-3)', fontSize: 10, width: 70, flexShrink: 0 }}>
              {isToday ? new Date(d.time).toLocaleTimeString('zh-TW', { hour: '2-digit', minute: '2-digit' }) : new Date(d.time).toLocaleDateString('zh-TW', { month: 'numeric', day: 'numeric' })}
            </span>
            <span style={{ color: c, width: 50, fontSize: 11.5, fontWeight: 500 }}>
              {d.action === 'accept' ? '接受' : '跳過'}
            </span>
            <span style={{ color: 'var(--ink-2)' }}>
              {d.kind === 'shoot' ? '開拍' : d.kind === 'backfill' ? '回填' : '推進'}
            </span>
            <span className="mono" style={{ color: 'var(--kai-bright)', marginLeft: 'auto' }}>{d.id}</span>
            {item && (
              <span style={{ fontSize: 11.5, color: 'var(--ink-2)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 260 }}>
                {item.title || item.topic}
              </span>
            )}
          </button>
        );
      })}
    </div>
  );
}

/* ========== 工具 ========== */
function buildContext(items, todos) {
  const live = items.filter(i => i.status === '已上線' && i.b);
  const high = live.filter(i => i.b.p === 'high');
  const ready = items.filter(i => i.status === '待拍').length;
  const stuck = items.filter(isStuck).length;
  const maxStuck = Math.max(0, ...items.filter(isStuck).map(i => i.age || 0));
  const inboxCount = items.filter(i => i.status === 'inbox').length;
  const recent = [...live].sort((a, b) => (b.publish || '').localeCompare(a.publish || ''))[0];
  const winRate = live.length ? Math.round((high.length / live.length) * 100) : 0;
  return { live: live.length, high: high.length, ready, stuck, maxStuck, inboxCount, recent, winRate };
}

function recommendNext(items, skipped, accepted) {
  const candidates = items.filter(i =>
    (i.status === 'inbox' || i.status === 'selected') &&
    !skipped.has(i.id) && !accepted.has(i.id)
  );
  if (candidates.length === 0) return null;

  const opening = [...PATTERNS.proven_openings].sort((a, b) => b.win_rate - a.win_rate)[0];
  const cta = [...PATTERNS.proven_ctas].sort((a, b) => b.win_rate - a.win_rate)[0];

  const selectedFirst = candidates.filter(i => i.status === 'selected');
  const pool = selectedFirst.length > 0 ? selectedFirst : candidates;
  const idea = pool.sort((a, b) => (b.age || 0) - (a.age || 0))[0];

  const reason = `${opening.name} + ${cta.name} 是目前勝率最高的配對。${idea.tags?.length ? `這個題目的標籤（${idea.tags.slice(0, 2).join('、')}）` : '這個題目'}適合這個公式 — 直接套用即可。`;

  const evidence = [...new Set([...opening.vid_evidence.slice(0, 2), ...cta.vid_evidence.slice(0, 2)])];

  return { idea, opening, cta, reason, evidence };
}

function getDays(dateStr) {
  if (!dateStr) return 0;
  return Math.round((Date.now() - new Date(dateStr).getTime()) / 86400000);
}

Object.assign(window, { CommandRoom });
