/**
 * AJL40 Digital Series
 * © 2026 sultanmuzaffar. Hak cipta terpelihara / All rights reserved.
 * Penggunaan, penyalinan atau pengedaran tanpa kebenaran bertulis adalah dilarang.
 * Unauthorized use, copying or distribution is prohibited.
 */

// AJL 40 — Data Visualisation: Peta Bunyi Malaysia (Genre Constellation / galaksi)

const { useState: useStateDV, useRef: useRefDV, useEffect: useEffectDV } = React;

/* ============== SONIC MAP OF MALAYSIA — GENRE CONSTELLATION ============== */
// 9 genre disusun sebagai gugusan bunyi (galaksi) mengelilingi pusat "Pentas AJL".
// Pusat direka berkonsepkan galaksi: bintang teras, bulan dan planet.
const SONIC = {
  center: { label: "PUSAT GALAKSI", title: "Pentas AJL" },
  nodes: [
    { id: "irama", name: "Irama Malaysia", origin: "Akar tradisi", init: { x: 50, y: 15 },
      body: "Bukan sekadar kompang, rebana atau songket sebagai hiasan — ia gabungan lenggok Melayu, alat tradisional, bahasa dan naratif budaya. AJL mengangkatnya sebagai bunyi besar pentas arus perdana: tradisi yang elegan, dramatik dan kompetitif." },
    { id: "fusion", name: "World Fusion", origin: "Silang budaya", init: { x: 73, y: 22 },
      body: "Ruang pertemuan antara bunyi tempatan, Nusantara, Timur Tengah, Latin, India dan Barat — kerja susunan yang menuntut rasa, ilmu dan disiplin, bukan campuran rawak. AJL memberi ruang eksperimen silang budaya, membuktikan muzik Malaysia boleh menyerap dunia tanpa hilang akar." },
    { id: "indie", name: "Indie & Folk", origin: "Bandar besar", init: { x: 86, y: 44 },
      body: "Bunyi yang lebih intim dan jujur — kecil tetapi kuat dari segi penulisan, lirik dan identiti artis. AJL membuka ruang kepada singer-songwriter dan lagu cerita peribadi, menyeimbangkan budaya pentas besar dengan kejujuran karya." },
    { id: "rock", name: "Rock", origin: "1980an–90an", init: { x: 80, y: 68 },
      body: "Suara tenaga, pemberontakan dan emosi — gitar, distorsi, balada rock dan semangat generasi. AJL pernah menjadi ruang penting untuk rock memasuki ruang keluarga dan nasional; bukan sekadar jeritan tetapi melodi, struktur dan momen pentas yang melekat dalam ingatan." },
    { id: "balada", name: "Balada", origin: "Bahasa emosi", init: { x: 62, y: 84 },
      body: "Bahasa emosi utama muzik popular Malaysia — tempat rakyat menyimpan patah hati, harapan, doa dan rindu. AJL menjadikan balada bentuk paling dominan; banyak lagunya hidup lama sebagai arkib perasaan rakyat, sebuah pintu rahsia ke masa lalu." },
    { id: "rap", name: "Rap & Hip-Hop", origin: "Bahasa kota", init: { x: 38, y: 84 },
      body: "Bahasa kota, jalanan, anak muda, protes dan sindiran — seni ritma, naratif dan sikap, bukan sekadar laju bercakap. AJL membantu mengabsahkan rap sebagai sebahagian muzik popular Malaysia, membuktikan slang, punchline dan flow boleh membawa idea besar." },
    { id: "pop", name: "Pop & R&B", origin: "Bunyi urban moden", init: { x: 18, y: 68 },
      body: "Ruang bunyi moden: melodi mudah diingati, groove, vokal lentur dan produksi kontemporari. AJL memberi Pop/R&B ruang berkembang daripada pop radio kepada persembahan vokal dan formula digital yang lebih sofistikated, sambil mengekalkan rasa walau bergerak mengikut trend." },
    { id: "borneo", name: "Etnik Sabah & Sarawak", origin: "Bunyi Borneo", init: { x: 14, y: 44 },
      body: "Wilayah bunyi yang hidup — bahasa tempatan, instrumen, adat, sungai, rumah panjang dan pengalaman Borneo, bukan sekadar warna tambahan di pentas nasional. AJL boleh membuka telinga Semenanjung kepada Sabah dan Sarawak, membaca Borneo sebagai pintu rantau ke Kalimantan, Brunei dan kepulauan sekitarnya." },
    { id: "elek", name: "Elektronik & EDM", origin: "Pasca-2010", init: { x: 27, y: 22 },
      body: "Bahasa produksi moden: synth, beat programming, sampling, drop, sound design dan pengalaman visual digital. Telinga generasi muda dibentuk oleh platform, festival dan remix — genre ini membuka perbincangan tentang teknologi, AI, algoritma dan hak kreatif." },
  ],
};

// Warna tandatangan setiap genre — satu identiti warna yang konsisten
// merentasi Peta Bunyi (galaksi) dan Hubungan Antara Genre.
// Warna cerah pada latar gelap; teks kekal ivory supaya sentiasa terbaca.
const GENRE_COLORS = {
  irama:  '#E07850', // terracotta hangat — akar tradisi
  fusion: '#00B5D9', // cyan — silang budaya global
  indie:  '#8FD16A', // hijau lembut — intim, jujur
  rock:   '#E4564B', // merah tenaga — pemberontakan
  balada: '#F08FB8', // merah jambu — bahasa emosi
  rap:    '#F5A623', // amber — bahasa kota
  pop:    '#B58CF0', // ungu — urban moden
  borneo: '#2EC7A6', // teal — bunyi Borneo
  elek:   '#5B8DEF', // biru elektrik — EDM digital
};
const genreColorByName = (name) => {
  const n = SONIC.nodes.find(x => x.name === name);
  return n ? GENRE_COLORS[n.id] : '#C9A84C';
};

// Warna dekad — diselaraskan dengan tona warna ARKIB bagi setiap dekad.
const DECADE_ACCENTS = ['#E07850', '#D4B073', '#00B5D9', '#AC7AF3'];

// Bintang latar galaksi (koordinat tetap supaya render stabil).
const SONIC_STARS = [
  { x: 8, y: 12, s: 1.6, o: 0.55 }, { x: 18, y: 33, s: 1, o: 0.4 }, { x: 30, y: 9, s: 1.2, o: 0.5 },
  { x: 43, y: 40, s: 1, o: 0.35 }, { x: 62, y: 10, s: 1.4, o: 0.5 }, { x: 74, y: 34, s: 1, o: 0.4 },
  { x: 90, y: 16, s: 1.6, o: 0.55 }, { x: 94, y: 52, s: 1, o: 0.4 }, { x: 85, y: 74, s: 1.3, o: 0.5 },
  { x: 68, y: 60, s: 1, o: 0.3 }, { x: 54, y: 92, s: 1.4, o: 0.5 }, { x: 33, y: 88, s: 1, o: 0.4 },
  { x: 12, y: 78, s: 1.5, o: 0.5 }, { x: 6, y: 55, s: 1, o: 0.4 }, { x: 22, y: 60, s: 1.1, o: 0.35 },
  { x: 47, y: 6, s: 1, o: 0.4 }, { x: 78, y: 92, s: 1.1, o: 0.4 }, { x: 96, y: 88, s: 1, o: 0.35 },
];

function SonicMap() {
  const initial = {};
  SONIC.nodes.forEach(n => { initial[n.id] = { ...n.init }; });

  const [positions, setPositions] = useStateDV(initial);
  const [active, setActive] = useStateDV(null);
  const [dragId, setDragId] = useStateDV(null);
  const [narrow, setNarrow] = useStateDV(false);
  const boardRef = useRefDV(null);
  const drag = useRefDV(null);
  const justDragged = useRefDV(false);

  useEffectDV(() => {
    const onResize = () => setNarrow(window.innerWidth < 880);
    onResize();
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  const node = SONIC.nodes.find((n) => n.id === active);

  const onPointerDown = (e, id) => {
    const rect = boardRef.current.getBoundingClientRect();
    drag.current = { id, moved: false, rect, startX: e.clientX, startY: e.clientY };
    setDragId(id);
    try { e.currentTarget.setPointerCapture(e.pointerId); } catch (err) {}
  };
  const onPointerMove = (e) => {
    const ds = drag.current;
    if (!ds) return;
    // Ambang gerakan: pergerakan halus (<5px) dianggap ketikan (tap), bukan seretan.
    // Ini memastikan satu klik terus mendaftar tanpa perlu tekan berkali-kali.
    if (!ds.moved) {
      const dx = e.clientX - ds.startX;
      const dy = e.clientY - ds.startY;
      if (dx * dx + dy * dy < 25) return;
      ds.moved = true;
    }
    const rect = ds.rect;
    let x = ((e.clientX - rect.left) / rect.width) * 100;
    let y = ((e.clientY - rect.top) / rect.height) * 100;
    x = Math.max(7, Math.min(93, x));
    y = Math.max(8, Math.min(92, y));
    setPositions(p => ({ ...p, [ds.id]: { x, y } }));
  };
  const onPointerUp = (e, id) => {
    const ds = drag.current;
    justDragged.current = !!(ds && ds.moved);
    drag.current = null;
    setDragId(null);
  };
  const onNodeClick = (id) => {
    if (justDragged.current) { justDragged.current = false; return; }
    setActive(active === id ? null : id);
  };
  const resetBoard = () => { setPositions(initial); setActive(null); };

  return (
    <section className="ajl-sonic" id="dataviz-sonic">
      <div className="ajl-container">
        <div className="ajl-section__head">
          <div className="ajl-eyebrow">Visualisasi · Peta Bunyi Malaysia</div>
          <h2 className="ajl-section__title">
            <span>Satu galaksi bunyi,</span><br />
            <em className="ajl-section__title-em">sembilan genre mengorbit AJL.</em>
          </h2>
          <p className="ajl-section__lede">
            Bunyi Malaysia bukan satu genre. Ia sebuah <strong style={{ color: '#C9A84C', fontWeight: 600 }}>galaksi</strong> —
            sembilan gugusan tradisi, bandar, kepulauan dan generasi yang mengorbit pentas yang sama, kadang-kadang saling bertindih.
            <strong style={{ color: '#C9A84C', fontWeight: 600 }}> Seret</strong> mana-mana planet genre untuk meneroka, atau klik untuk membaca konteksnya.
          </p>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: narrow ? '1fr' : '1.35fr 1fr', gap: narrow ? '24px' : '48px', alignItems: 'start' }}>
          {/* Galaxy exploration board */}
          <div>
            <div ref={boardRef} style={{
              position: 'relative', width: '100%',
              height: 'clamp(380px, 56vw, 560px)',
              background: 'radial-gradient(circle at 50% 50%, rgba(201,168,76,0.12) 0%, rgba(58,44,92,0.22) 30%, rgba(20,16,30,0.35) 55%, #0E0D0B 85%)',
              border: '1px solid rgba(255,255,255,0.08)', borderRadius: '0.5rem',
              overflow: 'hidden', touchAction: 'none', userSelect: 'none'
            }}>
              {/* starfield */}
              {SONIC_STARS.map((st, i) => (
                <span key={'star' + i} style={{
                  position: 'absolute', left: st.x + '%', top: st.y + '%',
                  width: st.s + 'px', height: st.s + 'px', borderRadius: '50%',
                  background: '#F5F0E8', opacity: st.o,
                  boxShadow: '0 0 ' + (st.s * 2.5) + 'px rgba(245,240,232,0.7)',
                  pointerEvents: 'none'
                }} />
              ))}

              {/* orbits + connecting lines */}
              <svg viewBox="0 0 100 100" preserveAspectRatio="none" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>
                <circle cx="50" cy="50" r="22" fill="none" stroke="rgba(201,168,76,0.14)" strokeWidth="0.3" vectorEffect="non-scaling-stroke" />
                <circle cx="50" cy="50" r="33" fill="none" stroke="rgba(201,168,76,0.10)" strokeWidth="0.3" strokeDasharray="1.5 2" vectorEffect="non-scaling-stroke" />
                {SONIC.nodes.map(n => {
                  const p = positions[n.id];
                  const on = active === n.id;
                  const gc = GENRE_COLORS[n.id];
                  return <line key={n.id} x1="50" y1="50" x2={p.x} y2={p.y}
                    stroke={on ? gc : 'rgba(201,168,76,0.22)'} strokeWidth={on ? 0.6 : 0.3} vectorEffect="non-scaling-stroke" />;
                })}
              </svg>

              {/* galaxy center: star core + moon + planet */}
              <div style={{
                position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%,-50%)',
                width: 'clamp(96px,19%,138px)', aspectRatio: '1 / 1',
                display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
                textAlign: 'center', pointerEvents: 'none', zIndex: 2
              }}>
                {/* radiant star glow */}
                <div style={{
                  position: 'absolute', inset: '-40%', borderRadius: '50%',
                  background: 'radial-gradient(circle, rgba(201,168,76,0.55) 0%, rgba(201,168,76,0.18) 35%, transparent 70%)',
                  filter: 'blur(2px)'
                }} />
                {/* star core */}
                <div style={{
                  position: 'relative', width: '100%', aspectRatio: '1 / 1', borderRadius: '50%',
                  background: 'radial-gradient(circle at 38% 32%, #FBE9C0 0%, #E4C463 34%, #C9A84C 62%, #8A6E2A 100%)',
                  boxShadow: '0 0 26px rgba(201,168,76,0.65), inset 0 0 14px rgba(255,255,255,0.35)',
                  display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
                  padding: '8px'
                }}>
                  <div style={{ fontFamily: 'var(--f-label,monospace)', fontSize: '8px', fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: '#3A2C0E' }}>{SONIC.center.label}</div>
                  <div style={{ fontFamily: 'var(--f-heading,serif)', fontWeight: 800, fontSize: 'clamp(14px,2.3vw,21px)', lineHeight: 1, color: '#241B06', marginTop: '3px' }}>{SONIC.center.title}</div>
                </div>
                {/* moon */}
                <div style={{
                  position: 'absolute', top: '2%', right: '-6%',
                  width: '20%', aspectRatio: '1 / 1', borderRadius: '50%',
                  background: 'radial-gradient(circle at 35% 32%, #F5F0E8 0%, #C7C2B6 60%, #8F8A7E 100%)',
                  boxShadow: '0 0 10px rgba(245,240,232,0.5)'
                }} />
                {/* planet with ring */}
                <div style={{
                  position: 'absolute', bottom: '-2%', left: '-10%',
                  width: '26%', aspectRatio: '1 / 1', borderRadius: '50%',
                  background: 'radial-gradient(circle at 35% 30%, #7FA6C9 0%, #3D6FA0 55%, #244B72 100%)',
                  boxShadow: '0 0 10px rgba(63,111,160,0.5)'
                }}>
                  <div style={{
                    position: 'absolute', left: '-32%', top: '38%', width: '164%', height: '24%',
                    border: '1.5px solid rgba(201,168,76,0.7)', borderRadius: '50%',
                    transform: 'rotate(-22deg)'
                  }} />
                </div>
              </div>

              {/* draggable genre planets */}
              {SONIC.nodes.map(n => {
                const p = positions[n.id];
                const on = active === n.id;
                const dragging = dragId === n.id;
                const gc = GENRE_COLORS[n.id];
                return (
                  <button key={n.id}
                    onClick={() => onNodeClick(n.id)}
                    onPointerDown={(e) => onPointerDown(e, n.id)}
                    onPointerMove={onPointerMove}
                    onPointerUp={(e) => onPointerUp(e, n.id)}
                    style={{
                      position: 'absolute', left: p.x + '%', top: p.y + '%',
                      transform: 'translate(-50%,-50%)' + (dragging ? ' scale(1.06)' : ''),
                      width: 'clamp(96px, 22vw, 132px)',
                      background: on ? gc + '26' : 'rgba(18,18,20,0.86)',
                      border: '1.5px solid ' + (on ? gc : gc + '55'),
                      borderRadius: '0.5rem', padding: '10px 12px',
                      backdropFilter: 'blur(2px)',
                      cursor: dragging ? 'grabbing' : 'grab', textAlign: 'center',
                      display: 'flex', flexDirection: 'column', gap: '4px', alignItems: 'center',
                      color: '#F5F0E8',
                      boxShadow: dragging ? '0 12px 30px rgba(0,0,0,0.5)' : (on ? '0 0 22px ' + gc + '66' : '0 0 12px ' + gc + '1F'),
                      transition: dragging ? 'none' : 'background 0.2s, border-color 0.2s, box-shadow 0.2s, transform 0.15s',
                      zIndex: dragging ? 5 : 3, touchAction: 'none'
                    }}>
                    <span style={{ width: '18px', height: '3px', borderRadius: '999px', background: gc, opacity: on ? 1 : 0.85, pointerEvents: 'none' }} />
                    <div style={{ fontFamily: 'var(--f-label,monospace)', fontSize: '11px', fontWeight: 700, letterSpacing: '0.06em', textTransform: 'uppercase', color: on ? gc : '#F5F0E8', pointerEvents: 'none' }}>{n.name}</div>
                    <div style={{ fontFamily: 'var(--f-label,monospace)', fontSize: '9px', letterSpacing: '0.05em', color: 'rgba(245,240,232,0.5)', pointerEvents: 'none' }}>{n.origin}</div>
                  </button>
                );
              })}
            </div>

            {/* board controls */}
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '0.75rem', marginTop: '0.75rem', flexWrap: 'wrap' }}>
              <p style={{ fontFamily: 'var(--f-label,monospace)', fontSize: '10px', letterSpacing: '0.06em', color: 'rgba(255,255,255,0.4)', margin: 0 }}>
                Seret planet genre untuk menyusun semula galaksi bunyi anda.
              </p>
              <button onClick={resetBoard} style={{
                fontFamily: 'var(--f-label,monospace)', fontSize: '10px', letterSpacing: '0.12em', textTransform: 'uppercase',
                color: '#9B9B9B', background: 'transparent', border: '1px solid rgba(255,255,255,0.08)',
                borderRadius: '999px', padding: '0.4rem 0.8rem', cursor: 'pointer' }}>Susun Semula</button>
            </div>
          </div>

          {/* detail panel */}
          <aside className="ajl-sonic__detail" style={{ minHeight: narrow ? 'auto' : '240px' }}>
            {node ? (
              <>
                <div className="ajl-sonic__detail-eyebrow" style={{ color: GENRE_COLORS[node.id] }}>Bunyi · {node.origin}</div>
                <h3 className="ajl-sonic__detail-title" style={{ color: GENRE_COLORS[node.id] }}>{node.name}</h3>
                <p className="ajl-sonic__detail-body">{node.body}</p>
                <div className="ajl-sonic__detail-meta">
                  <span><strong>Asal usul</strong>{node.origin}</span>
                </div>
              </>
            ) : (
              <>
                <div className="ajl-sonic__detail-eyebrow">Peta Bunyi</div>
                <h3 className="ajl-sonic__detail-title">Pilih satu bunyi</h3>
                <p className="ajl-sonic__placeholder">
                  Setiap planet ialah satu bahasa muzikal yang membentuk galaksi "Bunyi Malaysia".
                  Seret untuk meneroka, klik untuk mendengar konteks dan sejarahnya.
                </p>
              </>
            )}
          </aside>
        </div>
      </div>
    </section>
  );
}

/* ============== GENRE CONNECTIONS — HUBUNGAN ANTARA GENRE ============== */
// Pasangan genre yang sering bertindih dalam lagu Malaysia (dari dokumen cadangan).
const SONIC_LINKS = [
  { a: "Irama Malaysia", b: "World Fusion", tag: "Tradisi + Global",
    body: "Tradisi yang diberi susunan global — lenggok Melayu dan alat tradisional bertemu produksi antarabangsa, tanpa hilang akar." },
  { a: "Balada", b: "Pop & R&B", tag: "Emosi + Urban",
    body: "Lagu cinta moden dengan vokal lentur — bahasa perasaan balada disusun semula dengan groove dan produksi kontemporari." },
  { a: "Rap & Hip-Hop", b: "Elektronik & EDM", tag: "Kota + Digital",
    body: "Bahasa kota, beat moden dan budaya digital — ritma jalanan bertemu synth, sampling dan sound design generasi platform." },
  { a: "Indie & Folk", b: "Balada", tag: "Intim + Peribadi",
    body: "Lirik peribadi, susunan minimal dan rasa intim — kejujuran singer-songwriter menemui bahasa emosi balada." },
  { a: "Etnik Sabah & Sarawak", b: "World Fusion", tag: "Wilayah + Rantau",
    body: "Bunyi wilayah sebagai jambatan serantau — instrumen dan bahasa Borneo menghubungkan Malaysia dengan Kalimantan, Brunei dan kepulauan sekitarnya." },
];

function GenreConnections() {
  const [open, setOpen] = useStateDV(0);
  return (
    <section className="ajl-sonic" id="dataviz-links" style={{ paddingTop: 0 }}>
      <div className="ajl-container">
        <div className="ajl-section__head">
          <div className="ajl-eyebrow">Hubungan Antara Genre</div>
          <h2 className="ajl-section__title">
            <span>Bunyi Malaysia jarang berdiri sendiri.</span><br />
            <em className="ajl-section__title-em">Ia bergerak antara galaksi.</em>
          </h2>
          <p className="ajl-section__lede">
            Lagu Malaysia sering bertindih antara genre — node dalam galaksi bunyi saling bertaut. Klik setiap pasangan untuk melihat bagaimana dua bunyi bertemu menjadi satu bahasa baharu.
          </p>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
          {SONIC_LINKS.map((lk, i) => {
            const on = open === i;
            const ca = genreColorByName(lk.a);
            const cb = genreColorByName(lk.b);
            return (
              <button key={i} onClick={() => setOpen(on ? -1 : i)} style={{
                textAlign: 'left', width: '100%', cursor: 'pointer', position: 'relative', overflow: 'hidden',
                background: on ? 'linear-gradient(120deg, ' + ca + '1A, ' + cb + '1A)' : 'rgba(20,20,22,0.6)',
                border: '1px solid ' + (on ? ca + '77' : 'rgba(201,168,76,0.20)'),
                borderRadius: '0.5rem', padding: 'clamp(14px,2.4vw,20px)',
                transition: 'background 0.2s, border-color 0.2s'
              }}>
                {/* jalur dua warna genre di tepi kiri */}
                <span style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: '4px', background: 'linear-gradient(180deg, ' + ca + ', ' + cb + ')', opacity: on ? 1 : 0.6 }} />
                <div style={{ display: 'flex', alignItems: 'center', gap: '10px', flexWrap: 'wrap', paddingLeft: '8px' }}>
                  <span style={{ fontFamily: 'var(--f-heading,serif)', fontWeight: 800, fontSize: 'clamp(15px,2.2vw,20px)', color: ca }}>{lk.a}</span>
                  <span style={{ color: 'var(--ivory-40,rgba(244,239,230,0.4))', fontSize: '18px', fontWeight: 700 }}>+</span>
                  <span style={{ fontFamily: 'var(--f-heading,serif)', fontWeight: 800, fontSize: 'clamp(15px,2.2vw,20px)', color: cb }}>{lk.b}</span>
                  <span style={{ marginLeft: 'auto', fontFamily: 'var(--f-label,monospace)', fontSize: '9px', fontWeight: 700, letterSpacing: '0.14em', textTransform: 'uppercase', color: on ? '#F5F0E8' : 'rgba(201,168,76,0.85)', background: on ? ca + '33' : 'transparent', border: '1px solid ' + (on ? ca + '88' : 'rgba(201,168,76,0.3)'), borderRadius: '999px', padding: '3px 10px' }}>{lk.tag}</span>
                </div>
                {on && (
                  <p style={{ margin: '12px 0 0', paddingLeft: '8px', fontFamily: 'var(--f-body,sans-serif)', fontSize: 'clamp(14px,1.7vw,16px)', lineHeight: 1.65, color: 'rgba(245,240,232,0.85)' }}>{lk.body}</p>
                )}
              </button>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* ============== DECADE EVOLUTION — EVOLUSI EMPAT DEKAD ============== */
const SONIC_DECADES = [
  { range: "1986–1995", era: "Pembentukan",
    genres: ["Balada", "Rock", "Pop awal", "Irama Malaysia mula menguat"],
    narrative: "Pembentukan identiti pop Malaysia dan memori ruang tamu — zaman AJL menjadi acara keluarga nasional, ketika balada dan rock membina tulang belakang emosi pentas." },
  { range: "1996–2005", era: "Kemegahan",
    genres: ["Irama Malaysia", "Pop & R&B", "World Fusion", "Balada besar"],
    narrative: "Zaman superstars, eksperimen, visual dan kemegahan pentas — Irama Malaysia memuncak, fusion silang budaya berkembang, dan persembahan menjadi tontonan besar." },
  { range: "2006–2015", era: "Gangguan Digital",
    genres: ["Indie", "Alternative", "Hip-Hop", "Singer-songwriter", "Pop moden"],
    narrative: "Revolusi digital, suara peribadi dan gangguan arus perdana — gelombang indie dan hip-hop membawa suara yang lebih kecil, jujur dan berasaskan cerita peribadi ke tengah." },
  { range: "2016–2025", era: "Global & Algoritma",
    genres: ["Pop digital", "EDM", "Hip-Hop", "Performance art", "Fusion kontemporari"],
    narrative: "Visual besar, algoritma, global sound dan pencarian keaslian — telinga generasi dibentuk oleh platform dan festival, sambil terus mencari bunyi yang benar-benar Malaysia." },
];

function DecadeEvolution() {
  const [sel, setSel] = useStateDV(0);
  const d = SONIC_DECADES[sel];
  const accent = DECADE_ACCENTS[sel];
  return (
    <section className="ajl-sonic" id="dataviz-decades" style={{ paddingTop: 0 }}>
      <div className="ajl-container">
        <div className="ajl-section__head">
          <div className="ajl-eyebrow">Evolusi Empat Dekad</div>
          <h2 className="ajl-section__title">
            <span>Galaksi bunyi berputar</span><br />
            <em className="ajl-section__title-em">mengikut zamannya.</em>
          </h2>
          <p className="ajl-section__lede">
            Setiap dekad mengangkat gugusan genre yang berbeza. Pilih satu tempoh untuk melihat bunyi dominan dan naratif zamannya.
          </p>
        </div>

        {/* timeline selector */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))', gap: '8px', marginBottom: '24px' }}>
          {SONIC_DECADES.map((dd, i) => {
            const on = sel === i;
            const ac = DECADE_ACCENTS[i];
            return (
              <button key={i} onClick={() => setSel(i)} style={{
                cursor: 'pointer', textAlign: 'center', position: 'relative', overflow: 'hidden',
                background: on ? ac + '22' : 'rgba(20,20,22,0.6)',
                border: '1.5px solid ' + (on ? ac : ac + '40'),
                borderRadius: '0.5rem', padding: '12px 8px 10px',
                boxShadow: on ? '0 0 18px ' + ac + '3A' : 'none',
                transition: 'background 0.2s, border-color 0.2s, box-shadow 0.2s'
              }}>
                <span style={{ position: 'absolute', left: 0, right: 0, top: 0, height: '3px', background: ac, opacity: on ? 1 : 0.55 }} />
                <div style={{ fontFamily: 'var(--f-label,monospace)', fontSize: '12px', fontWeight: 700, letterSpacing: '0.04em', color: on ? ac : '#F5F0E8' }}>{dd.range}</div>
                <div style={{ fontFamily: 'var(--f-label,monospace)', fontSize: '9px', letterSpacing: '0.08em', textTransform: 'uppercase', marginTop: '3px', color: on ? ac : 'rgba(245,240,232,0.5)' }}>{dd.era}</div>
              </button>
            );
          })}
        </div>

        {/* selected decade detail */}
        <div style={{
          background: 'radial-gradient(circle at 12% 20%, ' + accent + '1F, transparent 55%), rgba(20,20,22,0.55)',
          border: '1px solid ' + accent + '4D', borderRadius: '0.5rem',
          boxShadow: '0 0 32px ' + accent + '1A', padding: 'clamp(18px,3vw,32px)',
          transition: 'background 0.3s, border-color 0.3s'
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
            <span style={{ width: '22px', height: '4px', borderRadius: '999px', background: accent }} />
            <div style={{ fontFamily: 'var(--f-label,monospace)', fontSize: '10px', fontWeight: 700, letterSpacing: '0.18em', textTransform: 'uppercase', color: accent }}>{d.range} · {d.era}</div>
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', margin: '14px 0 18px' }}>
            {d.genres.map((g, i) => (
              <span key={i} style={{
                fontFamily: 'var(--f-label,monospace)', fontSize: '11px', letterSpacing: '0.04em',
                color: '#F5F0E8', background: accent + '1F',
                border: '1px solid ' + accent + '66', borderRadius: '999px', padding: '5px 12px'
              }}>{g}</span>
            ))}
          </div>
          <p style={{ margin: 0, fontFamily: 'var(--f-body,sans-serif)', fontSize: 'clamp(15px,1.9vw,18px)', lineHeight: 1.7, color: 'rgba(245,240,232,0.86)', maxWidth: '60ch' }}>{d.narrative}</p>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { SonicMap, GenreConnections, DecadeEvolution });
