// charts.jsx — reusable editorial charts (ink marks, hairlines, tabular figures)
const { useState: useSC } = React;

// dual-anchor 四象限 scatter
function QuadrantScatter({ go }) {
  const { ASSESSED, INST_MEAN, recentAvg, deltaAvg, quadrantOf, QUADRANT_META } = window;
  const [hover, setHover] = useSC(null);
  const W = 560, H = 420, L = 54, R = 540, T = 22, B = 372;
  const xD = [-16, 18], yD = [-26, 18];
  const xPix = (d) => L + ((d - xD[0]) / (xD[1] - xD[0])) * (R - L);
  const yPix = (v) => T + ((yD[1] - v) / (yD[1] - yD[0])) * (B - T);
  const cx0 = xPix(0), cy0 = yPix(0);
  const pts = ASSESSED.map((s) => ({
    s, q: quadrantOf(s),
    x: xPix(Math.max(xD[0], Math.min(xD[1], deltaAvg(s)))),
    y: yPix(Math.max(yD[0], Math.min(yD[1], recentAvg(s) - INST_MEAN))),
    risk: s.status === '需關注',
  }));
  const qLab = (x, y, anchor, key) => <text x={x} y={y} textAnchor={anchor} fontFamily="'Noto Serif TC',serif" fontSize="13" fill="var(--ink-3)">{QUADRANT_META[key].label}</text>;
  return (
    <svg width="100%" viewBox={`0 0 ${W} ${H}`} style={{ display: 'block' }}>
      <rect x={L} y={T} width={R - L} height={B - T} fill="none" stroke="var(--border)" strokeWidth="0.5" />
      <line x1={cx0} y1={T} x2={cx0} y2={B} stroke="var(--border-strong)" strokeWidth="0.5" />
      <line x1={L} y1={cy0} x2={R} y2={cy0} stroke="var(--border-strong)" strokeWidth="0.5" />
      {qLab(R - 6, T + 16, 'end', 'maintain')}
      {qLab(L + 6, T + 16, 'start', 'acute')}
      {qLab(R - 6, B - 8, 'end', 'follow')}
      {qLab(L + 6, B - 8, 'start', 'risk')}
      <text x={L - 6} y={cy0 + 3} textAnchor="end" fontFamily="'Fraunces',serif" fontSize="11" fill="var(--ink-3)">{INST_MEAN}</text>
      {pts.map((p) => (
        <g key={p.s.id} style={{ cursor: 'pointer' }} onMouseEnter={() => setHover(p.s.id)} onMouseLeave={() => setHover(null)} onClick={() => go('inst.member', { studentId: p.s.id })}>
          {p.risk
            ? <circle cx={p.x} cy={p.y} r={hover === p.s.id ? 6 : 4.5} fill="var(--canvas)" stroke="var(--attention)" strokeWidth="1.5" />
            : <circle cx={p.x} cy={p.y} r={hover === p.s.id ? 6 : 4} fill="var(--mark)" />}
          {hover === p.s.id && <text x={p.x} y={p.y - 10} textAnchor="middle" fontFamily="'Noto Sans TC',sans-serif" fontSize="12" fill="var(--ink)">{p.s.name}</text>}
        </g>
      ))}
      <text x={(L + R) / 2} y={H - 6} textAnchor="middle" fontFamily="'Noto Sans TC',sans-serif" fontSize="12" fill="var(--ink-2)">較前測　退步 ←　→ 進步</text>
      <text transform={`translate(15 ${(T + B) / 2}) rotate(-90)`} textAnchor="middle" fontFamily="'Noto Sans TC',sans-serif" fontSize="12" fill="var(--ink-2)">相對機構平均　低於 ←　→ 高於</text>
    </svg>
  );
}

// 前後測 slope chart (per power)
function SlopeChart({ rows }) {
  const W = 300, rowH = 30, top = 8, left = 92, right = W - 8;
  const xV = (v) => left + (v / 100) * (right - left);
  return (
    <svg width="100%" viewBox={`0 0 ${W} ${rows.length * rowH + 16}`} style={{ display: 'block' }}>
      {rows.map((r, i) => {
        const y = top + i * rowH + 8;
        return (
          <g key={r.name}>
            <text x={0} y={y + 4} fontFamily="'Noto Sans TC',sans-serif" fontSize="12" fill={r.soft ? 'var(--ink-2)' : 'var(--ink)'}>{r.name}{r.soft ? '◦' : ''}</text>
            <line x1={left} y1={y} x2={right} y2={y} stroke="var(--border)" strokeWidth="0.5" />
            <line x1={xV(r.b)} y1={y} x2={xV(r.r)} y2={y} stroke="var(--mark)" strokeWidth="1" />
            <circle cx={xV(r.b)} cy={y} r="2.5" fill="var(--canvas)" stroke="var(--ink-3)" strokeWidth="1" />
            <circle cx={xV(r.r)} cy={y} r="3" fill="var(--mark)" />
          </g>
        );
      })}
    </svg>
  );
}

// composite trend line
function TrendLine({ vals, labels, min = 40, max = 90 }) {
  const W = 300, H = 130, pad = 16;
  const xs = vals.map((_, i) => pad + (i / (vals.length - 1)) * (W - pad * 2));
  const ys = vals.map((v) => H - pad - ((v - min) / (max - min)) * (H - pad * 2));
  const path = xs.map((x, i) => (i ? 'L' : 'M') + x + ' ' + ys[i]).join(' ');
  return (
    <svg width="100%" viewBox={`0 0 ${W} ${H + 18}`} style={{ display: 'block' }}>
      <line x1={pad} y1={H - pad} x2={W - pad} y2={H - pad} stroke="var(--border)" strokeWidth="0.5" />
      <path d={path} fill="none" stroke="var(--mark)" strokeWidth="1.5" />
      {xs.map((x, i) => <circle key={i} cx={x} cy={ys[i]} r="3" fill="var(--mark)" />)}
      {labels && xs.map((x, i) => <text key={i} x={x} y={H + 12} textAnchor="middle" fontFamily="'Fraunces',serif" fontSize="10" fill="var(--ink-3)">{labels[i]}</text>)}
      {xs.map((x, i) => <text key={'v' + i} x={x} y={ys[i] - 7} textAnchor="middle" fontFamily="'Fraunces',serif" fontSize="11" fill="var(--ink-2)">{vals[i]}</text>)}
    </svg>
  );
}

// weekly bars
function TrendBars({ vals, prefix = 'W', max = 100 }) {
  const W = 560, H = 130, pad = 16, n = vals.length;
  const bw = (W - pad * 2) / n * 0.5;
  return (
    <svg width="100%" viewBox={`0 0 ${W} ${H + 18}`} style={{ display: 'block' }}>
      <line x1={pad} y1={H - pad} x2={W - pad} y2={H - pad} stroke="var(--border-strong)" strokeWidth="0.5" />
      {vals.map((v, i) => {
        const x = pad + (i + 0.5) * ((W - pad * 2) / n);
        const h = (v / max) * (H - pad * 2);
        return (
          <g key={i}>
            <rect x={x - bw / 2} y={H - pad - h} width={bw} height={h} fill="var(--mark)" />
            <text x={x} y={H - pad - h - 6} textAnchor="middle" fontFamily="'Fraunces',serif" fontSize="11" fill="var(--ink-2)">{v}</text>
            <text x={x} y={H + 12} textAnchor="middle" fontFamily="'Fraunces',serif" fontSize="10" fill="var(--ink-3)">{prefix}{i + 1}</text>
          </g>
        );
      })}
    </svg>
  );
}

Object.assign(window, { QuadrantScatter, SlopeChart, TrendLine, TrendBars });
