// agent-crew.jsx — §04e Agent Crew (sprint timeline + multi-attempt cards)
//
// Real surfaces: src/renderer/windows/main/components/agent/{HarnessTimelineView,
// SprintCard, SprintAttemptCard, AgentCrewPanel}. The Crew system runs an
// agent across phases (planning → contracting → generating → evaluating) and
// can spawn multiple attempts per sprint with grades.

// ── Mission timeline (top-level: which phase the crew is in) ──
function CrewTimeline({ dark, currentPhase = 'generating' }) {
  const t = dark ? G.d : G.l;
  const phases = [
    { id: 'planning',   label: 'Planning',   icon: 'sparkle', desc: 'Decompose the goal into sprints' },
    { id: 'contracting', label: 'Contracting', icon: 'file', desc: 'Spec each sprint with acceptance criteria' },
    { id: 'generating',  label: 'Building',   icon: 'edit',  desc: 'Run sprints, iterate on attempts' },
    { id: 'evaluating',  label: 'Evaluating', icon: 'check', desc: 'Score against criteria, decide retry' },
    { id: 'completed',   label: 'Done',       icon: 'check', desc: 'Mission ready' },
  ];
  const idx = phases.findIndex(p => p.id === currentPhase);
  return (
    <ChatLayout dark={dark} title="Build a CSV importer crew">
      <UserMsg dark={dark}>Build a robust CSV importer with retries, validation, and progress UI.</UserMsg>

      {/* Mission card */}
      <div style={{
        maxWidth: 720, padding: 16,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
          <div style={{
            width: 28, height: 28, borderRadius: 8,
            background: '#5865F2', color: '#fff',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}><Icon name="bolt" size={14} color="#fff" /></div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 600 }}>Mission · CSV importer</div>
            <div style={{ fontSize: 11, color: t.fg3, marginTop: 2 }}>3 sprints · started 12 min ago</div>
          </div>
          <Tag>{phases[idx]?.label}</Tag>
        </div>

        {/* Phase timeline */}
        <div style={{ position: 'relative' }}>
          {phases.map((p, i) => {
            const done = i < idx, active = i === idx, pending = i > idx;
            return (
              <div key={p.id} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, paddingBottom: i === phases.length - 1 ? 0 : 14, position: 'relative' }}>
                {/* Connector line */}
                {i !== phases.length - 1 && (
                  <div style={{
                    position: 'absolute', left: 13, top: 26, bottom: -2, width: 1,
                    background: done ? t.fg : t.border,
                  }} />
                )}
                <div style={{
                  width: 28, height: 28, borderRadius: 14,
                  background: done ? t.fg : (active ? t.surface2 : 'transparent'),
                  border: `1.5px solid ${done ? t.fg : (active ? t.fg : t.border)}`,
                  color: done ? t.bg : (active ? t.fg : t.fg3),
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  flexShrink: 0, position: 'relative', zIndex: 1,
                }}>
                  {done ? <Icon name="check" size={12} /> :
                    active ? <span style={{ width: 10, height: 10, border: `1.5px solid ${t.fg}`, borderTopColor: 'transparent', borderRadius: 5, animation: 'gh-spin .8s linear infinite' }} /> :
                    <Icon name={p.icon} size={11} />}
                </div>
                <div style={{ flex: 1, paddingTop: 4 }}>
                  <div style={{ fontSize: 13, fontWeight: active ? 600 : 500, color: pending ? t.fg3 : t.fg }}>{p.label}</div>
                  <div style={{ fontSize: 11, color: t.fg3, marginTop: 1 }}>{p.desc}</div>
                </div>
                {done && <span style={{ fontSize: 10, fontFamily: G.mono, color: t.fg3, marginTop: 6 }}>{['1m 12s', '2m 34s', '8m 04s', '1m 18s', '—'][i]}</span>}
              </div>
            );
          })}
        </div>
      </div>
    </ChatLayout>
  );
}


// ── Sprint card with multi-attempt history ──
function CrewSprintCard({ dark, variant = 'pass' }) {
  const t = dark ? G.d : G.l;
  const isFail = variant === 'fail';
  const isRunning = variant === 'running';

  const sprintStatusBadge = isRunning ? { tone: '#febc2e', label: 'Running', icon: 'refresh' } :
    isFail ? { tone: '#ff5f57', label: 'Failed (max attempts)', icon: 'close' } :
    { tone: '#28c840', label: 'Passed · grade A', icon: 'check' };

  const attempts = isRunning ? [
    { n: 1, status: 'fail', grade: 'C-', summary: 'Did not handle empty rows; eval found 3 broken cases.', time: '2m 14s' },
    { n: 2, status: 'fail', grade: 'B-', summary: 'Empty rows OK but Unicode header detection still wrong.', time: '1m 48s' },
    { n: 3, status: 'running', grade: '—', summary: 'Streaming a fix for header detection…', time: '0:43' },
  ] : isFail ? [
    { n: 1, status: 'fail', grade: 'D', summary: 'Did not handle quoted commas.', time: '1m 02s' },
    { n: 2, status: 'fail', grade: 'D+', summary: 'Quoted commas OK but escape sequences broken.', time: '1m 38s' },
    { n: 3, status: 'fail', grade: 'C-', summary: 'Escapes OK but eval found memory leak under 1M rows.', time: '3m 12s' },
    { n: 4, status: 'fail', grade: 'C', summary: 'Memory OK but BOM detection regressed.', time: '2m 04s' },
  ] : [
    { n: 1, status: 'fail', grade: 'C', summary: 'Eval found 2 broken cases for quoted strings.', time: '1m 22s' },
    { n: 2, status: 'pass', grade: 'A', summary: 'All 12 acceptance criteria met. Diff: 4 files, +127/-14.', time: '2m 08s' },
  ];

  return (
    <ChatLayout dark={dark} title="Build a CSV importer crew">
      <div style={{
        maxWidth: 720, padding: 0,
        background: t.surface, border: `1px solid ${t.border}`, borderRadius: 14, overflow: 'hidden',
      }}>
        {/* Header */}
        <div style={{
          padding: '12px 16px', background: t.surface2,
          borderBottom: `0.5px solid ${t.border2}`,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{
            width: 28, height: 28, borderRadius: 8,
            background: t.surface, border: `1px solid ${t.border}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: sprintStatusBadge.tone,
          }}><Icon name={sprintStatusBadge.icon} size={13} color={sprintStatusBadge.tone} /></div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, fontWeight: 600 }}>Sprint 2 · Parser core</div>
            <div style={{ fontSize: 11, color: t.fg3, fontFamily: G.mono, marginTop: 1 }}>
              {attempts.length} attempt{attempts.length === 1 ? '' : 's'} · {attempts.reduce((acc) => acc, 0)} eval rounds
            </div>
          </div>
          <Tag style={{ background: sprintStatusBadge.tone, color: '#fff', border: 'none' }}>{sprintStatusBadge.label}</Tag>
        </div>

        {/* Attempts */}
        <div>
          {attempts.map((a, i) => (
            <div key={i} style={{
              padding: '12px 16px',
              borderBottom: i === attempts.length - 1 ? 'none' : `0.5px solid ${t.border2}`,
              opacity: a.status === 'fail' ? 0.85 : 1,
              display: 'flex', alignItems: 'flex-start', gap: 12,
            }}>
              <div style={{
                width: 22, height: 22, borderRadius: 11,
                background: a.status === 'pass' ? t.fg : (a.status === 'running' ? t.surface2 : 'transparent'),
                color: a.status === 'pass' ? t.bg : (a.status === 'running' ? t.fg : t.fg2),
                border: `1px solid ${a.status === 'pass' ? t.fg : (a.status === 'fail' ? '#ff5f57' : t.border)}`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontFamily: G.mono, fontSize: 10, fontWeight: 600,
                flexShrink: 0, marginTop: 1,
              }}>
                {a.status === 'running' ? (
                  <span style={{ width: 9, height: 9, border: `1.5px solid ${t.fg2}`, borderTopColor: 'transparent', borderRadius: 5, animation: 'gh-spin .8s linear infinite' }} />
                ) : a.n}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                  <span style={{ fontSize: 12, fontWeight: 600 }}>Attempt {a.n}</span>
                  <Tag style={{
                    height: 18, fontSize: 10, fontFamily: G.mono,
                    background: a.status === 'pass' ? '#28c840' : (a.status === 'fail' ? 'rgba(255,95,87,0.15)' : t.surface2),
                    color: a.status === 'pass' ? '#fff' : (a.status === 'fail' ? '#ff5f57' : t.fg2),
                    border: 'none',
                  }}>{a.grade}</Tag>
                  <span style={{ flex: 1 }} />
                  <span style={{ fontSize: 10, fontFamily: G.mono, color: t.fg3 }}>{a.time}</span>
                </div>
                <div style={{ fontSize: 12, color: t.fg2, lineHeight: 1.5 }}>{a.summary}</div>
                {a.status === 'pass' && (
                  <div style={{ marginTop: 8, display: 'flex', gap: 6 }}>
                    <Button variant="primary" size="sm">Apply diff</Button>
                    <Button variant="ghost" size="sm">View attempt</Button>
                  </div>
                )}
                {a.status === 'fail' && i === attempts.length - 1 && isFail && (
                  <div style={{ marginTop: 8, display: 'flex', gap: 6 }}>
                    <Button variant="primary" size="sm">Retry with hint</Button>
                    <Button variant="secondary" size="sm">Lower bar</Button>
                    <Button variant="ghost" size="sm">Abandon sprint</Button>
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      </div>
    </ChatLayout>
  );
}


// ── Crew panel (full-pane view: timeline + active sprint detail) ──
function CrewPanel({ dark }) {
  const t = dark ? G.d : G.l;
  return (
    <ChatLayout dark={dark} title="Build a CSV importer crew" rightPanel={
      <div style={{ height: '100%', overflow: 'auto', padding: 16, fontSize: 12, color: t.fg2 }}>
        <div style={{ fontSize: 11, fontFamily: G.mono, color: t.fg3, letterSpacing: 1, textTransform: 'uppercase', marginBottom: 8 }}>Acceptance criteria</div>
        {[
          'Parses RFC 4180 quoted fields',
          'Handles BOM in UTF-8 input',
          'Streams files larger than memory',
          'Detects header row automatically',
          'Reports row + column on parse error',
        ].map((c, i) => (
          <div key={i} style={{ padding: '6px 0', display: 'flex', alignItems: 'center', gap: 8, borderBottom: `0.5px solid ${t.border2}` }}>
            <Icon name="check" size={11} color={i < 3 ? '#28c840' : t.fg4} />
            <span style={{ fontSize: 12, color: i < 3 ? t.fg : t.fg3, textDecoration: i < 3 ? 'line-through' : 'none' }}>{c}</span>
          </div>
        ))}

        <div style={{ fontSize: 11, fontFamily: G.mono, color: t.fg3, letterSpacing: 1, textTransform: 'uppercase', marginTop: 18, marginBottom: 8 }}>Live diff</div>
        <pre style={{
          margin: 0, padding: 10,
          background: t.surface2, border: `1px solid ${t.border2}`, borderRadius: 8,
          fontFamily: G.mono, fontSize: 11, lineHeight: 1.55,
          maxHeight: 220, overflow: 'auto',
        }}>{`+ src/csv/parser.ts            +84
+ src/csv/streaming.ts         +52
+ src/csv/parser.test.ts       +38
~ src/csv/index.ts              ~7`}</pre>
      </div>
    }>
      <CrewTimelineMini dark={dark} />
    </ChatLayout>
  );
}

function CrewTimelineMini({ dark }) {
  const t = dark ? G.d : G.l;
  const phases = ['Planning', 'Contracting', 'Building', 'Evaluating', 'Done'];
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
      {phases.map((p, i) => (
        <React.Fragment key={p}>
          <div style={{
            padding: '5px 10px', borderRadius: 999,
            background: i < 2 ? t.fg : (i === 2 ? t.surface2 : 'transparent'),
            color: i < 2 ? t.bg : (i === 2 ? t.fg : t.fg3),
            border: `1px solid ${i <= 2 ? t.fg : t.border}`,
            fontSize: 11, fontFamily: G.mono, letterSpacing: 0.4,
            textTransform: 'uppercase', whiteSpace: 'nowrap',
          }}>{p}</div>
          {i < phases.length - 1 && <span style={{ width: 14, height: 1, background: t.border }} />}
        </React.Fragment>
      ))}
    </div>
  );
}


Object.assign(window, { CrewTimeline, CrewSprintCard, CrewPanel });
