/* global React, TweaksPanel, TweakSection, TweakColor, TweakToggle, TweakRadio, useTweaks */

// ────────────────────────────────────────────────────────────
// Links / constants
// ────────────────────────────────────────────────────────────
const LINKS = {
  spotifyArtist: 'https://open.spotify.com/intl-es/artist/2F9rcWekYI9RO47ndYMFap?si=2NaoXXaWT0yJ4eo_ZINkbQ',
  spotifyAlbum: 'https://open.spotify.com/intl-es/album/41pCS4YoENI0deqV2aTRAj',
  playlist: 'https://open.spotify.com/playlist/2IW5PWWRMZ8w0tkY0kLJ79',
  soundcloud: 'https://soundcloud.com/sigmahz',
  mixcloud: 'https://www.mixcloud.com/Sigmahz/',
  instagram: 'https://www.instagram.com/sigmahz.music/',
  booking: 'mailto:sigmahz.music@gmail.com',
  bookingEmail: 'sigmahz.music@gmail.com'
};

// ────────────────────────────────────────────────────────────
// Discography — reverse chronological. Years are placeholder
// estimates pending user confirmation; only the LATEST tag is
// hard-set on Dreams.
// ────────────────────────────────────────────────────────────
const RELEASES = [
{
  id: 'dreams',
  title: 'Dreams EP',
  label: 'Self-released',
  art: 'assets/dreams-ep.png',
  spotify: 'https://open.spotify.com/intl-es/album/41pCS4YoENI0deqV2aTRAj',
  badge: 'Latest'
},
{
  id: 'aether',
  title: 'Aether EP',
  label: 'Self-released',
  art: 'assets/aether.jpg',
  spotify: 'https://open.spotify.com/album/7d9txuSycha98TuKyvGkFc'
},
{
  id: 'night-ritual',
  title: 'Night Ritual',
  label: 'Self-released',
  art: 'assets/night-ritual.jpg',
  spotify: 'https://open.spotify.com/album/2jaJclT5uWQ4XTZUrlls6y'
},
{
  id: 'machine-learning',
  title: 'Machine Learning EP',
  label: 'Self-released',
  art: 'assets/machine-learning.jpg',
  spotify: 'https://open.spotify.com/album/1dIBzJ7GD4Qzabmv9rWMWK'
},
{
  id: 'entrance',
  title: 'Entrance EP',
  label: 'UXOA DUTXA ELITE',
  art: 'assets/entrance.jpg',
  spotify: 'https://open.spotify.com/album/5yLfWftK96x2PQM2GpM5bJ'
},
{
  id: 'color-out-of-space',
  title: 'The Color Out of Space',
  label: 'Self-released',
  art: 'assets/color-out-of-space.jpg',
  spotify: 'https://open.spotify.com/album/4VnOGvkZ7aulSsNhBbDxdx'
},
{
  id: 'space-odyssey',
  title: 'Space Odyssey EP',
  label: 'UXOA DUTXA ELITE',
  art: 'assets/space-odyssey.jpg',
  spotify: 'https://open.spotify.com/album/0ixcYXDSu72W29DEH8XUwf'
}];


// Latest album embed (Dreams EP) for the music section
const ALBUM_EMBED = 'https://open.spotify.com/embed/album/41pCS4YoENI0deqV2aTRAj?utm_source=generator&theme=0';
// Persistent dock = full catalogue playlist
const PLAYLIST_EMBED = 'https://open.spotify.com/embed/playlist/2IW5PWWRMZ8w0tkY0kLJ79?utm_source=generator&theme=0';

// Mixcloud widget for the latest set
const MIXCLOUD_LATEST = 'https://www.mixcloud.com/widget/iframe/?hide_cover=1&light=0&feed=%2FSigmahz%2Fresonate-together-episode-2%2F';
const MIXCLOUD_LATEST_TITLE = 'Resonate Together · Episode 2';

const BIO_ES = "Sigmahz es una fórmula — Σ (sigma) + Hz (hertz): la sumatoria de frecuencias. El sonido se abre en lo vasto y lo atmosférico — melodic techno, melodic house, progressive house — ritmos profundos que se disuelven en espacio inmersivo. A medida que las frecuencias se acumulan, algo nuevo toma forma. La Σ no se detiene.";

const BIO_EN = "Sigmahz is a formula — Σ (sigma) + Hz (hertz): the summation of frequencies. The sound opens in the vast and the atmospheric — melodic techno, melodic house, progressive house — deep rhythms dissolving into immersive space. As frequencies accumulate, something new takes shape. The Σ never stops.";

// ────────────────────────────────────────────────────────────
// Tiny SVG icons
// ────────────────────────────────────────────────────────────
const I = {
  play: <svg width="10" height="12" viewBox="0 0 10 12" fill="currentColor"><path d="M1 1l8 5-8 5V1z" /></svg>,
  arrow: <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.4"><path d="M3 11L11 3M5 3h6v6" /></svg>,
  spotify: <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.6 14.4c-.2.3-.6.4-.9.2-2.4-1.5-5.5-1.8-9.1-1-.4.1-.7-.2-.8-.5-.1-.4.2-.7.5-.8 3.9-.9 7.4-.5 10.1 1.2.3.2.4.6.2.9zm1.2-2.7c-.3.3-.7.4-1.1.2-2.8-1.7-7-2.2-10.3-1.2-.4.1-.9-.1-1-.5-.1-.4.1-.9.5-1 3.8-1.1 8.5-.6 11.7 1.4.4.2.5.7.2 1.1zm.1-2.8C14.6 9 8.5 8.8 5.3 9.8c-.5.2-1.1-.1-1.2-.6-.2-.5.1-1.1.6-1.2 3.7-1.1 10.4-.9 14.3 1.4.5.3.6.9.4 1.4-.3.4-1 .6-1.5.3z" /></svg>,
  soundcloud: <svg width="18" height="14" viewBox="0 0 18 14" fill="currentColor"><path d="M1 8v4M2.5 6v6M4 5.5v6.5M5.5 6v6M7 4v8M8.5 3v9M10 2.5v9.5M11.5 4v8M13 5v7" /><path d="M14 5a3 3 0 013 3v1a3 3 0 01-3 3h-1V5h1z" /></svg>,
  mixcloud: <svg width="20" height="12" viewBox="0 0 20 12" fill="currentColor"><circle cx="3" cy="6" r="2" /><circle cx="7" cy="6" r="2.5" /><circle cx="12" cy="6" r="3" /><circle cx="17" cy="6" r="2" /></svg>,
  instagram: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8"><rect x="3" y="3" width="18" height="18" rx="4" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="0.5" fill="currentColor" /></svg>
};

// ────────────────────────────────────────────────────────────
// Star field — generated once, lots of tiny dots
// ────────────────────────────────────────────────────────────
function Stars() {
  const stars = React.useMemo(() => {
    const rng = (() => {let s = 12345;return () => (s = (s * 9301 + 49297) % 233280) / 233280;})();
    return Array.from({ length: 120 }).map(() => ({
      x: rng() * 100,
      y: rng() * 100,
      r: 0.4 + rng() * 1.2,
      o: 0.3 + rng() * 0.7,
      tw: rng() * 4
    }));
  }, []);
  return (
    <svg className="hero-stars" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
      {stars.map((s, i) =>
      <circle key={i} cx={s.x} cy={s.y} r={s.r * 0.06}
      fill="#cfd8ff" opacity={s.o}>
          <animate attributeName="opacity"
        values={`${s.o};${s.o * 0.3};${s.o}`}
        dur={`${3 + s.tw}s`}
        repeatCount="indefinite" />
        </circle>
      )}
    </svg>);

}

// ────────────────────────────────────────────────────────────
// Scroll-reveal — IntersectionObserver toggles .in
// ────────────────────────────────────────────────────────────
function Reveal({ children, delay = 0, as: As = 'div', ...rest }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          setTimeout(() => e.target.classList.add('in'), delay);
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.18 });
    io.observe(el);
    return () => io.disconnect();
  }, [delay]);
  return <As ref={ref} className="reveal" {...rest}>{children}</As>;
}

// ────────────────────────────────────────────────────────────
// Nav
// ────────────────────────────────────────────────────────────
function Nav() {
  return (
    <nav className="nav">
      <a href="#top" className="mark" aria-label="Sigmahz home">
        <img src="assets/sigmahz-wordmark.png" alt="Sigmahz" />
      </a>
      <ul>
        <li><a href="#music">Music</a></li>
        <li><a href="#mixes">Mixes</a></li>
        <li><a href="#about">About</a></li>
        <li><a href={LINKS.booking} className="nav-cta">Book ↗</a></li>
      </ul>
    </nav>);

}

// ────────────────────────────────────────────────────────────
// Hero
// ────────────────────────────────────────────────────────────
function Hero() {
  return (
    <section className="hero" id="top" data-screen-label="Hero">
      <div className="hero-bg"></div>
      <Stars />
      <div className="hero-horizon"></div>

      <div className="hero-grid">
        <div>
          <div className="eyebrow"><span className="dot"></span>Producer &amp; DJ · Atlanta, GA · Out now: Dreams EP</div>
          <h1 className="hero-name" aria-label="Sigmahz">
            <img src="assets/sigmahz-wordmark.png" alt="Sigmahz" />
          </h1>
          <div className="hero-tag">
            <span>Melodic House &amp; Techno</span><span className="pipe">/</span>
            <span>Progressive House</span><span className="pipe">/</span>
            <span>Indie Dance</span><span className="pipe">/</span>
            <span>Deep House</span>
          </div>
        </div>

        <a href={LINKS.spotifyAlbum} target="_blank" rel="noopener" className="portal" aria-label="Listen to Dreams EP on Spotify">
          <img src="assets/dreams-ep.png" alt="Dreams EP cover" />
          <div className="portal-tag">
            <span>Dreams EP</span>
            <span className="out">Out Now</span>
          </div>
        </a>
      </div>

      <div className="hero-meta">
        <span>Mérida, MX → Atlanta, GA</span>
        <span className="scroll-cue">Scroll <span className="down">↓</span></span>
        <span>© MMXXVI</span>
      </div>
    </section>);

}

// ────────────────────────────────────────────────────────────
// Latest Release
// ────────────────────────────────────────────────────────────
function Latest() {
  return (
    <section className="section" id="music" data-screen-label="Latest Release">
      <div className="section-inner">
        <Reveal>
          <div className="section-header">
            <div>
              <div className="eyebrow"><span className="dot"></span>01 — Latest Release</div>
              <h2 className="h-section" style={{ marginTop: 14 }}>Step through.</h2>
            </div>
            <span className="meta">2026 / 001</span>
          </div>
        </Reveal>

        <div className="release">
          <Reveal>
            <div className="release-art release-art-embed">
              <iframe
                src={ALBUM_EMBED}
                title="Dreams EP on Spotify"
                allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
                loading="lazy" />
              
            </div>
          </Reveal>

          <Reveal delay={120}>
            <div className="release-info">
              <span className="stamp"><span style={{ width: 6, height: 6, borderRadius: '50%', background: 'currentColor', boxShadow: '0 0 8px currentColor' }}></span>OUT NOW</span>
              <h3>Dreams<br />EP.</h3>

              <div className="meta-row">
                <div><span className="k">Released</span><span className="v">2026</span></div>
                <div><span className="k">Label</span><span className="v">Self-released</span></div>
                <div><span className="k">Format</span><span className="v">Digital · EP</span></div>
              </div>

              <p className="lede" style={{ marginTop: 24 }}>
                Four tracks tracing the shape of a dream — melodic house &amp; techno meeting downtempo textures, analog warmth, the quiet space between sleep and motion.
              </p>

              <div className="platform-buttons">
                <a className="pbtn primary" href={LINKS.spotifyAlbum} target="_blank" rel="noopener">
                  <span className="icon">{I.spotify}</span> Open on Spotify
                </a>
                <a className="pbtn" href={LINKS.soundcloud} target="_blank" rel="noopener">
                  <span className="icon">{I.soundcloud}</span> Soundcloud
                </a>
              </div>
            </div>
          </Reveal>
        </div>
      </div>
    </section>);

}

// ────────────────────────────────────────────────────────────
// Discography
// ────────────────────────────────────────────────────────────
function Discography() {
  return (
    <section className="section" data-screen-label="Discography" style={{ borderTop: '1px solid var(--line)' }}>
      <div className="section-inner">
        <Reveal>
          <div className="section-header">
            <div>
              <div className="eyebrow"><span className="dot"></span>02 — Discography</div>
              <h2 className="h-section" style={{ marginTop: 14 }}>Catalogue.</h2>
            </div>
            <span className="meta">{RELEASES.length} releases · more incoming</span>
          </div>
        </Reveal>

        <Reveal>
          <div className="discog">
            {RELEASES.map((r) =>
            <a className="disc-card" key={r.id} href={r.spotify} target="_blank" rel="noopener">
                <div className="art">
                  {r.badge &&
                <span className={'badge' + (r.badge === 'Latest' ? '' : ' subtle')}>{r.badge}</span>
                }
                  {r.art ?
                <img src={r.art} alt={r.title} /> :

                <div className="art-pending">
                      <div className="art-pending-inner">
                        <span className="glyph">◷</span>
                        cover<br />on spotify
                      </div>
                    </div>
                }
                </div>
                <div className="title">{r.title}</div>
                <div className="sub">{r.label}</div>
              </a>
            )}

            {/* Teaser: forthcoming label release — Warp Drive on UXOA DUTXA ELITE */}
            <a className="disc-card disc-teaser" href={LINKS.instagram} target="_blank" rel="noopener">
              <div className="art teaser-art">
                <div className="teaser-inner">
                  <span className="teaser-eyebrow">June 18 · 2026</span>
                  <span className="teaser-glyph">◷</span>
                  <span className="teaser-foot">uxoa dutxa elite</span>
                </div>
              </div>
              <div className="title">Warp Drive</div>
              <div className="sub">Coming soon · follow @sigmahz.music</div>
            </a>
          </div>
        </Reveal>
      </div>
    </section>);

}

// ────────────────────────────────────────────────────────────
// Mixes
// ────────────────────────────────────────────────────────────
function Mixes() {
  // bar heights — deterministic pseudo-waveform
  const bars = React.useMemo(() => {
    const rng = (() => {let s = 99;return () => (s = (s * 9301 + 49297) % 233280) / 233280;})();
    return Array.from({ length: 56 }).map(() => 18 + rng() * 46);
  }, []);

  return (
    <section className="section" id="mixes" data-screen-label="Mixes" style={{ borderTop: '1px solid var(--line)' }}>
      <div className="section-inner">
        <Reveal>
          <div className="section-header">
            <div>
              <div className="eyebrow"><span className="dot"></span>03 — Mixes &amp; Radio</div>
              <h2 className="h-section" style={{ marginTop: 14 }}>Sigmahz Waveform.</h2>
            </div>
            <span className="meta">Mixcloud · ongoing</span>
          </div>
        </Reveal>

        <div className="mixes">
          <Reveal>
            <div className="mix-card">
              <div className="eyebrow"><span className="dot"></span>Latest · Sigmahz Waveform</div>
              <h3 style={{ marginTop: 22 }}>{MIXCLOUD_LATEST_TITLE}</h3>
              <p className="body">
                Long-form DJ sets stitched from the corners of melodic house &amp; techno, progressive house, indie dance and deep house — recorded live, posted slow.
              </p>
              <div className="mixcloud-embed">
                <iframe
                  src={MIXCLOUD_LATEST}
                  title={MIXCLOUD_LATEST_TITLE}
                  frameBorder="0"
                  allow="autoplay"
                />
              </div>
              <a className="pbtn primary" href={LINKS.mixcloud} target="_blank" rel="noopener">
                <span className="icon">{I.mixcloud}</span> All mixes on Mixcloud
              </a>
            </div>
          </Reveal>

          <Reveal delay={120}>
            <div>
              <div className="eyebrow">What to expect</div>
              <ul style={{ listStyle: 'none', padding: 0, margin: '24px 0 0' }}>
                {[
                ['Live DJ sets', '60–120 minute mixes recorded in one take — slow build, peak, soft landing.'],
                ['Genre arc', 'Progressive house → melodic house &amp; techno → indie dance → deep house — the whole spectrum across a single ride.'],
                ['Posted slow', 'New waveform every few weeks. Subscribe on Mixcloud for the drop.']].
                map(([k, v], i) =>
                <li key={i} style={{
                  padding: '20px 0',
                  borderTop: '1px solid var(--line)',
                  display: 'grid',
                  gridTemplateColumns: '160px 1fr',
                  gap: 24,
                  alignItems: 'baseline'
                }}>
                    <span style={{
                    fontFamily: 'var(--f-mono)',
                    fontSize: 11,
                    letterSpacing: '0.18em',
                    textTransform: 'uppercase',
                    color: 'var(--accent)'
                  }}>{k}</span>
                    <span style={{ color: 'var(--ink-soft)', fontSize: 15, lineHeight: 1.6 }}>{v}</span>
                  </li>
                )}
              </ul>
            </div>
          </Reveal>
        </div>
      </div>
    </section>);

}

// ────────────────────────────────────────────────────────────
// Bio
// ────────────────────────────────────────────────────────────
function Bio({ lang, setLang }) {
  return (
    <section className="section" id="about" data-screen-label="Bio" style={{ borderTop: '1px solid var(--line)' }}>
      <div className="section-inner">
        <Reveal>
          <div className="section-header">
            <div>
              <div className="eyebrow"><span className="dot"></span>04 — About</div>
              <h2 className="h-section" style={{ marginTop: 14 }}>The signal.</h2>
            </div>
            <div className="lang-switch" role="tablist" aria-label="Language">
              <button onClick={() => setLang('es')} data-active={lang === 'es'}>ES</button>
              <button onClick={() => setLang('en')} data-active={lang === 'en'}>EN</button>
            </div>
          </div>
        </Reveal>

        <div className="bio">
          <Reveal>
            <div className="bio-portrait has-image">
              <img src="assets/portrait.jpg" alt="Sigmahz at the decks" />
              <span className="corner tl">+</span>
              <span className="corner br">+</span>
              <span className="bio-credit">— live @ Mérida, Yucatán</span>
            </div>
          </Reveal>

          <Reveal delay={120}>
            <div className="bio-body">
              <p>{lang === 'es' ? BIO_ES : BIO_EN}</p>

              <div className="bio-origin">
                <div>
                  <span className="k">Born</span>
                  <span className="v">Mérida, Yucatán · MX</span>
                </div>
                <div>
                  <span className="k">Based</span>
                  <span className="v">Atlanta, GA · USA</span>
                </div>
                <div>
                  <span className="k">Since</span>
                  <span className="v">2022 —</span>
                </div>
              </div>
            </div>
          </Reveal>
        </div>
      </div>
    </section>);

}

// ────────────────────────────────────────────────────────────
// Footer
// ────────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer className="footer" id="contact" data-screen-label="Footer" style={{ borderTop: '1px solid var(--line)' }}>
      <div className="footer-inner">
        <Reveal>
          <div className="eyebrow"><span className="dot"></span>Keep listening</div>
          <h2 className="footer-bigname" style={{ marginTop: 24 }} aria-label="Sigmahz">
            <img src="assets/sigmahz-wordmark.png" alt="Sigmahz" />
          </h2>
        </Reveal>

        <Reveal>
          <div className="footer-grid">
            <div>
              <h4>Listen</h4>
              <a href={LINKS.spotifyArtist} target="_blank" rel="noopener">Spotify ↗</a>
              <a href={LINKS.playlist} target="_blank" rel="noopener">Full catalogue (playlist) ↗</a>
              <a href={LINKS.soundcloud} target="_blank" rel="noopener">Soundcloud ↗</a>
              <a href={LINKS.mixcloud} target="_blank" rel="noopener">Mixcloud ↗</a>
            </div>
            <div>
              <h4>Follow</h4>
              <a href={LINKS.instagram} target="_blank" rel="noopener">Instagram ↗</a>
              <p style={{ color: 'var(--ink-faint)' }}>@sigmahz.music</p>
            </div>
            <div>
              <h4>Bookings &amp; press</h4>
              <a href={LINKS.booking}>{LINKS.bookingEmail}</a>
              <p style={{ color: 'var(--ink-faint)', fontSize: 12, letterSpacing: '0.1em', textTransform: 'uppercase', marginTop: 12 }}>EPK on request</p>
            </div>
          </div>
        </Reveal>

        <div className="footer-bottom">
          <span>© 2026 Sigmahz</span>
          <span>Site v0.1 · in progress</span>
        </div>
      </div>
    </footer>);

}

// ────────────────────────────────────────────────────────────
// Persistent player dock (Spotify embed)
// ────────────────────────────────────────────────────────────
function PlayerDock() {
  return (
    <div className="dock" aria-label="Persistent player">
      <div className="dock-label"><span className="dot"></span>Now Playing · Sigmahz</div>
      <iframe
        className="dock-iframe"
        src={PLAYLIST_EMBED}
        title="Sigmahz — full catalogue"
        allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
        loading="lazy" />
      
    </div>);

}

// ────────────────────────────────────────────────────────────
// App
// ────────────────────────────────────────────────────────────
function SigmahzApp() {
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "accent": "#ff6b1a",
    "lang": "en",
    "density": "comfortable"
  } /*EDITMODE-END*/;

  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lang, setLang] = React.useState(t.lang || 'en');

  React.useEffect(() => {
    document.documentElement.style.setProperty('--accent', t.accent);
    // derived warm halo: shift the accent lighter
    document.documentElement.style.setProperty('--accent-2', shade(t.accent, 0.35));
    document.documentElement.style.setProperty('--accent-deep', shade(t.accent, -0.45));
    if (t.lang) setLang(t.lang);
  }, [t.accent, t.lang]);

  function onLang(l) {
    setLang(l);
    setTweak('lang', l);
  }

  return (
    <>
      <Nav />
      <main>
        <Hero />
        <Latest />
        <Discography />
        <Mixes />
        <Bio lang={lang} setLang={onLang} />
        <Footer />
      </main>
      <PlayerDock />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Accent — ember from the cover">
          <TweakColor
            label="Accent color"
            value={t.accent}
            onChange={(v) => setTweak('accent', v)}
            options={['#ff6b1a', '#e85a18', '#ffa760', '#3a7bd5', '#b266ff', '#1fb89a']} />
          
        </TweakSection>
        <TweakSection label="Language">
          <TweakRadio
            label="Bio language"
            value={t.lang || lang}
            options={['es', 'en']}
            onChange={(v) => {setTweak('lang', v);setLang(v);}} />
          
        </TweakSection>
      </TweaksPanel>
    </>);

}

// quick hex shade helper
function shade(hex, amt) {
  const h = hex.replace('#', '');
  const n = parseInt(h.length === 3 ? h.split('').map((c) => c + c).join('') : h, 16);
  let r = n >> 16 & 255,g = n >> 8 & 255,b = n & 255;
  const f = (c) => Math.max(0, Math.min(255, Math.round(c + (amt > 0 ? 255 - c : c) * amt)));
  return '#' + [f(r), f(g), f(b)].map((x) => x.toString(16).padStart(2, '0')).join('');
}

window.SigmahzApp = SigmahzApp;