// WeWire team dashboard — Profile drawer + Compare view.

function Ring({ value, size = 92 }) {
  const r = (size - 12) / 2, c = 2 * Math.PI * r;
  const col = value == null ? T.subtle : value >= 85 ? T.green : value >= 70 ? T.amber : T.orange;
  return (
    <div style={{ position: 'relative', width: size, height: size, flex: 'none' }}>
      <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={T.sand} strokeWidth={9} />
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={col} strokeWidth={9} strokeLinecap="round"
          strokeDasharray={c} strokeDashoffset={c * (1 - (value || 0) / 100)} style={{ transition: 'stroke-dashoffset 600ms' }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center' }}>
        <div style={{ textAlign: 'center' }}>
          <div style={{ fontFamily: DISP, fontWeight: 600, fontSize: 26, lineHeight: 1 }}>{value ?? '—'}</div>
          <div style={{ fontSize: 9.5, color: T.muted, letterSpacing: '0.1em', textTransform: 'uppercase' }}>Overall</div>
        </div>
      </div>
    </div>
  );
}

function Stars({ value, onChange }) {
  return (
    <div style={{ display: 'flex', gap: 4 }}>
      {[1, 2, 3, 4, 5].map(n => (
        <button key={n} onClick={() => onChange(n)} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2 }}>
          <Icon name="star" size={26} color={n <= value ? T.amber : T.line}
            style={{ fill: n <= value ? T.amber : 'none' }} sw={1.8} />
        </button>
      ))}
    </div>
  );
}

function EssayReview({ title, hint, essayText, score, review, reviewedBy, reviewedAt, onSave, disabled }) {
  const [localScore, setLocalScore] = React.useState(score ?? '');
  const [localReview, setLocalReview] = React.useState(review || '');
  const [saving, setSaving] = React.useState(false);
  const [msg, setMsg] = React.useState('');

  React.useEffect(() => {
    setLocalScore(score ?? '');
    setLocalReview(review || '');
  }, [score, review]);

  const save = async () => {
    const n = parseInt(localScore, 10);
    if (Number.isNaN(n) || n < 0 || n > 10) {
      setMsg('Score must be between 0 and 10.');
      return;
    }
    if (!localReview.trim()) {
      setMsg('Add a short review explaining your score.');
      return;
    }
    setMsg('');
    setSaving(true);
    try {
      await onSave({ score: n, review: localReview.trim() });
      setMsg('Review saved.');
      setTimeout(() => setMsg(''), 2500);
    } catch (err) {
      setMsg(err.message || 'Could not save review.');
    } finally {
      setSaving(false);
    }
  };

  return (
    <Card pad={18} style={{ marginBottom: 16 }}>
      <Eyebrow style={{ marginBottom: 10 }}>{title}</Eyebrow>
      {hint && <div style={{ fontSize: 13, color: T.muted, marginBottom: 12, lineHeight: 1.5 }}>{hint}</div>}
      {essayText && (
        <div style={{ marginBottom: 14, padding: 14, borderRadius: 12, background: T.panel, maxHeight: 220, overflowY: 'auto',
          fontSize: 14, lineHeight: 1.6, color: T.ink, whiteSpace: 'pre-wrap' }}>{essayText}</div>
      )}
      <div style={{ display: 'grid', gridTemplateColumns: '120px 1fr', gap: 14, marginBottom: 14 }}>
        <label>
          <div style={{ fontSize: 13, fontWeight: 600, color: T.muted, marginBottom: 7 }}>Score / 10</div>
          <input type="number" min={0} max={10} value={localScore} disabled={disabled}
            onChange={(e) => setLocalScore(e.target.value)}
            style={{ width: '100%', height: 44, borderRadius: 12, border: `1px solid ${T.lineStrong}`, padding: '0 12px',
              fontFamily: FONT, fontSize: 16, fontWeight: 700, boxSizing: 'border-box' }} />
        </label>
        <div>
          {score != null && <ScoreBar value={score} max={10} w="full" label="Current" />}
        </div>
      </div>
      <label style={{ display: 'block', marginBottom: 12 }}>
        <div style={{ fontSize: 13, fontWeight: 600, color: T.muted, marginBottom: 7 }}>Review</div>
        <textarea value={localReview} disabled={disabled} onChange={(e) => setLocalReview(e.target.value)}
          placeholder="What worked well? What gave you pause? Would you shortlist based on this?"
          rows={4}
          style={{ width: '100%', borderRadius: 12, border: `1px solid ${T.lineStrong}`, padding: 14, fontFamily: FONT,
            fontSize: 14, lineHeight: 1.5, resize: 'vertical', boxSizing: 'border-box', background: T.white }} />
      </label>
      {reviewedBy && (
        <div style={{ fontSize: 12, color: T.subtle, marginBottom: 10 }}>
          Last reviewed by {reviewedBy}{reviewedAt ? ` · ${new Date(reviewedAt).toLocaleString('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' })}` : ''}
        </div>
      )}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <Btn variant="primary" icon="check" onClick={save} disabled={disabled || saving}>{saving ? 'Saving…' : 'Save review'}</Btn>
        {msg && <span style={{ fontSize: 13, color: msg.includes('saved') ? T.green : T.red }}>{msg}</span>}
      </div>
    </Card>
  );
}

function Profile({ cand, onClose, onStatus, onDelete, onUpdate, onStageReview, useLive }) {
  const { STAGES } = window.WWData;
  const ov = overall(cand.scores);
  const scored = STAGES.filter(s => s.kind !== 'form' && cand.scores[s.key] != null);
  const pending = STAGES.filter(s => s.kind !== 'form' && cand.scores[s.key] == null);
  const [docs, setDocs] = React.useState({ cvUrl: null, caseUrl: null });
  const m2Complete = (cand.stage || 0) >= 7;
  const awaitingManualReview = m2Complete && cand.status !== 'shortlist' && cand.status !== 'offer' && cand.status !== 'rejected';
  const writtenPayload = cand.stagePayload?.written;
  const casePayload = cand.stagePayload?.case;
  const interviewPayload = cand.stagePayload?.interview;
  const writtenEssays = window.WWFunnel?.writtenEssaysFromPayload(writtenPayload) || [];
  const hasWritten = writtenEssays.length > 0 || cand.stage >= 6;
  const hasCase = !!(casePayload || cand.casePath || cand.stage >= 7);
  const bookedSlot = interviewPayload?.slot;

  React.useEffect(() => {
    if (!useLive || !window.WWAdmin) return;
    WWAdmin.getDocumentUrls(cand).then(setDocs).catch(() => {});
  }, [cand.id, useLive]);

  const scoreBarFor = (stage) => {
    const max = ESSAY_STAGE_KEYS.has(stage.key) ? 10 : 100;
    return <ScoreBar key={stage.key} label={stage.name} value={cand.scores[stage.key]} max={max} w="full" />;
  };

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 100, display: 'flex', justifyContent: 'flex-end' }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(27,24,19,0.35)', backdropFilter: 'blur(2px)' }} />
      <div style={{ position: 'relative', width: 660, maxWidth: '94vw', height: '100%', background: T.cream,
        boxShadow: '-30px 0 80px rgba(27,24,19,0.25)', overflowY: 'auto', animation: 'slideIn 320ms cubic-bezier(.22,1,.36,1)' }}>
        {/* header */}
        <div style={{ background: T.ink, color: T.cream, padding: '24px 28px 26px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 22 }}>
            <Badge status={cand.status} />
            <button onClick={onClose} style={{ background: 'rgba(251,247,240,0.12)', border: 'none', borderRadius: 9,
              width: 34, height: 34, cursor: 'pointer', display: 'grid', placeItems: 'center', color: T.cream }}>
              <Icon name="x" size={18} /></button>
          </div>
          <div style={{ display: 'flex', gap: 18, alignItems: 'center' }}>
            <Avatar name={cand.name} size={64} />
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: DISP, fontWeight: 600, fontSize: 26, letterSpacing: '-0.02em' }}>{cand.name}</div>
              <div style={{ fontSize: 14, color: 'rgba(251,247,240,0.72)', marginTop: 3 }}>{cand.track} · {cand.uni}</div>
              <div style={{ fontSize: 12.5, color: 'rgba(251,247,240,0.5)', marginTop: 4 }}>{cand.id} · Applied {cand.applied}</div>
            </div>
            <Ring value={ov} />
          </div>
        </div>

        <div style={{ padding: '24px 28px 60px' }}>
          {awaitingManualReview && (
            <Card pad={16} style={{ marginBottom: 18, background: T.blueSoft, border: `1px solid ${T.blue}22` }}>
              <div style={{ fontSize: 14, color: T.blue, lineHeight: 1.55, fontWeight: 600 }}>
                Milestone 2 complete — awaiting manual review
              </div>
              <div style={{ fontSize: 13, color: T.muted, lineHeight: 1.5, marginTop: 6 }}>
                Use <b>Shortlist for interview</b> to unlock their final interview slot. Marking as advancing does not invite them — only shortlist does.
              </div>
            </Card>
          )}

          {/* actions */}
          <div style={{ display: 'flex', gap: 10, marginBottom: 26, flexWrap: 'wrap' }}>
            <Btn variant="dark" icon="arrow" onClick={() => onStatus(cand.id, 'advancing')}>Mark advancing</Btn>
            <Btn variant="primary" icon="star" onClick={() => onStatus(cand.id, 'shortlist')}>Shortlist for interview</Btn>
            {(cand.status === 'shortlist' || cand.status === 'offer') &&
              <Btn variant="green" icon="check" onClick={() => onStatus(cand.id, 'offer')}>Extend offer</Btn>}
            <div style={{ flex: 1 }} />
            <Btn variant="red" icon="x" onClick={() => onStatus(cand.id, 'rejected')}>Not advancing</Btn>
            <Btn variant="ghost" icon="x" onClick={() => onDelete(cand.id)}
              style={{ color: T.red, borderColor: `${T.red}33` }}>Remove</Btn>
          </div>

          {/* assessment results */}
          <Eyebrow style={{ marginBottom: 14 }}>Assessment results</Eyebrow>
          {(docs.cvUrl || docs.caseUrl) && (
            <div style={{ display: 'flex', gap: 10, marginBottom: 14, flexWrap: 'wrap' }}>
              {docs.cvUrl && <a href={docs.cvUrl} target="_blank" rel="noopener noreferrer"><Btn variant="ghost" icon="arrow">Download CV</Btn></a>}
              {docs.caseUrl && <a href={docs.caseUrl} target="_blank" rel="noopener noreferrer"><Btn variant="ghost" icon="arrow">Download case memo</Btn></a>}
            </div>
          )}
          <Card pad={20} style={{ marginBottom: 16 }}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              {scored.map(scoreBarFor)}
            </div>
            {pending.length > 0 && (
              <div style={{ marginTop: 16, paddingTop: 14, borderTop: `1px solid ${T.line}`, fontSize: 12.5, color: T.subtle }}>
                Not yet taken: {pending.map(s => s.name).join(' · ')}
              </div>
            )}
          </Card>

          {(hasWritten || hasCase) && (
            <>
              <Eyebrow style={{ marginBottom: 14 }}>Essay & case review</Eyebrow>
              {hasWritten && writtenEssays.map((essay) => (
                <EssayReview
                  key={essay.id}
                  title={essay.title || essay.id}
                  hint={essay.wordCount ? `${essay.wordCount} words submitted` : 'Applicant essay response'}
                  essayText={essay.text}
                  score={essay.score ?? null}
                  review={essay.review}
                  reviewedBy={essay.reviewedBy}
                  reviewedAt={essay.reviewedAt}
                  disabled={!onStageReview}
                  onSave={(patch) => onStageReview(cand.id, 'written', { ...patch, essayId: essay.id })}
                />
              ))}
              {hasCase && (
                <EssayReview
                  title="Take-home case"
                  hint="Score the submitted case memo (download above). Review should reference structure, insight, and practicality."
                  essayText={null}
                  score={cand.scores.case}
                  review={casePayload?.review}
                  reviewedBy={casePayload?.reviewedBy}
                  reviewedAt={casePayload?.reviewedAt}
                  disabled={!onStageReview}
                  onSave={(patch) => onStageReview(cand.id, 'case', patch)}
                />
              )}
            </>
          )}

          {bookedSlot && (
            <Card pad={18} style={{ marginBottom: 16, background: T.greenSoft, border: 'none' }}>
              <Eyebrow style={{ marginBottom: 8 }}>Interview booked</Eyebrow>
              <div style={{ fontSize: 15, fontWeight: 600, color: T.ink }}>
                {bookedSlot.day || bookedSlot.date} · {bookedSlot.time}
              </div>
              <div style={{ fontSize: 13, color: T.muted, marginTop: 6 }}>WeWire HQ · Accra</div>
            </Card>
          )}

          {/* manual rating */}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, marginBottom: 16 }}>
            <Card pad={18}>
              <Eyebrow style={{ marginBottom: 10 }}>Interview impression</Eyebrow>
              <Stars value={cand.rating || 0} onChange={(n) => onUpdate(cand.id, { rating: n })} />
              <div style={{ fontSize: 12.5, color: T.subtle, marginTop: 10 }}>Panel's gut feel after meeting in Accra.</div>
            </Card>
            <Card pad={18}>
              <Eyebrow style={{ marginBottom: 10 }}>Fit signal</Eyebrow>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
                <span style={{ fontFamily: DISP, fontWeight: 600, fontSize: 30 }}>{ov ?? '—'}</span>
                <span style={{ fontSize: 13, color: T.muted }}>/ 100 across {scored.length} stages</span>
              </div>
              <div style={{ fontSize: 12.5, color: T.subtle, marginTop: 10 }}>
                {ov >= 88 ? 'Exceptional — strong seat candidate.' : ov >= 78 ? 'Solid — worth a close look.' : 'Developing — weigh against the pool.'}
              </div>
            </Card>
          </div>

          {/* notes */}
          <Eyebrow style={{ marginBottom: 10 }}>Reviewer notes</Eyebrow>
          <textarea value={cand.notes || ''} onChange={(e) => onUpdate(cand.id, { notes: e.target.value })}
            placeholder="What stood out? Anything to probe at interview…" rows={4}
            style={{ width: '100%', borderRadius: 12, border: `1px solid ${T.lineStrong}`, padding: 14, fontFamily: FONT,
              fontSize: 14, lineHeight: 1.5, resize: 'none', outline: 'none', boxSizing: 'border-box', background: T.white, color: T.ink }}
            onFocus={(e) => e.target.style.borderColor = T.orange} onBlur={(e) => e.target.style.borderColor = T.lineStrong} />
        </div>
      </div>
    </div>
  );
}

// ── Compare ──────────────────────────────────────────────────
function Compare({ data, selected, toggleSelect, setSelected, setView, openProfile }) {
  const { STAGES } = window.WWData;
  const cands = data.filter(a => selected.includes(a.id));

  if (cands.length < 2) {
    const top = [...data].filter(a => a.status !== 'rejected').sort((a, b) => overall(b.scores) - overall(a.scores)).slice(0, 3);
    return (
      <div style={{ padding: '30px 36px' }}>
        <Eyebrow>Side by side</Eyebrow>
        <h1 style={{ fontFamily: DISP, fontWeight: 600, fontSize: 34, letterSpacing: '-0.02em', margin: '8px 0 0' }}>Compare</h1>
        <Card pad={40} style={{ marginTop: 24, textAlign: 'center' }}>
          <div style={{ width: 56, height: 56, borderRadius: 16, background: T.orangeSoft, color: T.orangeDeep,
            display: 'grid', placeItems: 'center', margin: '0 auto 16px' }}><Icon name="compare" size={26} /></div>
          <div style={{ fontFamily: DISP, fontWeight: 600, fontSize: 20 }}>Pick at least two candidates</div>
          <p style={{ color: T.muted, fontSize: 14.5, margin: '8px auto 22px', maxWidth: 380, lineHeight: 1.5 }}>
            Select candidates from the pipeline, or jump straight to comparing the current top of the pool.</p>
          <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
            <Btn variant="ghost" icon="list" onClick={() => setView('pipeline')}>Go to pipeline</Btn>
            <Btn variant="primary" icon="star" onClick={() => setSelected(top.map(a => a.id))}>Compare top 3</Btn>
          </div>
        </Card>
      </div>
    );
  }

  const dims = [{ key: '_overall', name: 'Overall', get: a => overall(a.scores) }]
    .concat(STAGES.filter(s => s.kind !== 'form').map(s => ({
      key: s.key,
      name: s.name,
      get: a => a.scores[s.key],
      max: ESSAY_STAGE_KEYS.has(s.key) ? 10 : 100,
    })));
  const winner = [...cands].sort((a, b) => overall(b.scores) - overall(a.scores))[0];

  return (
    <div style={{ padding: '30px 36px 48px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 22 }}>
        <div>
          <Eyebrow>Side by side</Eyebrow>
          <h1 style={{ fontFamily: DISP, fontWeight: 600, fontSize: 34, letterSpacing: '-0.02em', margin: '8px 0 0' }}>Compare</h1>
        </div>
        <Btn variant="ghost" icon="list" onClick={() => setView('pipeline')}>Change selection</Btn>
      </div>

      <Card pad={0} style={{ overflow: 'hidden' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead><tr>
            <th style={{ width: 150, padding: 18, textAlign: 'left' }}></th>
            {cands.map(a => (
              <th key={a.id} style={{ padding: '18px 16px', borderLeft: `1px solid ${T.line}`, verticalAlign: 'top' }}>
                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8, position: 'relative' }}>
                  <button onClick={() => toggleSelect(a.id)} style={{ position: 'absolute', top: -6, right: -4, background: T.sand,
                    border: 'none', borderRadius: 7, width: 24, height: 24, cursor: 'pointer', display: 'grid', placeItems: 'center', color: T.muted }}>
                    <Icon name="x" size={14} /></button>
                  <Avatar name={a.name} size={48} />
                  <div style={{ textAlign: 'center', cursor: 'pointer' }} onClick={() => openProfile(a.id)}>
                    <div style={{ fontFamily: DISP, fontWeight: 600, fontSize: 15 }}>{a.name}</div>
                    <div style={{ fontSize: 11.5, color: T.subtle, marginTop: 2 }}>{a.track}</div>
                  </div>
                  <Badge status={a.status} size="sm" />
                </div>
              </th>
            ))}
          </tr></thead>
          <tbody>
            {dims.map((d, ri) => {
              const vals = cands.map(d.get);
              const norm = (v) => {
                if (v == null) return 0;
                const maxScale = d.max || 100;
                return (v / maxScale) * 100;
              };
              const max = Math.max(...vals.map(norm));
              return (
                <tr key={d.key} style={{ borderTop: `1px solid ${T.line}`, background: d.key === '_overall' ? T.panel : 'transparent' }}>
                  <td style={{ padding: '14px 18px', fontSize: 13.5, fontWeight: d.key === '_overall' ? 700 : 600,
                    color: d.key === '_overall' ? T.ink : T.muted }}>{d.name}</td>
                  {cands.map((a, ci) => {
                    const v = vals[ci];
                    const best = v != null && norm(v) === max && max > 0;
                    const maxScale = d.max || 100;
                    const barPct = v == null ? 0 : Math.round((v / maxScale) * 100);
                    const display = v == null ? '—' : (maxScale === 10 ? `${v}/10` : v);
                    return (
                      <td key={a.id} style={{ padding: '12px 16px', borderLeft: `1px solid ${T.line}` }}>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                          <div style={{ flex: 1, height: 7, background: T.sand, borderRadius: 999, overflow: 'hidden' }}>
                            {v != null && <div style={{ width: `${barPct}%`, height: '100%', borderRadius: 999,
                              background: best ? T.orange : T.lineStrong }} />}
                          </div>
                          <span style={{ width: 36, textAlign: 'right', fontFamily: DISP, fontWeight: 600, fontSize: 14,
                            color: v == null ? T.subtle : best ? T.orangeDeep : T.ink }}>{display}</span>
                        </div>
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>
      </Card>

      <Card pad={18} style={{ marginTop: 16, display: 'flex', alignItems: 'center', gap: 14, background: T.ink, border: 'none', color: T.cream }}>
        <Icon name="star" size={20} color={T.amber} style={{ fill: T.amber }} />
        <div style={{ fontSize: 14.5 }}>On raw scores, <b>{winner.name}</b> leads this group at <b>{overall(winner.scores)}</b> overall — but the in-person interview is where the seat is won.</div>
      </Card>
    </div>
  );
}

Object.assign(window, { Profile, Compare, Ring, Stars, EssayReview });
