// 04 · The Record Keepers — the human layer.

function TabKeepers() {
  const [selected, setSelected] = React.useState(0);
  const station = window.STATIONS[selected];

  return (
    <div style={{ padding: '32px 56px 80px' }}>
      <Eyebrow id="04 · THE RECORD KEEPERS"
        title="Eight stations. Eight century-long instruments. Eight stories the data tells."
        right="Ranked · signal-to-noise on the warming trend" />

      <div style={{ display: 'grid', gridTemplateColumns: '320px 1fr', gap: 24 }}>
        {/* Station list */}
        <div>
          <Tick>▌ INSTRUMENTS</Tick>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 1, marginTop: 12, background: '#1B2740', border: '1px solid #1B2740' }}>
            {window.STATIONS.map((s, i) => {
              const active = selected === i;
              return (
                <button key={s.id} onClick={() => setSelected(i)} style={{
                  background: active ? 'rgba(201,168,76,0.08)' : 'var(--bg-2)',
                  border: 'none', borderLeft: active ? '2px solid #C9A84C' : '2px solid transparent',
                  textAlign: 'left', padding: '14px 16px', cursor: 'pointer',
                  display: 'flex', flexDirection: 'column', gap: 4,
                }}>
                  <div className="mono" style={{ color: '#4E6A82', fontSize: 9.5, letterSpacing: 0.15 }}>{s.id}</div>
                  <div className="serif" style={{ color: active ? '#E6ECF2' : '#8BAFC7', fontSize: 15 }}>
                    {s.name}, {s.state}
                  </div>
                  <div className="mono" style={{ color: '#4E6A82', fontSize: 10 }}>
                    EST. {s.since} · {2025 - s.since} YRS
                  </div>
                </button>
              );
            })}
          </div>
        </div>

        {/* Station detail card */}
        <StationCard station={station} />
      </div>

      {/* Signal-to-noise ranking */}
      <div style={{ marginTop: 48 }}>
        <Eyebrow id="04 · ADDENDUM"
          title="Where the warming signal is clearest in the noise."
          right="Stations ranked by trend / variance ratio" />

        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 24 }}>
          <SignalToNoiseChart selectedId={station.id} onSelect={(i) => setSelected(i)} />

          <div style={{ border: '1px solid #1B2740', background: 'rgba(14,20,34,0.6)', padding: 24 }}>
            <Tick color="#C9A84C">▌ THE INTERESTING ML FINDING</Tick>
            <div className="serif" style={{ fontSize: 18, color: '#E6ECF2', marginTop: 14, lineHeight: 1.45, fontWeight: 300 }}>
              Stations vary wildly in how cleanly their century-long trend separates from year-to-year noise.
              Some have a textbook signal: the warming line emerges through the variance with almost no ambiguity.
              Others — coastal, marine, or short-record — wobble more.
            </div>
            <div className="serif" style={{ fontSize: 14, color: '#8BAFC7', marginTop: 16, lineHeight: 1.55 }}>
              The top-ranked stations are not necessarily the ones with the biggest extremes —
              they are the ones whose readings have left the least room for doubt.
            </div>
            <div style={{ marginTop: 18 }}><Confidence level="high" /></div>
          </div>
        </div>
      </div>
    </div>
  );
}

function StationCard({ station }) {
  // Compute a fit line
  const data = station.annual;
  const n = data.length;
  const meanX = (n - 1) / 2;
  let meanY = 0; for (const d of data) meanY += d.anomaly; meanY /= n;
  let num = 0, den = 0;
  for (let i = 0; i < n; i++) {
    num += (i - meanX) * (data[i].anomaly - meanY);
    den += (i - meanX) ** 2;
  }
  const slope = num / den; const intercept = meanY - slope * meanX;
  const fit = (i) => intercept + slope * i;

  const W = 820, H = 280, padL = 40, padR = 16, padT = 16, padB = 28;
  const innerW = W - padL - padR, innerH = H - padT - padB;
  const xs = (y) => padL + ((y - data[0].year) / (data[n-1].year - data[0].year)) * innerW;
  const ymin = -2.2, ymax = 3.2;
  const ys = (v) => padT + (1 - (v - ymin) / (ymax - ymin)) * innerH;
  const barW = Math.max(1.6, innerW / n - 0.6);

  return (
    <div style={{ border: '1px solid #1B2740', background: 'rgba(14,20,34,0.6)' }}>
      {/* Instrument-panel header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', padding: '20px 24px', borderBottom: '1px solid #1B2740' }}>
        <div>
          <div className="mono" style={{ color: '#C9A84C', fontSize: 11, letterSpacing: 0.2 }}>
            {station.id}
          </div>
          <div className="serif" style={{ fontSize: 30, color: '#E6ECF2', marginTop: 4, letterSpacing: -0.5, fontWeight: 300 }}>
            {station.name}, {station.state}
          </div>
          <div className="mono" style={{ color: '#8BAFC7', fontSize: 11, marginTop: 6 }}>
            {station.lat.toFixed(2)}°N · {Math.abs(station.lon).toFixed(2)}°W · GHCN-DAILY
          </div>
        </div>
        <div style={{ display: 'flex', gap: 20, alignItems: 'flex-start' }}>
          <MiniStat label="EST." value={station.since} />
          <MiniStat label="YRS REC." value={2025 - station.since} />
          <MiniStat label="GAPS" value="< 1%" />
        </div>
      </div>

      {/* Featured extreme */}
      <div style={{ padding: '20px 24px', display: 'flex', alignItems: 'center', gap: 30, borderBottom: '1px solid #1B2740' }}>
        <div>
          <Tick color="#C9A84C">▌ FEATURED RECORD</Tick>
          <div className="mono" style={{ color: '#4E6A82', fontSize: 11, marginTop: 4 }}>{station.extreme.label.toUpperCase()}</div>
        </div>
        <div className="mono" style={{ color: station.extreme.value.startsWith('-') || station.extreme.value.startsWith('−') ? '#74ADD1' : '#D73027', fontSize: 48, fontWeight: 700, letterSpacing: -1, lineHeight: 1 }}>
          {station.extreme.value}
        </div>
        <div>
          <div className="mono" style={{ color: '#E6ECF2', fontSize: 14 }}>{station.extreme.date}</div>
          <div className="serif" style={{ color: '#8BAFC7', fontSize: 13, marginTop: 4, fontStyle: 'italic', maxWidth: 380 }}>
            {station.note}
          </div>
        </div>
      </div>

      {/* Annual chart */}
      <div style={{ padding: '14px 24px 6px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <Tick>▌ ANNUAL ANOMALY · {data[0].year}–{data[n-1].year}</Tick>
          <Tick>TREND · +{(slope * 100).toFixed(2)} °F / century</Tick>
        </div>
      </div>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ display: 'block', width: '100%', height: 'auto' }}>
        {[-2, -1, 0, 1, 2, 3].map(v => (
          <g key={v}>
            <line x1={padL} x2={W - padR} y1={ys(v)} y2={ys(v)}
              stroke={v === 0 ? '#8BAFC7' : '#1B2740'} strokeWidth={v === 0 ? 1 : 0.4}
              strokeDasharray={v === 0 ? '0' : '2 4'} />
            <text x={padL - 6} y={ys(v) + 3} textAnchor="end" className="mono" fill="#4E6A82" fontSize="9" fontFamily="Space Mono">
              {v > 0 ? `+${v}` : v}°
            </text>
          </g>
        ))}
        {data.map((d, i) => (
          <rect key={d.year}
            x={xs(d.year) - barW / 2}
            y={d.anomaly >= 0 ? ys(d.anomaly) : ys(0)}
            width={barW}
            height={Math.abs(ys(d.anomaly) - ys(0))}
            fill={window.anomalyColor(d.anomaly)}
            opacity="0.95"
          />
        ))}
        {/* Fit line */}
        <line
          x1={xs(data[0].year)} y1={ys(fit(0))}
          x2={xs(data[n-1].year)} y2={ys(fit(n-1))}
          stroke="#C9A84C" strokeWidth="1.2" strokeDasharray="3 3"
        />
        <text x={W - padR - 4} y={ys(fit(n-1)) - 6} textAnchor="end" className="mono" fill="#C9A84C" fontSize="9" fontFamily="Space Mono">FIT</text>
        {/* X ticks */}
        {[data[0].year, data[Math.floor(n/4)].year, data[Math.floor(n/2)].year, data[Math.floor(3*n/4)].year, data[n-1].year].map(y => (
          <text key={y} x={xs(y)} y={padT + innerH + 16} textAnchor="middle" className="mono" fill="#4E6A82" fontSize="9" fontFamily="Space Mono">{y}</text>
        ))}
      </svg>
    </div>
  );
}

function MiniStat({ label, value }) {
  return (
    <div style={{ textAlign: 'right' }}>
      <div className="mono" style={{ color: '#4E6A82', fontSize: 9.5, letterSpacing: 0.15, textTransform: 'uppercase' }}>{label}</div>
      <div className="mono" style={{ color: '#E6ECF2', fontSize: 18, fontWeight: 700, marginTop: 2 }}>{value}</div>
    </div>
  );
}

function SignalToNoiseChart({ selectedId, onSelect }) {
  // Compute slope/variance for each station
  const rows = window.STATIONS.map((s, i) => {
    const d = s.annual;
    const n = d.length;
    const meanX = (n - 1) / 2;
    let meanY = 0; for (const x of d) meanY += x.anomaly; meanY /= n;
    let num = 0, den = 0;
    for (let j = 0; j < n; j++) { num += (j - meanX) * (d[j].anomaly - meanY); den += (j - meanX) ** 2; }
    const slope = num / den;
    // residual variance
    let rv = 0; for (let j = 0; j < n; j++) { const f = meanY + slope * (j - meanX); rv += (d[j].anomaly - f) ** 2; }
    rv = Math.sqrt(rv / n);
    const snr = (slope * 100) / rv;
    return { i, s, slope: slope * 100, noise: rv, snr };
  }).sort((a, b) => b.snr - a.snr);

  const maxSnr = Math.max(...rows.map(r => r.snr));

  return (
    <div style={{ border: '1px solid #1B2740', background: 'rgba(14,20,34,0.6)', padding: '20px 24px' }}>
      <div className="serif" style={{ fontSize: 18, color: '#E6ECF2' }}>Signal-to-noise ratio</div>
      <div className="mono" style={{ color: '#8BAFC7', fontSize: 11, marginTop: 4 }}>
        Trend (°F / century) divided by residual standard deviation. Higher = cleaner warming signal.
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 18 }}>
        {rows.map(r => {
          const active = r.s.id === selectedId;
          return (
            <button key={r.s.id} onClick={() => onSelect(r.i)} style={{
              background: 'transparent', border: 'none', textAlign: 'left', cursor: 'pointer', padding: 0,
              display: 'grid', gridTemplateColumns: '180px 1fr 60px 60px', gap: 12, alignItems: 'center',
            }}>
              <div className="serif" style={{ color: active ? '#C9A84C' : '#E6ECF2', fontSize: 14 }}>
                {r.s.name}, {r.s.state}
              </div>
              <div style={{ height: 8, background: '#0A0F1A', border: '1px solid #1B2740', position: 'relative' }}>
                <div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, width: `${(r.snr / maxSnr) * 100}%`,
                  background: active ? '#C9A84C' : 'linear-gradient(to right, #FDAE61, #D73027)' }} />
              </div>
              <div className="mono" style={{ color: '#8BAFC7', fontSize: 11 }}>+{r.slope.toFixed(2)}°</div>
              <div className="mono" style={{ color: '#C9A84C', fontSize: 11, fontWeight: 700, textAlign: 'right' }}>{r.snr.toFixed(2)}</div>
            </button>
          );
        })}
      </div>
    </div>
  );
}

Object.assign(window, { TabKeepers });
