// 03 · The Fronts — geographic + temporal pattern, US map.

function TabFronts() {
  const [decIdx, setDecIdx] = React.useState(window.DECADES.length - 1);
  const [mode, setMode] = React.useState('anomaly'); // 'anomaly' | 'clusters'
  const [playing, setPlaying] = React.useState(false);
  const [activeCluster, setActiveCluster] = React.useState(null);

  React.useEffect(() => {
    if (!playing) return;
    const t = setInterval(() => {
      setDecIdx(i => (i + 1) % window.DECADES.length);
    }, 900);
    return () => clearInterval(t);
  }, [playing]);

  const decade = window.DECADES[decIdx];

  return (
    <div style={{ padding: '32px 56px 80px' }}>
      <Eyebrow id="03 · THE FRONTS"
        title="Where the anomalies fall, and when they cluster into something larger."
        right="Spatial · M2 HDBSCAN clustering" />

      {/* Mode toggle */}
      <div style={{ display: 'flex', gap: 1, marginBottom: 20, background: '#1B2740', border: '1px solid #1B2740', width: 'fit-content' }}>
        {[
          { id: 'anomaly', label: 'Decadal anomaly map' },
          { id: 'clusters', label: 'Extreme-event clusters' },
        ].map(m => (
          <button key={m.id} onClick={() => setMode(m.id)} className="mono" style={{
            background: mode === m.id ? '#C9A84C' : 'var(--bg-2)',
            color: mode === m.id ? '#0A0F1A' : '#8BAFC7',
            border: 'none', padding: '10px 18px', cursor: 'pointer',
            fontSize: 11, letterSpacing: 0.2, textTransform: 'uppercase',
            fontFamily: "'Space Mono', monospace", fontWeight: mode === m.id ? 700 : 400,
          }}>
            {m.label}
          </button>
        ))}
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1.65fr 1fr', gap: 24 }}>
        {/* MAP */}
        <div style={{ border: '1px solid #1B2740', background: 'rgba(14,20,34,0.6)' }}>
          <div style={{ padding: '18px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <div>
              <div className="serif" style={{ fontSize: 19, color: '#E6ECF2', letterSpacing: -0.2 }}>
                {mode === 'anomaly'
                  ? `Decadal mean anomaly — ${decade.label}`
                  : `Notable extreme-event clusters — 1900–2025`}
              </div>
              <div className="mono" style={{ color: '#8BAFC7', fontSize: 11, marginTop: 4 }}>
                {mode === 'anomaly'
                  ? 'Each dot = a long-record GHCN station. Color encodes deviation from baseline.'
                  : `${window.EVENT_CLUSTERS.length} clusters · co-occurring all-time extremes`}
              </div>
            </div>
            <TempLegend width={220} />
          </div>

          <USMap mode={mode} decade={decade} activeCluster={activeCluster} setActiveCluster={setActiveCluster} />

          {/* Time scrubber */}
          {mode === 'anomaly' && (
            <div style={{ padding: '12px 24px 20px', borderTop: '1px solid #1B2740' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                <button onClick={() => setPlaying(p => !p)} className="mono" style={{
                  background: 'transparent', color: '#C9A84C', border: '1px solid #C9A84C',
                  padding: '6px 12px', fontSize: 10, letterSpacing: 0.2, textTransform: 'uppercase',
                  cursor: 'pointer', fontFamily: "'Space Mono', monospace", minWidth: 70,
                }}>
                  {playing ? '■ pause' : '▶ play'}
                </button>
                <div style={{ flex: 1, position: 'relative', height: 32 }}>
                  <div style={{ position: 'absolute', top: 14, left: 0, right: 0, height: 4, background: '#1B2740' }} />
                  <div style={{ position: 'absolute', top: 14, left: 0, height: 4, width: `${(decIdx / (window.DECADES.length - 1)) * 100}%`,
                    background: 'linear-gradient(to right, #2166AC, #F7F7F7 50%, #D73027)' }} />
                  {window.DECADES.map((d, i) => (
                    <button key={d.label} onClick={() => setDecIdx(i)} style={{
                      position: 'absolute',
                      left: `calc(${(i / (window.DECADES.length - 1)) * 100}% - 5px)`,
                      top: 11, width: 10, height: 10, borderRadius: '50%',
                      background: i === decIdx ? '#C9A84C' : '#243353',
                      border: i === decIdx ? '2px solid #0A0F1A' : 'none',
                      cursor: 'pointer', padding: 0,
                    }} />
                  ))}
                  <div style={{ position: 'absolute', top: 26, left: 0, right: 0, display: 'flex', justifyContent: 'space-between' }}>
                    {window.DECADES.map(d => (
                      <span key={d.label} className="mono" style={{ color: '#4E6A82', fontSize: 9 }}>
                        {d.label.slice(0, 2)}s
                      </span>
                    ))}
                  </div>
                </div>
                <div className="mono" style={{ color: '#C9A84C', fontSize: 14, minWidth: 90, textAlign: 'right', fontWeight: 700 }}>
                  {decade.label}
                </div>
              </div>
            </div>
          )}
        </div>

        {/* Sidebar */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          {mode === 'anomaly' ? <DecadeBrief decade={decade} /> : <ClusterDetail c={activeCluster ?? window.EVENT_CLUSTERS[4]} />}
        </div>
      </div>

      {/* Cluster list */}
      {mode === 'clusters' && (
        <div style={{ marginTop: 32 }}>
          <div className="mono" style={{ color: '#4E6A82', fontSize: 10, letterSpacing: 0.2, textTransform: 'uppercase', marginBottom: 12 }}>
            ▌ EVENT INDEX
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 1, background: '#1B2740', border: '1px solid #1B2740' }}>
            {window.EVENT_CLUSTERS.map(c => (
              <button key={c.label} onClick={() => setActiveCluster(c)} style={{
                background: activeCluster?.label === c.label ? 'rgba(201,168,76,0.08)' : 'var(--bg-2)',
                border: 'none', textAlign: 'left', padding: '14px 16px', cursor: 'pointer',
                display: 'flex', flexDirection: 'column', gap: 4,
              }}>
                <div className="mono" style={{ color: c.kind === 'hot' ? '#D73027' : '#74ADD1', fontSize: 10, letterSpacing: 0.15 }}>
                  {c.date.toUpperCase()} · {c.stations} STATIONS
                </div>
                <div className="serif" style={{ color: '#E6ECF2', fontSize: 15 }}>{c.label}</div>
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

function DecadeBrief({ decade }) {
  const briefs = {
    '1900s': 'Sparse but consistent. The instrumental record finds its footing.',
    '1910s': 'A cool decade across most of the continent. The Great War summers run mild.',
    '1920s': 'A return toward the baseline. Florida real-estate boom on the back of mild winters.',
    '1930s': 'The Dust Bowl. The hottest decade on the Plains in the entire record — until the 2010s.',
    '1940s': 'WWII-era. Above baseline in the early years, drifting cool by decade\'s end.',
    '1950s': 'A mid-century pause. Aerosols mute the surface warming signal.',
    '1960s': 'The coldest decade since 1900. Northern stations notably below baseline.',
    '1970s': 'Lingering cool. The decade Time magazine asked if a new ice age was coming.',
    '1980s': 'The inflection. The warming trend that has not yet stopped begins here.',
    '1990s': 'Heat creeps in from the coasts. 1998 a clear above-baseline year.',
    '2000s': 'Western warming intensifies. Drought returns to the Plains.',
    '2010s': 'A decade above baseline at every long-record station. None below.',
    '2020s': 'Acceleration. 2024 the warmest year in the continental record.',
  };
  return (
    <>
      <div style={{ border: '1px solid #1B2740', background: 'rgba(14,20,34,0.6)', padding: 24 }}>
        <Tick color="#C9A84C">▌ BRIEF · {decade.label.toUpperCase()}</Tick>
        <div className="mono" style={{ color: window.anomalyColor(decade.bias), fontSize: 56, fontWeight: 700, marginTop: 10, lineHeight: 1, letterSpacing: -1 }}>
          {decade.bias > 0 ? '+' : ''}{decade.bias.toFixed(1)}°
        </div>
        <div className="mono" style={{ color: '#8BAFC7', fontSize: 11, marginTop: 6 }}>
          decadal mean anomaly vs 1900–1950
        </div>
        <div className="serif" style={{ color: '#E6ECF2', fontSize: 15, marginTop: 22, lineHeight: 1.55, textWrap: 'pretty' }}>
          {briefs[decade.label]}
        </div>
      </div>
      <div style={{ border: '1px solid #1B2740', background: 'rgba(14,20,34,0.6)', padding: 24 }}>
        <Tick>▌ COMPARED TO TODAY</Tick>
        <CompareBars now={2.6} then={decade.bias} />
      </div>
    </>
  );
}

function CompareBars({ now, then }) {
  const max = 3.0;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14, marginTop: 14 }}>
      {[
        { label: `${then >= 0 ? '+' : ''}${then.toFixed(1)}° · the decade`, value: then, color: window.anomalyColor(then) },
        { label: `+${now.toFixed(1)}° · 2020s`, value: now, color: window.anomalyColor(now) },
      ].map((r, i) => (
        <div key={i}>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <span className="mono" style={{ color: '#8BAFC7', fontSize: 11 }}>{r.label}</span>
          </div>
          <div style={{ height: 8, background: '#0A0F1A', border: '1px solid #1B2740', marginTop: 6, position: 'relative' }}>
            <div style={{
              position: 'absolute', top: 0, bottom: 0,
              left: r.value < 0 ? `${50 + (r.value / max) * 50}%` : '50%',
              width: `${Math.abs(r.value) / max * 50}%`, background: r.color,
            }} />
            <div style={{ position: 'absolute', top: -2, bottom: -2, left: '50%', width: 1, background: '#8BAFC7' }} />
          </div>
        </div>
      ))}
    </div>
  );
}

function ClusterDetail({ c }) {
  return (
    <div style={{ border: '1px solid #1B2740', background: 'rgba(14,20,34,0.6)', padding: 24 }}>
      <Tick color={c.kind === 'hot' ? '#D73027' : '#74ADD1'}>▌ CLUSTER · {c.date.toUpperCase()}</Tick>
      <div className="serif" style={{ fontSize: 24, color: '#E6ECF2', marginTop: 10, lineHeight: 1.2 }}>{c.label}</div>
      <div style={{ display: 'flex', gap: 24, marginTop: 18, paddingTop: 16, borderTop: '1px solid #1B2740' }}>
        <Stat label="STATIONS IN CLUSTER" value={c.stations} color="#E6ECF2" mono />
        <Stat label="COHERENCE" value={`${(c.magnitude * 100).toFixed(0)}%`} color="#C9A84C" mono />
        <Stat label="TYPE" value={c.kind.toUpperCase()} color={c.kind === 'hot' ? '#D73027' : '#74ADD1'} mono />
      </div>
      <div className="serif" style={{ color: '#8BAFC7', fontSize: 14, marginTop: 18, lineHeight: 1.55 }}>
        {c.desc}
      </div>
      <div style={{ marginTop: 18 }}>
        <Confidence level="high" />
      </div>
    </div>
  );
}

function USMap({ mode, decade, activeCluster, setActiveCluster }) {
  // Use the Wikimedia Albers projection viewBox: 959 x 593
  const W = 959, H = 593;
  const field = React.useMemo(() => window.decadeField(decade, decade.year), [decade]);

  // Map grid points from 0..1 space to the actual SVG coordinates
  // The continental US in this projection spans roughly x:60..920, y:30..520
  const mapX = (nx) => 60 + nx * 860;
  const mapY = (ny) => 30 + ny * 490;

  return (
    <div style={{ position: 'relative', background: 'rgba(10,15,26,0.4)', overflow: 'hidden' }}>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ display: 'block', width: '100%', height: 'auto' }}>
        {/* State boundaries */}
        <g>
          {(window.US_STATE_PATHS || []).map((d, i) => (
            <path key={i} d={d} fill="rgba(139,175,199,0.04)" stroke="#243353" strokeWidth="0.5" />
          ))}
        </g>

        {/* Anomaly dots */}
        {mode === 'anomaly' && field.map((p, i) => (
          <g key={i}>
            <circle cx={mapX(p.x)} cy={mapY(p.y)} r={8}
              fill={window.anomalyColor(p.v)} opacity="0.92"
              stroke="#0A0F1A" strokeWidth="0.8" />
          </g>
        ))}

        {/* Clusters */}
        {mode === 'clusters' && window.EVENT_CLUSTERS.map(c => {
          const r = 22 + c.magnitude * 34;
          const fill = c.kind === 'hot' ? '#D73027' : '#74ADD1';
          const isActive = activeCluster?.label === c.label;
          return (
            <g key={c.label} onClick={() => setActiveCluster(c)} style={{ cursor: 'pointer' }}>
              <circle cx={mapX(c.x)} cy={mapY(c.y)} r={r} fill={fill} opacity="0.10" />
              <circle cx={mapX(c.x)} cy={mapY(c.y)} r={r * 0.6} fill={fill} opacity="0.18" />
              <circle cx={mapX(c.x)} cy={mapY(c.y)} r={5} fill={fill} />
              {isActive && (
                <circle cx={mapX(c.x)} cy={mapY(c.y)} r={r + 5} fill="none" stroke="#C9A84C" strokeWidth="1.2" />
              )}
              <text x={mapX(c.x)} y={mapY(c.y) - r - 8} textAnchor="middle"
                className="mono" fill={isActive ? '#C9A84C' : '#E6ECF2'} fontSize="11"
                fontFamily="Space Mono" letterSpacing="0.05">
                {c.date.toUpperCase()}
              </text>
            </g>
          );
        })}

        {/* Compass */}
        <g transform={`translate(${W - 60}, ${H - 50})`}>
          <circle cx="0" cy="0" r="18" fill="none" stroke="#243353" strokeWidth="0.6" />
          <line x1="0" y1="-18" x2="0" y2="18" stroke="#243353" strokeWidth="0.6" />
          <line x1="-18" y1="0" x2="18" y2="0" stroke="#243353" strokeWidth="0.6" />
          <text y="-24" textAnchor="middle" className="mono" fill="#4E6A82" fontSize="10" fontFamily="Space Mono">N</text>
        </g>
      </svg>
    </div>
  );
}

Object.assign(window, { TabFronts });
