// ─── Wave 17-C — GaokaoCohortsBlock ─────────────────────────────────────────
// Shows a "同分段去向" chip on the gaokao form.
// On click (or after score submission), opens a modal with a vanilla SVG
// horizontal bar chart of same-score-band peer admission outcomes.
//
// Data source: /data/gaokao-cohort-outcomes/<province>/<year>.json
// Schema: [{ scoreRange, year, totalStudents, breakdown: [{schoolName, count, pct}] }]
//
// data-testid attributes:
//   cohort-chip       — the trigger chip
//   cohort-modal      — the modal overlay
//   cohort-bar-<name> — each bar rect (name is schoolName, spaces replaced with -)

const GaokaoCohortsBlock = ({ lang, score, province }) => {
  const [open, setOpen]             = React.useState(false);
  const [selectedYear, setYear]     = React.useState(2025); // #292 — real HI cohort data is 2025 (2024 file is dormant/fabricated)
  const [data, setData]             = React.useState(null);   // full JSON array
  const [loading, setLoading]       = React.useState(false);
  const [fetchErr, setFetchErr]     = React.useState(null);

  // i18n dict
  const fallbackZh = (window.I18N && window.I18N.zh && window.I18N.zh.gk && window.I18N.zh.gk.cohort) || null;
  const dict = (window.I18N && window.I18N[lang] && window.I18N[lang].gk && window.I18N[lang].gk.cohort)
    || fallbackZh
    || {
      chip:     '同分段去向',
      title:    '同分段考生录取去向',
      subtitle: '与你同分数段的同侪最终去了哪？',
      close:    '关闭',
      yearLabel:'年份',
      rangeLabel:'分数段',
      totalLabel:'总人数',
      noData:   '暂无该分数段数据',
      loading:  '加载中…',
      errFetch: '数据加载失败，请刷新重试。',
      footer:   '数据基于公开录取信息整理，仅供参考。',
      pctSuffix: '%',
    };

  // Resolve province code from prop or default to HI
  const prov = province || 'HI';

  // Derive score range
  const scoreNum = typeof score === 'number' ? score : (typeof score === 'string' ? parseFloat(score) : null);

  function _findRange(s) {
    if (!s || !Number.isFinite(s)) return null;
    if (s >= 700) return '700+';
    if (s < 550)  return null;
    const RANGES = [
      [550,560],[560,570],[570,580],[580,590],[590,600],
      [600,610],[610,620],[620,630],[630,640],[640,650],
      [650,660],[660,670],[670,680],[680,690],[690,700],
    ];
    for (const [lo, hi] of RANGES) {
      if (s >= lo && s < hi) return `${lo}-${hi}`;
    }
    return null;
  }

  const resolvedRange = _findRange(scoreNum);

  // ── Data fetching ──────────────────────────────────────────────────────────
  const _cacheRef = React.useRef({});

  async function _fetchData(yr) {
    const cacheKey = `${prov}-${yr}`;
    if (_cacheRef.current[cacheKey] !== undefined) return _cacheRef.current[cacheKey];
    try {
      const res = await fetch(`/data/gaokao-cohort-outcomes/${prov}/${yr}.json`);
      if (!res.ok) {
        _cacheRef.current[cacheKey] = null;
        return null;
      }
      const json = await res.json();
      _cacheRef.current[cacheKey] = Array.isArray(json) ? json : null;
      return _cacheRef.current[cacheKey];
    } catch (_e) {
      _cacheRef.current[cacheKey] = null;
      return null;
    }
  }

  React.useEffect(() => {
    if (!open) return;
    setLoading(true);
    setFetchErr(null);
    _fetchData(selectedYear).then((d) => {
      setData(d);
      setLoading(false);
      if (d === null) setFetchErr(dict.errFetch || 'Load failed.');
    });
  }, [open, selectedYear]);

  // ── Body scroll lock ───────────────────────────────────────────────────────
  React.useEffect(() => {
    if (typeof document === 'undefined' || !document.body) return;
    if (!open) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = prev; };
  }, [open]);

  // ── ESC to close ───────────────────────────────────────────────────────────
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open]);

  // ── Derive current record ──────────────────────────────────────────────────
  const currentRange = resolvedRange;
  const record = React.useMemo(() => {
    if (!data || !currentRange) return null;
    return data.find((r) => r.scoreRange === currentRange && r.year === selectedYear) || null;
  }, [data, currentRange, selectedYear]);

  // All available ranges from loaded data (for selector)
  const allRanges = React.useMemo(() => {
    if (!data) return [];
    const seen = new Set();
    return data
      .filter((r) => r.year === selectedYear)
      .map((r) => r.scoreRange)
      .filter((s) => { if (seen.has(s)) return false; seen.add(s); return true; });
  }, [data, selectedYear]);

  const [activeRange, setActiveRange] = React.useState(null);

  // When data loads, set activeRange to resolved or first available
  React.useEffect(() => {
    if (!data) return;
    if (currentRange) { setActiveRange(currentRange); return; }
    if (allRanges.length > 0) setActiveRange(allRanges[0]);
  }, [data, currentRange]);

  const displayRecord = React.useMemo(() => {
    if (!data || !activeRange) return null;
    return data.find((r) => r.scoreRange === activeRange && r.year === selectedYear) || null;
  }, [data, activeRange, selectedYear]);

  // ── Bar chart helper ───────────────────────────────────────────────────────
  const BAR_COLORS = [
    '#b5985a', '#4c7eb5', '#4caf74', '#e09452', '#7b62a8',
    '#4cb8d4', '#e05252', '#9ca3af',
  ];

  function BarChart({ breakdown }) {
    if (!breakdown || breakdown.length === 0) return null;
    const maxPct = Math.max(...breakdown.map((b) => b.pct));
    const BAR_H = 28;
    const GAP   = 10;
    const LABEL_W = 90;
    const CHART_W = 280;
    const NUM_W   = 50;
    const svgH = breakdown.length * (BAR_H + GAP) - GAP + 4;

    return (
      <svg
        viewBox={`0 0 ${LABEL_W + CHART_W + NUM_W + 8} ${svgH}`}
        width="100%"
        style={{ display: 'block', overflow: 'visible' }}
        aria-label="录取去向分布图"
      >
        {breakdown.map((item, i) => {
          const barW = maxPct > 0 ? (item.pct / maxPct) * CHART_W : 0;
          const y = i * (BAR_H + GAP);
          const colorIdx = i < BAR_COLORS.length - 1 ? i : BAR_COLORS.length - 1;
          const color = BAR_COLORS[colorIdx];
          // testid: cohort-bar-清华大学 → cohort-bar-清华大学
          const testId = `cohort-bar-${item.schoolName.replace(/\s+/g, '-')}`;
          return (
            <g key={item.schoolName} data-testid={testId}>
              {/* School label */}
              <text
                x={LABEL_W - 6}
                y={y + BAR_H / 2 + 4}
                textAnchor="end"
                fontSize={11}
                fill="var(--pb-fg-muted, #6b7280)"
                fontFamily="var(--pb-sans, sans-serif)"
              >
                {item.schoolName.length > 6 ? item.schoolName.slice(0, 6) + '…' : item.schoolName}
              </text>
              {/* Bar */}
              <rect
                x={LABEL_W + 4}
                y={y}
                width={Math.max(barW, 2)}
                height={BAR_H}
                rx={4}
                fill={color}
                opacity={0.85}
              />
              {/* Pct label */}
              <text
                x={LABEL_W + 4 + Math.max(barW, 2) + 6}
                y={y + BAR_H / 2 + 4}
                fontSize={11}
                fill="var(--pb-fg-muted, #6b7280)"
                fontFamily="var(--pb-sans, sans-serif)"
              >
                {item.pct.toFixed(1)}%
              </text>
            </g>
          );
        })}
      </svg>
    );
  }

  // ── Render ─────────────────────────────────────────────────────────────────
  return (
    <React.Fragment>
      {/* Chip */}
      <button
        type="button"
        data-testid="cohort-chip"
        onClick={() => setOpen(true)}
        style={{
          display: 'inline-flex',
          alignItems: 'center',
          gap: 6,
          padding: '6px 14px',
          fontSize: 12,
          fontWeight: 600,
          letterSpacing: '0.04em',
          textTransform: 'uppercase',
          borderRadius: 100,
          border: '1px solid var(--pb-teal-500, #3b82a0)',
          background: 'transparent',
          color: 'var(--pb-teal-700, #1e6080)',
          cursor: 'pointer',
          transition: 'background 0.15s, color 0.15s',
        }}
        onMouseEnter={(e) => {
          e.currentTarget.style.background = 'var(--pb-teal-500, #3b82a0)';
          e.currentTarget.style.color = '#fff';
        }}
        onMouseLeave={(e) => {
          e.currentTarget.style.background = 'transparent';
          e.currentTarget.style.color = 'var(--pb-teal-700, #1e6080)';
        }}
      >
        <span aria-hidden="true" style={{ fontSize: 14, lineHeight: 1 }}>📊</span>
        {dict.chip || '同分段去向'}
      </button>

      {/* Modal — portalled to body to escape sticky stacking context (#258) */}
      {open && ReactDOM.createPortal(
        <div
          data-testid="cohort-modal"
          role="dialog"
          aria-modal="true"
          aria-labelledby="cohort-modal-title"
          style={{
            position: 'fixed',
            inset: 0,
            // Unified top modal layer — above auth-gate (2147483640) & tweaks panel (2147483646) so the popover is never occluded (#258/#218).
            zIndex: 2147483647,
            background: 'rgba(15, 22, 36, 0.55)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            padding: 24,
          }}
          onClick={(e) => { if (e.target === e.currentTarget) setOpen(false); }}
        >
          <div
            className="pb-card"
            style={{
              maxWidth: 680,
              width: '100%',
              maxHeight: '88vh',
              overflow: 'auto',
              padding: 0,
              boxShadow: '0 20px 60px rgba(0,0,0,0.35)',
            }}
          >
            {/* ── Header ── */}
            <div style={{
              padding: '20px 24px',
              borderBottom: '1px solid var(--pb-border)',
              display: 'flex',
              justifyContent: 'space-between',
              alignItems: 'flex-start',
              gap: 16,
              position: 'sticky',
              top: 0,
              background: 'var(--pb-paper)',
              zIndex: 1,
            }}>
              <div>
                <div className="pb-eyebrow" style={{ color: 'var(--pb-teal-700, #1e6080)', marginBottom: 6, fontSize: 11 }}>
                  同分段录取去向 · WAVE 17-C
                </div>
                <h3
                  id="cohort-modal-title"
                  style={{ fontFamily: 'var(--pb-serif)', fontSize: 20, fontWeight: 600, margin: 0 }}
                >
                  {dict.title || '同分段考生录取去向'}
                </h3>
                {dict.subtitle && (
                  <p style={{ fontSize: 12, color: 'var(--pb-fg-muted)', margin: '4px 0 0', lineHeight: 1.5 }}>
                    {dict.subtitle}
                  </p>
                )}
              </div>
              <button
                type="button"
                data-testid="cohort-close"
                aria-label={dict.close || '关闭'}
                onClick={() => setOpen(false)}
                style={{
                  background: 'transparent',
                  border: '1px solid var(--pb-border)',
                  borderRadius: 8,
                  padding: '4px 10px',
                  fontSize: 16,
                  lineHeight: 1,
                  cursor: 'pointer',
                  color: 'var(--pb-fg-muted)',
                  flexShrink: 0,
                }}
              >
                ×
              </button>
            </div>

            {/* ── Controls ── */}
            <div style={{
              padding: '16px 24px',
              borderBottom: '1px solid var(--pb-border)',
              display: 'flex',
              gap: 16,
              flexWrap: 'wrap',
              alignItems: 'center',
              background: 'var(--pb-surface-alt)',
            }}>
              {/* Year selector */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--pb-fg-muted)', whiteSpace: 'nowrap' }}>
                  {dict.yearLabel || '年份'}
                </label>
                {[2025].map((yr) => (
                  <button
                    key={yr}
                    type="button"
                    onClick={() => setYear(yr)}
                    style={{
                      padding: '4px 12px',
                      fontSize: 12,
                      fontWeight: 600,
                      borderRadius: 100,
                      border: `1px solid ${selectedYear === yr ? 'var(--pb-teal-500, #3b82a0)' : 'var(--pb-border)'}`,
                      background: selectedYear === yr ? 'var(--pb-teal-500, #3b82a0)' : 'transparent',
                      color: selectedYear === yr ? '#fff' : 'var(--pb-fg-muted)',
                      cursor: 'pointer',
                    }}
                  >
                    {yr}
                  </button>
                ))}
              </div>

              {/* Range selector */}
              {allRanges.length > 0 && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--pb-fg-muted)', whiteSpace: 'nowrap' }}>
                    {dict.rangeLabel || '分数段'}
                  </label>
                  <select
                    data-testid="cohort-range-select"
                    value={activeRange || ''}
                    onChange={(e) => setActiveRange(e.target.value)}
                    style={{
                      fontSize: 12,
                      padding: '4px 8px',
                      borderRadius: 6,
                      border: '1px solid var(--pb-border)',
                      background: 'var(--pb-paper)',
                      color: 'var(--pb-fg)',
                      cursor: 'pointer',
                    }}
                  >
                    {allRanges.map((r) => (
                      <option key={r} value={r}>{r} 分</option>
                    ))}
                  </select>
                </div>
              )}
            </div>

            {/* ── Chart body ── */}
            <div style={{ padding: '20px 24px' }}>
              {loading && (
                <div style={{ textAlign: 'center', color: 'var(--pb-fg-muted)', fontSize: 13, padding: '40px 0' }}>
                  {dict.loading || '加载中…'}
                </div>
              )}
              {fetchErr && !loading && (
                <div style={{ textAlign: 'center', color: '#e05252', fontSize: 13, padding: '40px 0' }}>
                  {fetchErr}
                </div>
              )}
              {!loading && !fetchErr && !displayRecord && (
                <div style={{ textAlign: 'center', color: 'var(--pb-fg-muted)', fontSize: 13, padding: '40px 0' }}>
                  {dict.noData || '暂无该分数段数据'}
                </div>
              )}
              {!loading && !fetchErr && displayRecord && (
                <React.Fragment>
                  {/* Summary line */}
                  <div style={{ marginBottom: 16, display: 'flex', gap: 20, flexWrap: 'wrap', alignItems: 'center' }}>
                    <div>
                      <span style={{ fontSize: 11, color: 'var(--pb-fg-muted)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.04em' }}>
                        {dict.rangeLabel || '分数段'}
                      </span>
                      <div style={{ fontSize: 20, fontWeight: 700, fontFamily: 'var(--pb-serif)', color: 'var(--pb-teal-700, #1e6080)' }}>
                        {displayRecord.scoreRange}
                      </div>
                    </div>
                    <div>
                      <span style={{ fontSize: 11, color: 'var(--pb-fg-muted)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.04em' }}>
                        {dict.totalLabel || '总人数'}
                      </span>
                      <div style={{ fontSize: 20, fontWeight: 700, fontFamily: 'var(--pb-serif)' }}>
                        {displayRecord.totalStudents.toLocaleString()}
                      </div>
                    </div>
                    <div style={{ fontSize: 12, color: 'var(--pb-fg-muted)', lineHeight: 1.5 }}>
                      {selectedYear} 年海南高考
                    </div>
                  </div>

                  {/* Bar chart */}
                  <div style={{ padding: '8px 0 12px' }}>
                    <BarChart breakdown={displayRecord.breakdown} />
                  </div>

                  {/* Breakdown table (compact) */}
                  <div style={{ marginTop: 16 }}>
                    <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                      <thead>
                        <tr style={{ borderBottom: '1px solid var(--pb-border)' }}>
                          <th style={{ textAlign: 'left', padding: '6px 0', color: 'var(--pb-fg-muted)', fontWeight: 600 }}>院校</th>
                          <th style={{ textAlign: 'right', padding: '6px 0', color: 'var(--pb-fg-muted)', fontWeight: 600 }}>人数</th>
                          <th style={{ textAlign: 'right', padding: '6px 8px', color: 'var(--pb-fg-muted)', fontWeight: 600 }}>占比</th>
                        </tr>
                      </thead>
                      <tbody>
                        {displayRecord.breakdown.map((item, idx) => (
                          <tr key={item.schoolName} style={{ borderBottom: '1px solid var(--pb-border)', opacity: item.schoolName === '其他' ? 0.65 : 1 }}>
                            <td style={{ padding: '7px 0', color: 'var(--pb-fg)' }}>{item.schoolName}</td>
                            <td style={{ padding: '7px 0', textAlign: 'right', color: 'var(--pb-fg)', fontVariantNumeric: 'tabular-nums' }}>{item.count}</td>
                            <td style={{ padding: '7px 8px', textAlign: 'right', color: 'var(--pb-fg-muted)', fontVariantNumeric: 'tabular-nums' }}>{item.pct.toFixed(1)}%</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                </React.Fragment>
              )}
            </div>

            {/* ── Footer ── */}
            <div style={{
              padding: '12px 24px',
              borderTop: '1px solid var(--pb-border)',
              background: 'var(--pb-surface-alt)',
              fontSize: 11,
              color: 'var(--pb-fg-muted)',
              lineHeight: 1.6,
            }}>
              {dict.footer || '数据基于公开录取信息整理，仅供参考。实际录取以各省招考院公告为准。'}
            </div>
          </div>
        </div>
      , document.body)}
    </React.Fragment>
  );
};

window.GaokaoCohortsBlock = GaokaoCohortsBlock;
