// SwiftyEx Hackfest Osun 2026 landing
const { useState, useEffect, useRef } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "dark"
}/*EDITMODE-END*/;

// ----- Theme hook -----
// Source of truth = localStorage. Multiple consumers (Nav toggle + ThemePanel)
// stay in sync via a custom event broadcast on every change.
function useTheme() {
  const [theme, setThemeState] = useState(() =>
    localStorage.getItem('hk-theme')
    || document.documentElement.getAttribute('data-theme')
    || 'dark'
  );
  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('hk-theme', theme);
  }, [theme]);
  useEffect(() => {
    const onChange = (e) => setThemeState(e.detail);
    window.addEventListener('hk-theme-change', onChange);
    return () => window.removeEventListener('hk-theme-change', onChange);
  }, []);
  const setTheme = (v) =>
    window.dispatchEvent(new CustomEvent('hk-theme-change', { detail: v }));
  const toggle = () => setTheme(theme === 'dark' ? 'light' : 'dark');
  return [theme, toggle, setTheme];
}

// ----- Reveal-on-scroll hook -----
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const els = document.querySelectorAll('.hk-reveal');
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('visible');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  }, []);
}

// ----- Parallax mascot orb -----
function MascotOrb() {
  const orbRef = useRef(null);
  useEffect(() => {
    let raf = 0;
    let mx = 0, my = 0;
    const onMove = (e) => {
      const r = window.innerWidth, h = window.innerHeight;
      mx = (e.clientX / r - 0.5) * 24;
      my = (e.clientY / h - 0.5) * 24;
    };
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        if (!orbRef.current) return;
        const y = window.scrollY;
        const tilt = Math.min(20, y * 0.04);
        const scale = Math.max(0.78, 1 - y * 0.0006);
        orbRef.current.style.transform =
          `translate3d(${mx}px, ${my + y * 0.15}px, 0) scale(${scale}) rotate(${-tilt}deg)`;
      });
    };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => {
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('scroll', onScroll);
      cancelAnimationFrame(raf);
    };
  }, []);
  return (
    <div className="hk-hero-stage">
      <div className="hk-mascot-orb" ref={orbRef}>
        <img className="hk-mascot-img" src="assets/mascot.jpg" alt="Swiftyex mascot" />
      </div>
      <div className="hk-token tk-1"><span className="num">$2K</span> PRIZE POOL</div>
      <div className="hk-token tk-2"><span className="num">3</span> TRACKS</div>
      <div className="hk-token tk-3"><span className="num">∞</span> POSSIBILITIES</div>
      <div className="hk-token tk-4"><span className="num">OSUN</span> 2026</div>
    </div>
  );
}

// ----- Count-up number -----
function CountUp({ to, prefix = '', duration = 1800 }) {
  const [val, setVal] = useState(0);
  const ref = useRef(null);
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (!e.isIntersecting) return;
        const start = performance.now();
        const tick = (t) => {
          const p = Math.min(1, (t - start) / duration);
          const eased = 1 - Math.pow(1 - p, 3);
          setVal(Math.round(to * eased));
          if (p < 1) requestAnimationFrame(tick);
        };
        requestAnimationFrame(tick);
        io.unobserve(e.target);
      });
    }, { threshold: 0.4 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref}>{prefix}{val.toLocaleString('en-US')}</span>;
}

// ----- Hero -----
function Hero() {
  return (
    <section className="hk-hero">
      <div className="hk-hero-text">
        <div className="hk-hero-eyebrow hk-reveal">OSUN STATE · NIGERIA · 2026</div>
        <h1 className="hk-hero-title hk-reveal delay-1" data-text="HACK THE BOT.">
          <span className="word">HACK</span> <span className="word">THE</span> <span className="word accent">BOT.</span>
        </h1>
        <p className="hk-hero-sub hk-reveal delay-2">
          A 72-hour, no-holds-barred sprint to break, build and amplify the Swiftyex Telegram crypto bot.
          Three tracks. One prize pool. Zero excuses.
        </p>
        <div className="hk-hero-meta hk-reveal delay-2">
          <div className="hk-meta-chip"><span className="dot"></span>$2,000 prize pool</div>
          <div className="hk-meta-chip purple"><span className="dot"></span>3 tracks</div>
          <div className="hk-meta-chip pink"><span className="dot"></span>50% paid upfront</div>
        </div>
        <div className="hk-hero-actions hk-reveal delay-3">
          <a href="#register" className="hk-cta-primary"><span className="arrow">↗</span> Apply now</a>
          <a href="#tracks" className="hk-cta-ghost">See the tracks</a>
        </div>
      </div>
      <MascotOrb />
    </section>
  );
}

// ----- Marquee -----
function Marquee() {
  const items = [
    'BUILDERS · GUARDIANS · AMPLIFIERS',
    '$2,000 IN PRIZES',
    'BLACK-BOX SANDBOX',
    'SHIP IN 72 HOURS',
    'PAID IN BOT',
  ];
  const repeated = [...items, ...items, ...items, ...items];
  return (
    <div className="hk-marquee">
      <div className="hk-marquee-track">
        {repeated.map((t, i) => (
          <React.Fragment key={i}>
            <span>{t}</span>
            <span className="star">✦</span>
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

// ----- Tracks -----
function Tracks() {
  const tracks = [
    {
      key: 'builders', tag: 'TRACK A', tone: 'builders', glyph: '⚙', total: '$900',
      title: <>The <span className="accent">Builders</span></>,
      desc: 'Ship new features and UX improvements via API integrations and Telegram Web App plugins. Make the bot do something it couldn\'t before.',
      prizes: [['1st place', '$600'], ['2nd place', '$300']],
    },
    {
      key: 'guardians', tag: 'TRACK B', tone: 'guardians', glyph: '◈', total: '$650',
      title: <>The <span className="accent">Guardians</span></>,
      desc: 'Black-box pentest the staging bot. Find logic flaws, race conditions, auth bugs. Break it before someone else does.',
      prizes: [['1st place', '$500'], ['Bug pool', '$150']],
    },
    {
      key: 'amplifiers', tag: 'TRACK C', tone: 'amplifiers', glyph: '✦', total: '$450',
      title: <>The <span className="accent">Amplifiers</span></>,
      desc: 'AI-generated viral campaigns and onboarding funnels. Bring users in, keep them in, make them post about it.',
      prizes: [['1st place', '$450']],
    },
  ];
  return (
    <section className="hk-section" id="tracks">
      <div className="hk-tracks-head">
        <div>
          <div className="hk-section-eyebrow hk-reveal">★ Three tracks</div>
          <h2 className="hk-section-title hk-reveal delay-1">Pick your<br/><span className="accent">battlefield.</span></h2>
        </div>
        <p className="hk-section-sub hk-reveal delay-2">
          Whether you write code, break code, or write copy — there's a lane for you.
          Each track is judged independently. Submit to one, two, or all three.
        </p>
      </div>
      <div className="hk-tracks">
        {tracks.map((t, i) => (
          <article key={t.key} className={`hk-track ${t.tone} hk-reveal delay-${i+1}`}>
            <div className="num">{t.tag}</div>
            <div className="total">{t.total}</div>
            <div className="glyph">{t.glyph}</div>
            <h3>{t.title}</h3>
            <p>{t.desc}</p>
            <div className="prizes">
              {t.prizes.map(([place, amt]) => (
                <div key={place} className="prize">
                  <span className="place">{place}</span>
                  <span className="amt">{amt}</span>
                </div>
              ))}
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

// ----- Prize pool -----
function PrizePool() {
  return (
    <section className="hk-section" id="prizes" style={{ paddingTop: 0 }}>
      <div className="hk-pool hk-reveal">
        <div className="hk-pool-label">★ Total prize pool</div>
        <div className="hk-pool-amount"><CountUp to={2000} prefix="$" /></div>
        <p className="hk-pool-sub">
          Distributed across three tracks. Paid 50% upfront via the bot, 50% post-integration week.
          No equity asks. No strings.
        </p>
      </div>
    </section>
  );
}

// ----- Rules -----
function Rules() {
  const rules = [
    { n: '01', title: 'Black-box policy', body: 'No core source code. No fiat credentials. You work from the outside-in, like a real attacker would.' },
    { n: '02', title: 'Sandbox environment', body: 'All technical work happens on a dedicated staging bot with test tokens. No production data touched, no users harmed.' },
    { n: '03', title: 'IP rights', body: 'Company retains a non-exclusive license to implement any submitted ideas, code, or copy. You keep the credit.' },
    { n: '04', title: 'Payout cadence', body: '50% paid in stablecoin via the bot on award day. Remaining 50% released after the post-event integration week.' },
  ];
  return (
    <section className="hk-section" id="rules">
      <div className="hk-section-eyebrow hk-reveal">★ Rules of engagement</div>
      <h2 className="hk-section-title hk-reveal delay-1">Play <span className="accent">hard.</span><br/>Play fair.</h2>
      <p className="hk-section-sub hk-reveal delay-2">Four rules. Read them. Sign them. Then go feral.</p>
      <div className="hk-rules-grid">
        {rules.map((r, i) => (
          <div key={r.n} className={`hk-rule hk-reveal delay-${(i%3)+1}`}>
            <div className="rule-num">{r.n}</div>
            <div>
              <h4>{r.title}</h4>
              <p>{r.body}</p>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

// ----- Schedule -----
function Schedule() {
  const rows = [
    { date: 'WEEK -2', title: 'Applications open', sub: 'Submit your team and track preference. Rolling review.', tag: 'INTAKE' },
    { date: 'WEEK -1', title: 'Sandbox access dispatched', sub: 'Approved teams get bot tokens, docs, and a Discord channel.', tag: 'PREP' },
    { date: 'DAY 0', title: 'Kickoff in Osun', sub: 'In-person opening + remote stream. Brief, then build.', tag: 'OPENING' },
    { date: 'DAY 1–3', title: '72-hour build window', sub: 'Heads down. Mentors on call. Energy drinks on us.', tag: 'BUILD' },
    { date: 'DAY 3', title: 'Submissions + demo', sub: 'Ship to the staging bot. Live demo in front of judges.', tag: 'JUDGING' },
    { date: 'DAY 4', title: 'Awards + 50% payout', sub: 'Winners announced. Half the prize hits your bot wallet on the spot.', tag: 'PAYOUT' },
    { date: 'WEEK +1', title: 'Integration week', sub: 'We merge the wins into production. Final 50% released.', tag: 'WRAP' },
  ];
  return (
    <section className="hk-section" id="schedule">
      <div className="hk-section-eyebrow hk-reveal">★ Schedule</div>
      <h2 className="hk-section-title hk-reveal delay-1">From <span className="accent">apply</span> to <span className="accent">payout.</span></h2>
      <p className="hk-section-sub hk-reveal delay-2">A clear path through the chaos.</p>
      <div className="hk-schedule">
        {rows.map((r, i) => (
          <div key={i} className="hk-sch-row hk-reveal">
            <div className="hk-sch-date">{r.date}</div>
            <div className="hk-sch-title">{r.title}<span className="sub">{r.sub}</span></div>
            <div className="hk-sch-tag">{r.tag}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

// ----- Partners -----
function Partners() {
  const partners = [
    { name: 'Elegance Tech Hub', src: 'assets/partners/elegance.png', href: '#', kind: 'color' },
    { name: 'Finezcv', src: 'assets/partners/finezcv.svg', href: 'https://finezcv-fe.onrender.com/', kind: 'light' },
    { name: 'Spree', src: 'assets/partners/spree.png', href: '#', kind: 'dark' },
  ];
  return (
    <section className="hk-section" id="partners">
      <div className="hk-section-eyebrow hk-reveal">★ Partners</div>
      <h2 className="hk-section-title hk-reveal delay-1">Backed by <span className="accent">builders.</span></h2>
      <p className="hk-section-sub hk-reveal delay-2">The teams powering infrastructure, payments, and the on-the-ground community in Osun.</p>
      <div className="hk-partners">
        {partners.map((p, i) => (
          <a
            key={p.name}
            href={p.href}
            target={p.href.startsWith('http') ? '_blank' : undefined}
            rel={p.href.startsWith('http') ? 'noopener noreferrer' : undefined}
            className={`hk-partner hk-partner--${p.kind} hk-reveal delay-${(i%3)+1}`}
            aria-label={p.name}
          >
            <img src={p.src} alt={p.name} />
          </a>
        ))}
      </div>
    </section>
  );
}

// ----- FAQ -----
function FAQ() {
  const faqs = [
    { q: 'Do I need to be in Osun to participate?', a: 'No. The kickoff and judging are hybrid — show up in person if you can, but remote teams are first-class citizens. The 72-hour build window is fully online.' },
    { q: 'Can I enter more than one track?', a: 'Yes. Each track is judged independently. If you have the bandwidth and the team, submit to all three.' },
    { q: 'What languages / stacks are accepted?', a: 'Anything the bot can call. The staging bot exposes a documented API + TWA surface. Use whatever you ship best in.' },
    { q: 'How big can a team be?', a: 'Solo to four. Above four, prize splits get awkward and you spend more time arguing than building.' },
    { q: 'When and how do I get paid?', a: '50% in USDT (or equivalent) sent via the bot on award day. The remaining 50% is released after we ship your integration in production — usually within a week.' },
    { q: 'What if I find a critical security bug before the event?', a: 'Email security@swiftyex.com directly. We pay bounties year-round and will fast-track you into the Guardians track if you want a seat.' },
  ];
  return (
    <section className="hk-section" id="faq">
      <div className="hk-section-eyebrow hk-reveal">★ Frequently asked</div>
      <h2 className="hk-section-title hk-reveal delay-1">Questions, <span className="accent">answered.</span></h2>
      <div className="hk-faqs">
        {faqs.map((f, i) => (
          <details key={i} className="hk-faq hk-reveal">
            <summary>
              <span>{f.q}</span>
              <span className="plus">+</span>
            </summary>
            <div className="body">{f.a}</div>
          </details>
        ))}
      </div>
    </section>
  );
}

// ----- Custom select -----
function HkSelect({ value, onChange, options, placeholder, required, name, id }) {
  const [open, setOpen] = useState(false);
  const [focusIdx, setFocusIdx] = useState(-1);
  const wrapRef = useRef(null);
  const listRef = useRef(null);
  const triggerRef = useRef(null);
  const selected = options.find((o) => o.value === value);

  useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (!wrapRef.current?.contains(e.target)) setOpen(false);
    };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [open]);

  useEffect(() => {
    if (!open) return;
    const idx = options.findIndex((o) => o.value === value);
    setFocusIdx(idx >= 0 ? idx : 0);
    listRef.current?.focus();
  }, [open]);

  const commit = (v) => {
    onChange(v);
    setOpen(false);
    triggerRef.current?.focus();
  };

  const onTriggerKey = (e) => {
    if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      setOpen(true);
    } else if (e.key === 'Escape') {
      setOpen(false);
    }
  };

  const onListKey = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setFocusIdx((i) => Math.min(options.length - 1, i + 1)); }
    else if (e.key === 'ArrowUp') { e.preventDefault(); setFocusIdx((i) => Math.max(0, i - 1)); }
    else if (e.key === 'Home') { e.preventDefault(); setFocusIdx(0); }
    else if (e.key === 'End') { e.preventDefault(); setFocusIdx(options.length - 1); }
    else if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (focusIdx >= 0) commit(options[focusIdx].value); }
    else if (e.key === 'Escape') { e.preventDefault(); setOpen(false); triggerRef.current?.focus(); }
    else if (e.key === 'Tab') { setOpen(false); }
  };

  return (
    <div className={`hk-select ${open ? 'open' : ''}`} ref={wrapRef}>
      <button
        ref={triggerRef}
        type="button"
        id={id}
        className={`hk-select-trigger ${selected ? '' : 'placeholder'}`}
        aria-haspopup="listbox"
        aria-expanded={open}
        onClick={() => setOpen((o) => !o)}
        onKeyDown={onTriggerKey}
      >
        <span className="hk-select-label">{selected ? selected.label : placeholder}</span>
        <span className="hk-select-chev" aria-hidden="true">
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
            <path d="M2.5 4.5L6 8L9.5 4.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </span>
      </button>
      {required && (
        <input
          className="hk-select-validation"
          tabIndex={-1}
          aria-hidden="true"
          required
          name={name}
          value={value || ''}
          onChange={() => {}}
          onFocus={() => triggerRef.current?.focus()}
        />
      )}
      <ul
        className="hk-select-menu"
        role="listbox"
        tabIndex={-1}
        ref={listRef}
        onKeyDown={onListKey}
      >
        {options.map((o, i) => (
          <li
            key={o.value}
            role="option"
            aria-selected={o.value === value}
            className={`hk-select-opt ${i === focusIdx ? 'focused' : ''} ${o.value === value ? 'selected' : ''}`}
            onMouseEnter={() => setFocusIdx(i)}
            onMouseDown={(e) => { e.preventDefault(); commit(o.value); }}
          >
            <span>{o.label}</span>
            {o.value === value && <span className="hk-select-check" aria-hidden="true">✓</span>}
          </li>
        ))}
      </ul>
    </div>
  );
}

// ----- Register -----
function Register() {
  const [submitted, setSubmitted] = useState(false);
  const [track, setTrack] = useState('');
  const [teamSize, setTeamSize] = useState('');
  const onSubmit = (e) => {
    e.preventDefault();
    setSubmitted(true);
  };
  return (
    <section className="hk-section" id="register">
      <div className="hk-section-eyebrow hk-reveal">★ Apply</div>
      <h2 className="hk-section-title hk-reveal delay-1">Lock in <span className="accent">your seat.</span></h2>
      <div className="hk-register hk-reveal delay-2">
        <div>
          <h3>Are you in?</h3>
          <p>
            Submit your details below. We'll review within 48 hours and email you sandbox access,
            the Discord invite, and the kickoff calendar drop.
          </p>
          <div className="stamps">
            <span>Rolling review · 48-hour decision</span>
            <span>Free to enter · No equity</span>
            <span>Powered by Swiftyex</span>
          </div>
        </div>
        {!submitted ? (
          <form className="hk-form" onSubmit={onSubmit}>
            <div className="hk-field">
              <label>Full name</label>
              <input required type="text" placeholder="Ada Lovelace" />
            </div>
            <div className="hk-field-row">
              <div className="hk-field">
                <label>Email</label>
                <input required type="email" placeholder="you@domain.com" />
              </div>
              <div className="hk-field">
                <label>Telegram handle</label>
                <input required type="text" placeholder="@yourhandle" />
              </div>
            </div>
            <div className="hk-field-row">
              <div className="hk-field">
                <label>Track</label>
                <HkSelect
                  required
                  name="track"
                  value={track}
                  onChange={setTrack}
                  placeholder="Choose a track…"
                  options={[
                    { value: 'A', label: 'A · Builders' },
                    { value: 'B', label: 'B · Guardians' },
                    { value: 'C', label: 'C · Amplifiers' },
                    { value: 'ALL', label: 'All three' },
                  ]}
                />
              </div>
              <div className="hk-field">
                <label>Team size</label>
                <HkSelect
                  required
                  name="teamSize"
                  value={teamSize}
                  onChange={setTeamSize}
                  placeholder="Pick a size…"
                  options={[
                    { value: 'Solo', label: 'Solo' },
                    { value: '2', label: '2' },
                    { value: '3', label: '3' },
                    { value: '4', label: '4' },
                  ]}
                />
              </div>
            </div>
            <div className="hk-field">
              <label>Why you</label>
              <textarea required rows="3" placeholder="One paragraph. What have you built / broken / shipped that we should know about?" />
            </div>
            <button type="submit" className="hk-form-cta">
              <span style={{fontSize:14}}>↗</span> Submit application
            </button>
          </form>
        ) : (
          <div className="hk-form-success show">
            <div className="check">✓</div>
            <h4 style={{fontFamily:'var(--hk-display)',fontSize:24,margin:'12px 0 8px',letterSpacing:'-.01em'}}>You're on the list.</h4>
            <p style={{margin:0,color:'var(--hk-fg-2)',lineHeight:1.55}}>
              Check your inbox within 48 hours for sandbox access and the Discord invite.
              Then start sharpening your tools.
            </p>
          </div>
        )}
      </div>
    </section>
  );
}

// ----- Footer -----
function Footer() {
  return (
    <footer className="hk-footer">
      <div>
        <a href="#tracks">Tracks</a>·
        <a href="#rules">Rules</a>·
        <a href="#schedule">Schedule</a>·
        <a href="#faq">FAQ</a>·
        <a href="#register">Apply</a>
      </div>
      <div className="legal">
        SWIFTYEX × HACKATHON OSUN 2026 · MADE WITH MINT &amp; PURPLE · ALL RIGHTS RESERVED
      </div>
    </footer>
  );
}

// ----- Theme tweaks -----
function ThemePanel() {
  const [theme, , setTheme] = useTheme();
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Theme">
        <TweakRadio
          value={theme}
          onChange={(v) => setTheme(v)}
          options={[{label:'Dark',value:'dark'},{label:'Light',value:'light'}]}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

// ----- Top nav -----
function Nav() {
  const [theme, toggleTheme] = useTheme();
  const isDark = theme === 'dark';
  return (
    <nav className="hk-nav">
      <div className="hk-brand">
        <img className="hk-brand-mark" src="assets/mascot.jpg" alt="" />
        <div>
          <div className="hk-brand-co">SwiftyEx <span className="hk-brand-x">×</span> Hackfest</div>
        </div>
        <span className="hk-brand-tag">Osun · 2026</span>
      </div>
      <div className="hk-nav-links">
        <a href="#tracks">Tracks</a>
        <a href="#rules">Rules</a>
        <a href="#schedule">Schedule</a>
        <a href="#faq">FAQ</a>
      </div>
      <div className="hk-nav-actions">
        <button
          type="button"
          className="hk-theme-toggle"
          onClick={toggleTheme}
          aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
          title={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
        >
          <span className="hk-theme-icon" aria-hidden="true">{isDark ? '☀' : '☾'}</span>
        </button>
        <a href="#register" className="hk-nav-cta"><span style={{fontSize:13}}>↗</span> Apply</a>
      </div>
    </nav>
  );
}

// ----- App root -----
function App() {
  useReveal();
  return (
    <div className="hk-page">
      <Nav />
      <Hero />
      <Marquee />
      <Tracks />
      <PrizePool />
      <Rules />
      <Schedule />
      <Partners />
      <FAQ />
      <Register />
      <Footer />
      <ThemePanel />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
