// Shared lo-fi sketch components for the Pulse wireframes.
// Exports to window: makeSessions, Line, StatusDot, StatusWord, ProgressBar,
// AgentAvatar, Annot, SessionCardMini, SessionRow, SessionDetailCard

const SESSION_POOL = [
  { id: 's1', repo: 'pulse-api',  title: 'Fix auth token refresh',   status: 'needs',   runtime: '12:40', pct: 80,  log: 'awaiting approval: run db migration?', diff: '+124 −30' },
  { id: 's2', repo: 'webapp',     title: 'Dark mode pass',           status: 'running', runtime: '04:12', pct: 35,  log: 'editing theme.css…',                   diff: '+48 −9'  },
  { id: 's3', repo: 'cli',        title: 'Add --watch flag',         status: 'done',    runtime: '22:05', pct: 100, log: 'all 48 tests pass',                    diff: '+210 −12' },
  { id: 's4', repo: 'infra',      title: 'Split terraform modules',  status: 'running', runtime: '08:51', pct: 60,  log: 'refactoring vpc module…',              diff: '+88 −140' },
  { id: 's5', repo: 'mobile',     title: 'Fix crash on resume',      status: 'needs',   runtime: '17:09', pct: 90,  log: 'needs decision: API fallback',         diff: '+36 −8'  },
  { id: 's6', repo: 'payments',   title: 'Stripe webhook retries',   status: 'running', runtime: '06:27', pct: 45,  log: 'writing retry queue…',                 diff: '+72 −15' },
  { id: 's7', repo: 'search',     title: 'Index rebuild script',     status: 'done',    runtime: '31:48', pct: 100, log: 'rebuilt 1.2M docs',                    diff: '+154 −61' },
  { id: 's8', repo: 'docs',       title: 'Rewrite quickstart',       status: 'running', runtime: '01:33', pct: 15,  log: 'drafting install section…',            diff: '+22 −4'  },
  { id: 's9', repo: 'design-sys', title: 'Token export',             status: 'done',    runtime: '09:14', pct: 100, log: 'tokens.json exported',                 diff: '+67 −3'  },
  { id: 's10',repo: 'ml-svc',     title: 'Batch inference queue',    status: 'running', runtime: '02:58', pct: 25,  log: 'spawning workers…',                    diff: '+41 −0'  },
];

function makeSessions(n) {
  const count = Math.max(2, Math.min(10, Math.round(n)));
  return SESSION_POOL.slice(0, count);
}

// ---- a straight line drawn as a rotated div (no SVG) ----
function Line({ x1, y1, x2, y2, color = '#b9b2a6', dashed = true, width = 2 }) {
  const dx = x2 - x1, dy = y2 - y1;
  const len = Math.sqrt(dx * dx + dy * dy);
  const ang = Math.atan2(dy, dx) * 180 / Math.PI;
  const style = {
    position: 'absolute', left: x1, top: y1, width: len, height: 0,
    borderTop: `${width}px ${dashed ? 'dashed' : 'solid'} ${color}`,
    transform: `rotate(${ang}deg)`, transformOrigin: '0 0', pointerEvents: 'none',
  };
  return <div style={style}></div>;
}

function StatusDot({ status, accent, size = 13 }) {
  const base = {
    width: size, height: size, borderRadius: '50%', flex: 'none',
    boxSizing: 'border-box',
  };
  if (status === 'needs') return <span style={{ ...base, background: accent, border: `2px solid ${accent}` }}></span>;
  if (status === 'done') return <span style={{ ...base, background: '#2b2a28', border: '2px solid #2b2a28' }}></span>;
  return <span style={{ ...base, background: '#fff', border: '2px dashed #2b2a28' }}></span>;
}

function StatusWord({ status, accent }) {
  if (status === 'needs') return <span style={{ color: accent, fontWeight: 700 }}>needs you</span>;
  if (status === 'done') return <span>done ✓</span>;
  return <span style={{ color: '#7a7468' }}>running…</span>;
}

function ProgressBar({ pct, accent, status, width = '100%' }) {
  const fill = status === 'needs' ? accent : '#2b2a28';
  return (
    <div className="wf-box r2" style={{ width, height: 12, padding: 2, background: '#fff' }}>
      <div style={{ width: pct + '%', height: '100%', background: fill, borderRadius: 6, opacity: status === 'done' ? 1 : 0.85 }}></div>
    </div>
  );
}

// ---- agent avatar, 3 sketch variants ----
function AgentAvatar({ variant = 'Bot face', size = 120, accent = '#2b2a28', talking = true }) {
  const wrap = { position: 'relative', width: size, height: size, display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 'none' };
  const ring = talking ? (
    <div className="wf-pulse" style={{
      position: 'absolute', inset: -size * 0.14, borderRadius: '50%',
      border: `2px dashed ${accent}`, pointerEvents: 'none',
    }}></div>
  ) : null;

  if (variant === 'Ring') {
    return (
      <div style={wrap}>
        {ring}
        <div style={{ width: size * 0.78, height: size * 0.78, borderRadius: '50%', border: '3px solid #2b2a28', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ width: size * 0.34, height: size * 0.34, borderRadius: '50%', background: '#2b2a28' }}></div>
        </div>
      </div>
    );
  }
  if (variant === 'Waveform') {
    const bars = [0.35, 0.7, 1, 0.55, 0.8, 0.4];
    return (
      <div style={wrap}>
        {ring}
        <div style={{ width: size * 0.82, height: size * 0.82, borderRadius: '50%', border: '3px solid #2b2a28', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: size * 0.045 }}>
          {bars.map((h, i) => (
            <div key={i} style={{ width: size * 0.05, height: size * 0.42 * h, background: '#2b2a28', borderRadius: 4 }}></div>
          ))}
        </div>
      </div>
    );
  }
  // Bot face (default)
  return (
    <div style={wrap}>
      {ring}
      <div className="wf-box r1" style={{ width: size * 0.74, height: size * 0.74, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: size * 0.16, background: '#fff' }}>
        <div style={{ width: size * 0.085, height: size * 0.085, borderRadius: '50%', background: '#2b2a28' }}></div>
        <div style={{ width: size * 0.085, height: size * 0.085, borderRadius: '50%', background: '#2b2a28' }}></div>
      </div>
    </div>
  );
}

// ---- handwritten annotation ----
function Annot({ x, y, w = 220, color = '#8a93a6', align = 'left', children }) {
  return (
    <div className="wf-annot" style={{ position: 'absolute', left: x, top: y, width: w, color, textAlign: align, pointerEvents: 'none' }}>
      {children}
    </div>
  );
}

// ---- compact card for the orbit ring ----
function SessionCardMini({ s, accent }) {
  const needs = s.status === 'needs';
  return (
    <div className="wf-box r2" style={{
      width: 208, padding: '10px 12px', background: '#fff',
      borderColor: needs ? accent : '#2b2a28', borderWidth: needs ? 3 : 2,
      display: 'flex', flexDirection: 'column', gap: 6, boxSizing: 'border-box',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <StatusDot status={s.status} accent={accent} size={12} />
        <span style={{ fontWeight: 700, fontSize: 17, whiteSpace: 'nowrap' }}>{s.repo}</span>
        <span style={{ marginLeft: 'auto', fontSize: 14, color: '#7a7468', whiteSpace: 'nowrap' }}>{s.runtime}</span>
      </div>
      <div style={{ fontSize: 15, lineHeight: 1.15 }}>{s.title}</div>
      <ProgressBar pct={s.pct} accent={accent} status={s.status} />
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
        <StatusWord status={s.status} accent={accent} />
        <span className="wf-mono" style={{ marginLeft: 'auto', color: '#7a7468' }}>{s.diff}</span>
      </div>
    </div>
  );
}

// ---- full-width row for the split layout ----
function SessionRow({ s, accent }) {
  const needs = s.status === 'needs';
  return (
    <div className="wf-box r3" style={{
      display: 'flex', alignItems: 'center', gap: 16, padding: '12px 16px', background: '#fff',
      borderColor: needs ? accent : '#2b2a28', borderWidth: needs ? 3 : 2, boxSizing: 'border-box',
    }}>
      <StatusDot status={s.status} accent={accent} size={16} />
      <div style={{ width: 230, flex: 'none' }}>
        <div style={{ fontWeight: 700, fontSize: 18 }}>{s.repo}</div>
        <div style={{ fontSize: 15, color: '#55504a' }}>{s.title}</div>
      </div>
      <div style={{ width: 170, flex: 'none' }}>
        <ProgressBar pct={s.pct} accent={accent} status={s.status} />
        <div style={{ fontSize: 13, color: '#7a7468', marginTop: 3 }}>{s.pct}% · {s.runtime}</div>
      </div>
      <div className="wf-mono" style={{ flex: 1, fontSize: 13, color: '#55504a', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}>
        » {s.log}
      </div>
      <div className="wf-mono" style={{ flex: 'none', fontSize: 13, color: '#7a7468' }}>{s.diff}</div>
      {needs ? (
        <button className="wf-box r1 wf-btn" style={{ borderColor: accent, color: accent }}>Review →</button>
      ) : (
        <span style={{ width: 84, flex: 'none', fontSize: 14, textAlign: 'center' }}><StatusWord status={s.status} accent={accent} /></span>
      )}
    </div>
  );
}

// ---- detail popover for a focused constellation star ----
function SessionDetailCard({ s, accent }) {
  return (
    <div className="wf-box r1" style={{ width: 270, padding: '12px 14px', background: '#fff', borderColor: accent, borderWidth: 3, display: 'flex', flexDirection: 'column', gap: 7, boxSizing: 'border-box' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <StatusDot status={s.status} accent={accent} />
        <span style={{ fontWeight: 700, fontSize: 18, whiteSpace: 'nowrap' }}>{s.repo}</span>
        <span style={{ marginLeft: 'auto', fontSize: 14, color: '#7a7468', whiteSpace: 'nowrap' }}>{s.runtime}</span>
      </div>
      <div style={{ fontSize: 16 }}>{s.title}</div>
      <ProgressBar pct={s.pct} accent={accent} status={s.status} />
      <div className="wf-mono" style={{ fontSize: 13, color: '#55504a' }}>» {s.log}</div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
        <button className="wf-box r2 wf-btn" style={{ borderColor: accent, color: accent }}>Review →</button>
        <span className="wf-mono" style={{ marginLeft: 'auto', fontSize: 13, color: '#7a7468' }}>{s.diff}</span>
      </div>
    </div>
  );
}

Object.assign(window, {
  makeSessions, Line, StatusDot, StatusWord, ProgressBar,
  AgentAvatar, Annot, SessionCardMini, SessionRow, SessionDetailCard,
});
