const { useState: useSt, useEffect: useEf } = React;

function App() {
  const [tweaks, setTweaks] = useSt(window.TWEAK_DEFAULTS);
  const [editMode, setEditMode] = useSt(false);
  const [panelOpen, setPanelOpen] = useSt(false);
  const [isLive, setIsLive] = useSt(true);
  // Which platform is currently live — 'kick' | 'tiktok'. Defaults to kick
  // since that's Amr's main daily stream and the CTA copy is tuned for it.
  const [livePlatform, setLivePlatform] = useSt('kick');

  const setTweak = (k, v) => setTweaks(prev => {
    const next = { ...prev, [k]: v };
    window.parent?.postMessage({ type: '__edit_mode_set_keys', edits: { [k]: v } }, '*');
    return next;
  });

  // Apply tweaks to DOM
  useEf(() => {
    const root = document.documentElement;
    root.setAttribute('data-theme', tweaks.theme);
    root.setAttribute('data-density', tweaks.density);
    root.setAttribute('data-layout', tweaks.layout);
    root.setAttribute('data-font', tweaks.font);
    root.setAttribute('lang', tweaks.lang);
    root.setAttribute('dir', tweaks.lang === 'ar' ? 'rtl' : 'ltr');
    const accent = tweaks.accent;
    root.style.setProperty('--red-0', accent);
    root.style.setProperty('--red-1', shade(accent, 20));
    root.style.setProperty('--red-2', shade(accent, -30));
    root.style.setProperty('--red-dim', hexToRgba(accent, 0.15));
    window.__soundEnabled?.(tweaks.soundOnHover);
  }, [tweaks]);

  // Live check across Kick + TikTok. Both platforms block cross-origin reads, so we
  // route every request through CORS proxies (allorigins / corsproxy). Kick is the
  // primary daily stream; TikTok is secondary — so when both are live we prefer Kick.
  // If every proxy fails we keep the previous state instead of flipping to OFF, so a
  // transient proxy outage doesn't ruin the CTA.
  useEf(() => {
    let cancelled = false;

    const proxify = (url) => [
      'https://api.allorigins.win/raw?url=' + encodeURIComponent(url),
      'https://corsproxy.io/?' + encodeURIComponent(url),
    ];
    const fetchVia = async (target) => {
      for (const url of proxify(target)) {
        try {
          const r = await fetch(url, { cache: 'no-store' });
          if (r.ok) return r;
        } catch (_) { /* try next proxy */ }
      }
      return null;
    };

    // Kick has a real JSON API — cleanest signal.
    const checkKick = async () => {
      const r = await fetchVia('https://kick.com/api/v2/channels/3mr');
      if (!r) return null;
      try {
        const d = await r.json();
        return !!(d && d.livestream);
      } catch { return null; }
    };

    // TikTok has no public live API. We fetch the /live page and look for markers
    // that only appear when the broadcaster is actually on air. It's unofficial and
    // can fail if TikTok returns a captcha page, so null = "unknown" (keep state).
    const checkTikTok = async () => {
      const r = await fetchVia('https://www.tiktok.com/@3mrrdiab/live');
      if (!r) return null;
      try {
        const html = await r.text();
        if (/liveRoom[\s\S]{0,1200}?"status"\s*:\s*2/i.test(html)) return true;
        if (/"@type"\s*:\s*"BroadcastEvent"/i.test(html)) return true;
        if (/"isLive"\s*:\s*true/i.test(html)) return true;
        return false;
      } catch { return null; }
    };

    const check = async () => {
      const [kick, tiktok] = await Promise.all([checkKick(), checkTikTok()]);
      if (cancelled) return;
      // Prefer Kick when both are live (main platform, daily schedule).
      if (kick === true)        { setIsLive(true);  setLivePlatform('kick');   return; }
      if (tiktok === true)      { setIsLive(true);  setLivePlatform('tiktok'); return; }
      // Only flip to offline when at least one check returned a definitive false.
      if (kick === false || tiktok === false) {
        setIsLive(false);
        setLivePlatform('kick');
      }
      // Otherwise both were null → keep previous state.
    };

    check();
    const t = setInterval(check, 60000);
    return () => { cancelled = true; clearInterval(t); };
  }, []);

  // Edit mode handshake
  useEf(() => {
    const onMsg = (e) => {
      if (e.data?.type === '__activate_edit_mode') setEditMode(true);
      if (e.data?.type === '__deactivate_edit_mode') setEditMode(false);
    };
    window.addEventListener('message', onMsg);
    window.parent?.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', onMsg);
  }, []);

  useEf(() => { setTimeout(() => window.__observeReveals?.(), 100); }, [tweaks.lang]);

  const t = I18N[tweaks.lang] || I18N.en;
  const ctx = { lang: tweaks.lang, t };

  return (
    <LangContext.Provider value={ctx}>
      <Nav isLive={isLive} lang={tweaks.lang} setLang={v=>setTweak('lang',v)} onOpenTweaks={() => setPanelOpen(o=>!o)}/>
      <Hero isLive={isLive} livePlatform={livePlatform}/>
      <Stats/>
      <RankProof/>
      <Bio/>
      <Platforms isLive={isLive} livePlatform={livePlatform}/>
      <PlatformMarquee/>
      <Contact/>
      <Footer isLive={isLive}/>
      <TweaksPanel tweaks={tweaks} setTweak={setTweak} visible={editMode || panelOpen} onClose={()=>setPanelOpen(false)}/>
    </LangContext.Provider>
  );
}

function Nav({ isLive, lang, setLang, onOpenTweaks }) {
  const { t } = React.useContext(LangContext);
  const [scrolled, setScrolled] = useSt(false);
  const [memOpen, setMemOpen] = useSt(false);
  const memWrapRef = React.useRef(null);
  const memCloseTimer = React.useRef(null);

  useEf(() => {
    const onScroll = () => setScrolled(window.scrollY > 20);
    window.addEventListener('scroll', onScroll);
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // Close memorial on outside click / Esc
  useEf(() => {
    const onDoc = (e) => {
      if (!memWrapRef.current) return;
      if (!memWrapRef.current.contains(e.target)) setMemOpen(false);
    };
    const onKey = (e) => { if (e.key === 'Escape') setMemOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDoc);
      document.removeEventListener('keydown', onKey);
    };
  }, []);

  const openMem  = () => { clearTimeout(memCloseTimer.current); setMemOpen(true); };
  const closeMem = () => { memCloseTimer.current = setTimeout(() => setMemOpen(false), 180); };

  return (
    <nav className={`nav ${scrolled?'nav--scrolled':''}`}>
      <div className="nav__inner">
        <div
          className={`nav__logo-wrap ${memOpen?'is-open':''}`}
          ref={memWrapRef}
          onMouseEnter={openMem}
          onMouseLeave={closeMem}
        >
          <button
            type="button"
            className="nav__logo"
            data-hover
            onClick={() => { setMemOpen(o=>!o); window.__playClick?.(); }}
            onMouseEnter={() => window.__playHover?.()}
            aria-haspopup="dialog"
            aria-expanded={memOpen}
            aria-label="3MR — open tribute to Heba Diab"
          >
            <img src="3mr-heba.jpg" alt="3MR"/>
            <span className="mono">3MR</span>
            <span className="nav__logo-pulse" aria-hidden="true"></span>
          </button>

          {/* In loving memory of Heba Diab — رحمها الله */}
          <div className={`mem-card ${memOpen?'is-open':''}`} role="dialog" aria-labelledby="memTitle" aria-hidden={!memOpen}>
            <div className="mem-card__aura" aria-hidden="true"></div>

            <div className="mem-card__photo">
              <img src="3mr-heba.jpg" alt="Amr with his late sister Heba Diab" loading="lazy"/>
              <span className="mem-card__photo-veil" aria-hidden="true"></span>
              <span className="mem-card__photo-corner tl" aria-hidden="true"></span>
              <span className="mem-card__photo-corner tr" aria-hidden="true"></span>
              <span className="mem-card__photo-corner bl" aria-hidden="true"></span>
              <span className="mem-card__photo-corner br" aria-hidden="true"></span>
            </div>

            <div className="mem-card__body">
              <div className="mem-card__kicker mono">
                <span className="mem-card__ember" aria-hidden="true"></span>
                <span>{t.memKicker}</span>
                <span className="mem-card__ember" aria-hidden="true"></span>
              </div>

              <h3 id="memTitle" className="mem-card__name">
                {lang === 'ar' ? t.memName : t.memName}
              </h3>
              {lang !== 'ar' && <div className="mem-card__name-ar">هبة دياب</div>}
              <div className="mem-card__rel mono">{t.memRel}</div>

              <div className="mem-card__divider" aria-hidden="true"><span></span></div>

              <p className="mem-card__dua" dir="rtl">{t.memDuaAr}</p>
              <p className="mem-card__dua-en">{t.memDuaEn}</p>

              <div className="mem-card__footer mono">
                <span className="mem-card__heart" aria-hidden="true">
                  <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
                    <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
                  </svg>
                </span>
                <span>{t.memBy}</span>
              </div>
            </div>
          </div>
        </div>
        <div className="nav__links mono">
          <a href="#bio" data-hover>{t.about}</a>
          <a href="#platforms" data-hover>{t.channels}</a>
          <a href="#contact" data-hover>{t.contact}</a>
        </div>
        <div className="nav__right">
          <a href="https://kick.com/3mr" target="_blank" rel="noopener noreferrer" className="live-pill nav__live" data-live={isLive} data-hover onMouseEnter={()=>window.__playHover?.()}>
            <span className="live-dot"></span>
            <span className="mono small">{isLive ? t.live : t.off}</span>
          </a>
          <div className="lang-toggle" data-lang={lang}>
            <button className={`lang-btn ${lang==='en'?'is-active':''}`} onClick={()=>setLang('en')} data-hover>EN</button>
            <button className={`lang-btn ${lang==='ar'?'is-active':''}`} onClick={()=>setLang('ar')} data-hover>AR</button>
          </div>
          <button className="tweaks-toggle" onClick={() => { onOpenTweaks(); window.__playClick?.(); }} data-hover aria-label="Tweaks">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <circle cx="12" cy="12" r="3"/>
              <path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 0 1-4 0v-.1a1.7 1.7 0 0 0-1.2-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 0 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.2 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 0 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 0 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/>
            </svg>
          </button>
        </div>
      </div>
    </nav>
  );
}

function hexToRgba(hex, a) {
  const h = hex.replace('#','');
  const b = parseInt(h.length === 3 ? h.split('').map(c=>c+c).join('') : h, 16);
  return `rgba(${(b>>16)&255},${(b>>8)&255},${b&255},${a})`;
}
function shade(hex, percent) {
  const h = hex.replace('#','');
  const bi = parseInt(h.length === 3 ? h.split('').map(c=>c+c).join('') : h, 16);
  let r = (bi>>16)&255, g = (bi>>8)&255, b = bi&255;
  const amt = Math.round(2.55 * percent);
  r = Math.max(0, Math.min(255, r + amt));
  g = Math.max(0, Math.min(255, g + amt));
  b = Math.max(0, Math.min(255, b + amt));
  return '#' + ((1<<24) + (r<<16) + (g<<8) + b).toString(16).slice(1);
}

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