// ReadingDashboard — per-doc time-spent doughnuts inside the admin
// ForwardTimelineModal.
//
// Fetches /api/admin/invite-reading?invite_id=... on mount, renders a
// responsive grid of mini doughnuts. Each doughnut shows:
//   - outer ring fill   = max scroll % the recipient reached
//   - center label      = total time spent (e.g. "25s", "2min", "1.5h")
//   - download arrow    = true iff they ever clicked download
//   - doc title above   = truncated to one line
//
// Sorted by total_seconds desc so the most-engaged doc is first.
// Empty state when there are no doc.closed events yet (e.g. a freshly
// minted invite that hasn't been opened).

// ── Local copy of secondsToLabel ──────────────────────────────────
// api/_lib/time-format.js holds the canonical implementation. This
// duplicate exists because Babel-standalone has no module system —
// the JSX runtime can't require() server modules. Keep in lockstep.
function secondsToLabel(seconds) {
  if (seconds === null || seconds === undefined) return '—';
  const s = Number(seconds);
  if (!Number.isFinite(s) || s < 0) return '—';
  if (s < 60) return `${Math.round(s)}s`;
  if (s < 3600) return `${Math.round(s / 60)}min`;
  const halfHours = Math.round(s / 1800);
  const h = halfHours / 2;
  const formatted = (h % 1 === 0) ? String(h) : h.toFixed(1);
  return `${formatted}h`;
}

function Doughnut({ scrollPct, label, downloaded, muted }) {
  // SVG ring geometry — 80px box, 6px stroke, internal radius 32.
  const SIZE = 80, STROKE = 6, R = (SIZE / 2) - (STROKE / 2);
  const C = 2 * Math.PI * R;
  const fillPct = Math.max(0, Math.min(100, Number(scrollPct) || 0));
  const filled = (fillPct / 100) * C;
  const gap = C - filled;
  const ringColor = muted ? 'rgba(212,175,55,0.18)' : (fillPct >= 90 ? 'var(--success)' : 'var(--gold)');
  const textColor = muted ? 'var(--text-tertiary)' : 'var(--text)';

  return (
    <svg width={SIZE} height={SIZE} viewBox={`0 0 ${SIZE} ${SIZE}`} style={{ display: 'block' }}>
      {/* Track */}
      <circle cx={SIZE / 2} cy={SIZE / 2} r={R}
              fill="none" stroke="var(--border)" strokeWidth={STROKE} />
      {/* Fill — starts at 12 o'clock by rotating -90deg around the center */}
      {fillPct > 0 && (
        <circle cx={SIZE / 2} cy={SIZE / 2} r={R}
                fill="none" stroke={ringColor} strokeWidth={STROKE}
                strokeDasharray={`${filled} ${gap}`}
                strokeLinecap="round"
                transform={`rotate(-90 ${SIZE / 2} ${SIZE / 2})`} />
      )}
      <text x={SIZE / 2} y={SIZE / 2}
            textAnchor="middle" dominantBaseline="central"
            fontFamily="'JetBrains Mono', monospace"
            fontSize={fillPct >= 100 ? 13 : 12}
            fontWeight="500"
            fill={textColor}>
        {label}
      </text>
      {downloaded && (
        // Down-arrow glyph in the bottom-right of the doughnut — small,
        // not in the centre, doesn't compete with the time label.
        <text x={SIZE - 12} y={SIZE - 8}
              textAnchor="middle"
              fontFamily="'JetBrains Mono', monospace"
              fontSize="11"
              fontWeight="700"
              fill="var(--gold-dark)">
          ↓
        </text>
      )}
    </svg>
  );
}

function ReadingDashboard({ invite }) {
  const [reading, setReading] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      setLoading(true); setError(null);
      try {
        const r = await adminFetch(`/api/admin/invite-reading?invite_id=${encodeURIComponent(invite.id)}`);
        if (!r.ok) {
          if (!cancelled) setError(`HTTP ${r.status}`);
          return;
        }
        const data = await r.json();
        if (!cancelled) setReading(data.reading || []);
      } catch (e) {
        if (!cancelled) setError(e.message);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [invite.id]);

  if (loading) {
    return (
      <div style={{ padding: 12, color: 'var(--text-tertiary)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>
        LOADING READING…
      </div>
    );
  }
  if (error) {
    return (
      <div style={{ padding: 12, border: '1px solid var(--error)', color: 'var(--error)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>
        {error}
      </div>
    );
  }
  if (!reading || reading.length === 0) {
    return (
      <div style={{
        padding: 12, color: 'var(--text-tertiary)',
        fontSize: 12, fontStyle: 'italic',
        marginBottom: 16,
      }}>
        No documents opened yet.
      </div>
    );
  }

  const totalSeconds = reading.reduce((sum, d) => sum + (d.total_seconds || 0), 0);

  return (
    <div style={{ marginBottom: 16, padding: 12, background: 'var(--bg)', border: '1px solid var(--border)' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 12 }}>
        <div className="mono" style={{ fontSize: 10, letterSpacing: '0.12em', color: 'var(--text-tertiary)' }}>
          TIME SPENT PER DOC
        </div>
        <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)' }}>
          {reading.length} doc{reading.length === 1 ? '' : 's'} · total {secondsToLabel(totalSeconds)}
        </div>
      </div>

      <div style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
        gap: 12,
      }}>
        {reading.map(d => (
          <DocTile key={d.doc_id} doc={d} />
        ))}
      </div>
    </div>
  );
}

function DocTile({ doc }) {
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', alignItems: 'center',
      gap: 6, padding: '8px 4px',
    }}>
      <div style={{
        fontSize: 11, color: 'var(--text-secondary)',
        textAlign: 'center', width: '100%',
        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
      }} title={doc.doc_title}>
        {doc.doc_title}
      </div>
      <Doughnut
        scrollPct={doc.max_scroll_pct}
        label={secondsToLabel(doc.total_seconds)}
        downloaded={doc.downloaded}
      />
      <div className="mono" style={{ fontSize: 9, color: 'var(--text-tertiary)', letterSpacing: '0.06em' }}>
        {doc.open_count} open{doc.open_count === 1 ? '' : 's'} · {doc.max_scroll_pct || 0}%
      </div>
    </div>
  );
}
