/* ENSSA Reporting — chart primitives.
   Risk colours from CSS tokens. Charts handle the four-state risk schema. */

/* global React, RISK, RISK_ORDER, useMediaQuery */

/* ─── Risk breakdown stacked bar ─────────────────────────── */
function RiskBreakdownStackedBar({ counts, height = 18, showLegend = true, showLabels = false }) {
  const total = counts.low + counts.moderate + counts.high + counts.more_info || 1;
  const segs = RISK_ORDER.map((k) => ({ key: k, n: counts[k] || 0, pct: (counts[k] || 0) / total * 100 }));
  return (
    <div>
      <div style={{ display: 'flex', height, borderRadius: 999, overflow: 'hidden', background: 'var(--ink-100)', border: '1px solid var(--border-subtle)' }}>
        {segs.map((s) => s.n > 0 &&
        <div key={s.key} title={`${RISK[s.key].label}: ${s.n}`}
        style={{
          width: `${s.pct}%`,
          background: s.key === 'more_info' ? 'repeating-linear-gradient(45deg, var(--ink-200) 0 6px, var(--ink-100) 6px 12px)' : RISK[s.key].color,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: s.key === 'more_info' ? 'var(--fg-2)' : '#fff',
          fontSize: 11, fontWeight: 700
        }}>
            {showLabels && s.pct > 8 ? s.n : null}
          </div>
        )}
      </div>
      {showLegend &&
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 14, marginTop: 10, fontSize: 12, color: 'var(--fg-2)' }}>
          {RISK_ORDER.map((k) =>
        <span key={k} style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
              <span style={{
            width: 10, height: 10, borderRadius: 2,
            background: k === 'more_info' ? 'repeating-linear-gradient(45deg, var(--ink-200) 0 3px, var(--ink-100) 3px 6px)' : RISK[k].color,
            border: '1px solid var(--border-default)'
          }} />
              <strong style={{ fontFamily: 'var(--font-mono)', color: 'var(--fg-1)' }}>{counts[k] || 0}</strong>{' '}
              {RISK[k].label.toLowerCase()}
            </span>
        )}
        </div>
      }
    </div>);

}

/* ─── Task box plot panel ────────────────────────────────── */
function TaskBoxPlotPanel({ stats, compact = false }) {
  const isNarrow = useMediaQuery('(max-width: 640px)');
  const desktopCols = compact ? '140px 1fr 200px' : '170px 1fr 220px';
  const narrowCols = 'minmax(110px, 36%) 1fr';
  return (
    <div>
      <div style={{ display: 'grid', gridTemplateColumns: isNarrow ? narrowCols : desktopCols, gap: isNarrow ? 12 : 16, alignItems: 'center', padding: '6px 0 14px', borderBottom: '1px solid var(--border-subtle)', fontSize: 11, fontWeight: 700, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
        <div>Task</div>
        <div>{isNarrow ? 'DISTRIBUTION' : 'PERCENTILE DISTRIBUTION'}</div>
        {!isNarrow && <div style={{ textAlign: 'right' }}>STATS</div>}
      </div>
      {Object.values(stats).map((s) => <BoxPlotRow key={s.id} s={s} compact={compact} isNarrow={isNarrow} />)}
    </div>);

}

function BoxPlotRow({ s, compact, isNarrow }) {
  const W = 100;
  const [tip, setTip] = React.useState(null); // { label, pct }
  const [expanded, setExpanded] = React.useState(false);
  const desktopCols = compact ? '140px 1fr 200px' : '170px 1fr 220px';
  const narrowCols = 'minmax(110px, 36%) 1fr';

  const toggleExpanded = (e) => {
    if (!isNarrow) return;
    // Don't toggle if user was hovering/clicking on the box plot (tooltip targets)
    if (e.target.closest('svg')) return;
    setExpanded(v => !v);
  };

  const statsBlock = (
    <div style={{ textAlign: isNarrow ? 'left' : 'right', fontSize: 12, lineHeight: 1.65, color: 'var(--fg-2)', fontFamily: 'var(--font-mono)' }}>
      <div>Median <strong>P{s.p50}</strong> · IQR P{s.p25}–P{s.p75}</div>
      <div>
        {s.below20 > 0 && <span style={{ color: 'var(--risk-concern-fg)', fontWeight: 700 }}>{s.below20} below P20 · </span>}
        <span style={{ color: 'var(--fg-3)' }}>n={s.n}</span>
      </div>
    </div>
  );

  return (
    <div style={{ borderBottom: '1px solid var(--border-subtle)' }}>
      <div onClick={toggleExpanded}
        style={{ display: 'grid', gridTemplateColumns: isNarrow ? narrowCols : desktopCols, gap: isNarrow ? 12 : 16, alignItems: 'center', padding: '14px 0', cursor: isNarrow ? 'pointer' : 'default' }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>
          {isNarrow && (
            <span aria-hidden="true" style={{ fontSize: 11, color: 'var(--fg-3)', flexShrink: 0, marginTop: 2 }}>{expanded ? '▾' : '▸'}</span>
          )}
          <div style={{ fontWeight: 700, fontSize: isNarrow ? 13 : 14, lineHeight: 1.3, whiteSpace: 'normal', wordBreak: 'break-word', flex: 1 }}>{s.label}</div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ fontSize: 9, color: 'var(--fg-3)', fontFamily: 'var(--font-mono)', flexShrink: 0 }}>P0</span>
          <div style={{ flex: 1, position: 'relative', height: 28 }}>
            {tip && (
              <div style={{
                position: 'absolute', left: `${tip.pct}%`, bottom: 'calc(100% + 6px)',
                transform: 'translateX(-50%)',
                background: 'var(--ink-800)', color: '#fff',
                fontSize: 11, fontWeight: 700, padding: '4px 9px', borderRadius: 6,
                whiteSpace: 'nowrap', pointerEvents: 'none', zIndex: 10,
                boxShadow: 'var(--sh-2)',
              }}>
                {tip.label}
                <span style={{ position: 'absolute', left: '50%', bottom: -4, transform: 'translateX(-50%)', width: 8, height: 8, background: 'var(--ink-800)', clipPath: 'polygon(0 0,100% 0,50% 100%)' }} />
              </div>
            )}
            <svg viewBox={`0 0 ${W} 28`} preserveAspectRatio="none"
              style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', overflow: 'visible' }}>
              <line x1={0} x2={0} y1={2} y2={26} stroke="var(--ink-150)" strokeWidth="0.5" />
              <line x1={100} x2={100} y1={2} y2={26} stroke="var(--ink-150)" strokeWidth="0.5" />
              <line x1={s.p10} x2={s.p90} y1={14} y2={14} stroke="var(--ink-300)" strokeWidth="0.6" />
              <line x1={s.p10} x2={s.p10} y1={9}  y2={19} stroke="var(--ink-300)" strokeWidth="0.6"
                style={{ cursor: 'pointer' }}
                onMouseEnter={() => setTip({ label: `P${s.p10}`, pct: s.p10 })}
                onMouseLeave={() => setTip(null)} />
              <line x1={s.p90} x2={s.p90} y1={9}  y2={19} stroke="var(--ink-300)" strokeWidth="0.6"
                style={{ cursor: 'pointer' }}
                onMouseEnter={() => setTip({ label: `P${s.p90}`, pct: s.p90 })}
                onMouseLeave={() => setTip(null)} />
              {/* IQR box — hoverable */}
              <rect x={s.p25} y={6} width={Math.max(0.6, s.p75 - s.p25)} height={16}
                fill="var(--enssa-mauve)" opacity="0.38" stroke="var(--enssa-aubergine)" strokeWidth="0.5"
                style={{ cursor: 'pointer' }}
                onMouseEnter={() => setTip({ label: `IQR: P${s.p25} to P${s.p75}`, pct: (s.p25 + s.p75) / 2 })}
                onMouseLeave={() => setTip(null)} />
              {/* Invisible wide hit area for median */}
              <line x1={s.p50} x2={s.p50} y1={4} y2={24} stroke="transparent" strokeWidth="8"
                style={{ cursor: 'pointer' }}
                onMouseEnter={() => setTip({ label: `Median: P${s.p50}`, pct: s.p50 })}
                onMouseLeave={() => setTip(null)} />
              <line x1={s.p50} x2={s.p50} y1={4} y2={24} stroke="var(--enssa-aubergine)" strokeWidth="0.9"
                style={{ pointerEvents: 'none' }} />
            </svg>
          </div>
          <span style={{ fontSize: 9, color: 'var(--fg-3)', fontFamily: 'var(--font-mono)', flexShrink: 0 }}>P100</span>
        </div>
        {!isNarrow && statsBlock}
      </div>
      {isNarrow && expanded && (
        <div style={{ background: 'var(--ink-50)', padding: '10px 12px 14px', borderTop: '1px solid var(--border-subtle)' }}>
          {statsBlock}
        </div>
      )}
    </div>
  );
}

/* ─── Risk Pyramid (3-tier visual: high top, mod mid, low base) ── */
function RiskPyramid({ counts }) {
  const total = (counts.low + counts.moderate + counts.high + (counts.more_info || 0)) || 1;
  // minW: enough for "MODERATE RISK" label + 1 digit. All bars start at this width and grow.
  // We express everything as a flex layout: a fixed label portion + a proportional grow portion.
  const tiers = [
    { k: 'high',     n: counts.high,     frac: counts.high / total },
    { k: 'moderate', n: counts.moderate, frac: counts.moderate / total },
    { k: 'low',      n: counts.low,      frac: counts.low / total },
  ];
  const maxFrac = Math.max(...tiers.map(t => t.frac), (counts.more_info || 0) / total, 0.01);

  function TierBar({ color, label, n, frac }) {
    // Bars scale from 25% (min, fits label + 1 digit) to 100% (largest bar)
    const widthPct = 25 + (frac / maxFrac) * 75;
    return (
      <div style={{
        width: `${widthPct}%`,
        background: color, color: '#fff',
        padding: '14px 18px', borderRadius: 6,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        fontWeight: 700, boxSizing: 'border-box',
      }}>
        <span style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', lineHeight: 1.2, flexShrink: 0 }}>{label}</span>
        <span style={{ fontSize: 24, fontFamily: 'var(--font-mono)', fontWeight: 900, marginLeft: 12 }}>{n}</span>
      </div>
    );
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {tiers.map(t => (
        <TierBar key={t.k} color={RISK[t.k].color} label={RISK[t.k].label} n={t.n} frac={t.frac} />
      ))}
      {(counts.more_info || 0) > 0 && (
        <div style={{ marginTop: 2 }}>
          <div style={{
            width: `${25 + ((counts.more_info / total) / maxFrac) * 75}%`,
            background: 'var(--ink-150)', padding: '14px 18px', borderRadius: 6,
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            fontWeight: 700, boxSizing: 'border-box',
          }}>
            <span style={{ fontSize: 12, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: 'var(--fg-2)', flexShrink: 0 }}>Pending</span>
            <span style={{ fontSize: 24, fontFamily: 'var(--font-mono)', fontWeight: 900, color: 'var(--fg-2)', marginLeft: 12 }}>{counts.more_info}</span>
          </div>
        </div>
      )}
    </div>
  );
}

/* ─── Task percentile bar (Student page) ─────────────────── */
function TaskPercentileBar({ value }) {
  return (
    <div style={{ position: 'relative', height: 10, background: 'var(--ink-100)', borderRadius: 999, width: '100%' }}>
      <div style={{ position: 'absolute', left: 0, top: 0, height: '100%', width: `${value}%`, background: 'linear-gradient(to right, color-mix(in oklab, var(--enssa-mauve) 25%, transparent), color-mix(in oklab, var(--enssa-mauve) 65%, transparent))', borderRadius: 999 }} />
      <div style={{ position: 'absolute', left: `${value}%`, top: -3, transform: 'translateX(-50%)', width: 4, height: 16, background: 'var(--enssa-aubergine)', borderRadius: 2 }} />
    </div>);

}

/* ─── Population position bar (Student page header) ─────── */
function PopulationPositionBar({ percentile, intervalLow, intervalHigh }) {
  return (
    <div>
      <div style={{ position: 'relative', height: 24, background: 'var(--ink-100)', borderRadius: 999 }}>
        {[10, 25, 50, 75, 90].map((t) =>
        <div key={t} style={{ position: 'absolute', left: `${t}%`, top: 4, bottom: 4, width: 1, background: 'rgba(0,0,0,0.10)' }} />
        )}
        {intervalLow != null &&
        <div style={{ position: 'absolute', left: `${intervalLow}%`, width: `${intervalHigh - intervalLow}%`, top: 0, bottom: 0, background: 'color-mix(in oklab, var(--enssa-mauve) 35%, transparent)', borderRadius: 999 }} />
        }
        <div style={{ position: 'absolute', left: `${percentile}%`, top: -4, transform: 'translateX(-50%)', width: 6, height: 32, background: 'var(--enssa-aubergine)', borderRadius: 3 }} />
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: 'var(--fg-3)', marginTop: 6, fontFamily: 'var(--font-mono)' }}>
        <span>P0</span><span>P25</span><span>P50</span><span>P75</span><span>P100</span>
      </div>
    </div>);

}

Object.assign(window, { RiskBreakdownStackedBar, TaskBoxPlotPanel, RiskPyramid, TaskPercentileBar, PopulationPositionBar });