/* global React */
const { useEffect, useState, useRef, createContext, useContext } = React;

/* ============================================================
   I18N — language context, auto-detect, persist, helper
   ============================================================ */
const LangCtx = createContext({ lang: "en", setLang: () => {} });

function detectInitialLang() {
  try {
    const stored = localStorage.getItem("lang");
    if (stored === "es" || stored === "en") return stored;
  } catch (e) { /* ignore */ }
  const nav = (navigator.language || navigator.userLanguage || "en").toLowerCase();
  return nav.startsWith("es") ? "es" : "en";
}

function LangProvider({ children }) {
  const [lang, setLangState] = useState(detectInitialLang);
  const [transition, setTransition] = useState(null); // null | { from, to }
  const inFlight = useRef(false);

  useEffect(() => {
    document.documentElement.lang = lang;
    try { localStorage.setItem("lang", lang); } catch (e) { /* ignore */ }
  }, [lang]);

  const setLang = (next) => {
    if (next === lang || inFlight.current) return;
    const reduced = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduced) { setLangState(next); return; }
    inFlight.current = true;
    setTransition({ from: lang, to: next });
    document.documentElement.classList.add("lang-transitioning");
    // Swap content at midpoint of the 700ms animation
    setTimeout(() => setLangState(next), 320);
    setTimeout(() => {
      document.documentElement.classList.remove("lang-transitioning");
      setTransition(null);
      inFlight.current = false;
    }, 720);
  };

  return (
    <LangCtx.Provider value={{ lang, setLang }}>
      {children}
      {transition && (
        <div className="lang-sweep" aria-hidden="true" key={`${transition.from}-${transition.to}`}>
          <span className="lang-sweep-line" />
          <span className="lang-sweep-badge">
            <span>{transition.from.toUpperCase()}</span>
            <span className="lang-sweep-arrow">→</span>
            <span className="lang-sweep-to">{transition.to.toUpperCase()}</span>
          </span>
        </div>
      )}
    </LangCtx.Provider>
  );
}

function useLang() { return useContext(LangCtx); }
function useT() {
  const { lang } = useContext(LangCtx);
  return (en, es) => (lang === "es" ? (es != null ? es : en) : en);
}

/* Optional helper: translate the active link label by route */
function LangToggle({ compact = false }) {
  const { lang, setLang } = useLang();
  return (
    <div className={`lang-toggle${compact ? " is-compact" : ""}`} role="group" aria-label="Language">
      <button
        type="button"
        className={"lang-btn" + (lang === "en" ? " is-active" : "")}
        onClick={() => setLang("en")}
        aria-pressed={lang === "en"}
      >EN</button>
      <span className="lang-sep">·</span>
      <button
        type="button"
        className={"lang-btn" + (lang === "es" ? " is-active" : "")}
        onClick={() => setLang("es")}
        aria-pressed={lang === "es"}
      >ES</button>
    </div>
  );
}

/* ============================================================
   TOPBAR
   ============================================================ */
function TopBar({ active = "home" }) {
  const [scrolled, setScrolled] = useState(false);
  const t = useT();
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 20);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  const link = (id, label, href) => (
    <a href={href} className={active === id ? "is-active" : ""}>{label}</a>
  );

  return (
    <header className="topbar" style={{
      background: scrolled
        ? "rgba(10,10,10,0.92)"
        : "linear-gradient(180deg, rgba(10,10,10,0.92) 0%, rgba(10,10,10,0.6) 70%, rgba(10,10,10,0) 100%)",
      borderBottom: scrolled ? "1px solid var(--line-soft)" : "1px solid transparent",
      transition: "background 0.4s, border-color 0.4s"
    }}>
      <nav className="left">
        {link("home",    t("Index",   "Inicio"),   "index.html")}
        {link("merch",   t("Merch",   "Tienda"),   "merch.html")}
        {link("podcast", t("Podcast", "Podcast"),  "podcast.html")}
      </nav>

      <a href="index.html" className="brand">
        The 1 <span className="pct">%</span>
      </a>

      <nav className="right">
        <span className="meta">EST · 2024</span>
        <a href="https://www.instagram.com/onepercent.work/" target="_blank" rel="noreferrer">Instagram</a>
        <a href="https://www.youtube.com/@The1Percent_Work" target="_blank" rel="noreferrer">YouTube</a>
        <LangToggle />
      </nav>
    </header>
  );
}

/* ============================================================
   FOOTER
   ============================================================ */
function Footer() {
  const t = useT();
  return (
    <footer className="footer">
      <div className="wrap">
        <div className="footer-grid">
          <div>
            <p className="signature">— Timothy Valverde</p>
            <p className="body" style={{ fontSize: 14, maxWidth: "44ch" }}>
              {t(
                "Pastor, husband, father. Sharing my son Hunt's two-time journey with cancer — and a daily pursuit to become better by one percent.",
                "Pastor, esposo, padre. Compartiendo las dos batallas de mi hijo Hunt contra el cáncer — y la búsqueda diaria de ser un uno por ciento mejor."
              )}
            </p>
            <div style={{ display: "flex", gap: 18, marginTop: 24 }}>
              <a href="https://www.instagram.com/onepercent.work/" target="_blank" rel="noreferrer" className="btn-ghost" style={{ padding: "8px 0", fontSize: 10 }}>
                Instagram <span className="arrow">→</span>
              </a>
              <a href="https://www.youtube.com/@The1Percent_Work" target="_blank" rel="noreferrer" className="btn-ghost" style={{ padding: "8px 0", fontSize: 10 }}>
                YouTube <span className="arrow">→</span>
              </a>
            </div>
          </div>

          <div>
            <h4>{t("Index", "Índice")}</h4>
            <ul>
              <li><a href="/">{t("Home", "Inicio")}</a></li>
              <li><a href="/merch">{t("Merch", "Tienda")}</a></li>
              <li><a href="/podcast">Podcast</a></li>
              <li><a href="/#hunt-for-hope">{t("Premiere", "Estreno")}</a></li>
              <li><a href="/donate">{t("Support", "Apoyar")}</a></li>
            </ul>
          </div>

          <div>
            <h4>Dossier</h4>
            <ul>
              <li><a href="/hunt-story">{t("Hunt's Story", "La Historia de Hunt")}</a></li>
              <li><a href="/#about">{t("About Timothy", "Sobre Timothy")}</a></li>
              <li><a href="/speaking">{t("Speaking", "Conferencias")}</a></li>
              <li><a href="/press">{t("Press", "Prensa")}</a></li>
            </ul>
          </div>
        </div>

        <div className="colophon">
          <span>{t("© 2026 — The 1 Percent · All rights reserved", "© 2026 — The 1 Percent · Todos los derechos reservados")}</span>
          <span>{t("A journey from pain · to · progress", "Del dolor · al · progreso")}</span>
        </div>

        <div className="footer-credit">
          <a href="https://www.bigbangbrand.co" target="_blank" rel="noreferrer">
            <span className="credit-label">design</span>
            <span className="credit-x">✕</span>
            <span className="credit-handle">Big Bang Brand</span>
          </a>
        </div>
      </div>
    </footer>
  );
}

/* ============================================================
   REVEAL HOOK — IntersectionObserver
   ============================================================ */
function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll(".reveal, .curtain");
    // Reveal anything already in the viewport on mount (avoids stuck curtain over videos)
    requestAnimationFrame(() => {
      els.forEach((el) => {
        const r = el.getBoundingClientRect();
        if (r.top < window.innerHeight * 0.95 && r.bottom > 0) {
          el.classList.add("is-in");
        }
      });
    });
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add("is-in");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.05, rootMargin: "0px 0px -5% 0px" });
    els.forEach((el) => { if (!el.classList.contains("is-in")) io.observe(el); });
    return () => io.disconnect();
  }, []);
}

/* ============================================================
   MARQUEE
   ============================================================ */
function Marquee({ items }) {
  const all = [...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {all.map((t, i) => (
          <span key={i}>
            {t}
            <span className="star">✦</span>
          </span>
        ))}
      </div>
    </div>
  );
}

/* ============================================================
   SECTION HEAD
   ============================================================ */
function SectionHead({ title }) {
  return (
    <div className="section-head reveal">
      <h2 className="title" dangerouslySetInnerHTML={{ __html: title }} />
    </div>
  );
}

/* ============================================================
   YT EMBED — with fallback to thumbnail + link if blocked (Error 153)
   On click: try to open the native YouTube app (iOS/Android), fall back to web.
   ============================================================ */
function openYouTube(e, vid) {
  const ua = navigator.userAgent || "";
  const isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
  const isAndroid = /Android/.test(ua);
  const webUrl = `https://www.youtube.com/watch?v=${vid}`;
  if (!isIOS && !isAndroid) return; // desktop: let the default target="_blank" web link run
  e.preventDefault();
  const appUrl = isIOS
    ? `youtube://watch?v=${vid}`
    : `intent://www.youtube.com/watch?v=${vid}#Intent;package=com.google.android.youtube;scheme=https;end`;
  // If the app opens, the page goes hidden — cancel fallback. Otherwise, web after 1.4s.
  const fallback = setTimeout(() => { window.location.href = webUrl; }, 1400);
  document.addEventListener("visibilitychange", function once() {
    if (document.hidden) clearTimeout(fallback);
    document.removeEventListener("visibilitychange", once);
  });
  window.location.href = appUrl;
}

function YTEmbed({ vid, title }) {
  const t = useT();
  return (
    <div className="yt-wrap">
      <a
        href={`https://www.youtube.com/watch?v=${vid}`}
        target="_blank"
        rel="noreferrer"
        onClick={(e) => openYouTube(e, vid)}
        className="yt-fallback"
        style={{
          background: `#000 url(https://img.youtube.com/vi/${vid}/maxresdefault.jpg) center/cover no-repeat`,
        }}
        aria-label={t(`Watch ${title} on YouTube`, `Ver ${title} en YouTube`)}
      >
        <span className="yt-overlay" />
        <span className="yt-play"><span className="yt-play-tri" /></span>
        <span className="yt-cta">{t("WATCH ON YOUTUBE →", "VER EN YOUTUBE →")}</span>
        <span className="yt-rec">● REC</span>
      </a>
    </div>
  );
}

/* ============================================================
   COUNTDOWN — to a target ISO date
   ============================================================ */
function Countdown({ to, label, sublabel }) {
  const t = useT();
  const target = new Date(to).getTime();
  const calc = () => {
    const diff = target - Date.now();
    if (diff <= 0) return null;
    const d = Math.floor(diff / (1000 * 60 * 60 * 24));
    const h = Math.floor((diff / (1000 * 60 * 60)) % 24);
    const m = Math.floor((diff / (1000 * 60)) % 60);
    const s = Math.floor((diff / 1000) % 60);
    return { d, h, m, s };
  };
  const [tick, setTick] = useState(calc());
  useEffect(() => {
    const id = setInterval(() => setTick(calc()), 1000);
    return () => clearInterval(id);
  }, []);
  const released = !tick;

  const cell = (val, lbl) => (
    <div className="cd-cell">
      <span className="cd-num">{String(val).padStart(2, "0")}</span>
      <span className="cd-lbl">{lbl}</span>
    </div>
  );

  return (
    <div className="countdown bracket">
      <div className="cd-head">
        <span className="mono cd-mono-lbl">{label || t("Premiere", "Estreno")}</span>
        <span className="hairline" style={{ flex: 1 }} />
        <span className="mono cd-mono-lbl" style={{ color: "var(--gold)" }}>{released ? t("● LIVE NOW", "● EN VIVO") : t("● COUNTDOWN", "● CUENTA REGRESIVA")}</span>
      </div>
      {released ? (
        <div className="cd-released">
          <span className="serif">{t("The dossier is open.", "El dossier está abierto.")}</span>
        </div>
      ) : (
        <div className="cd-grid">
          {cell(tick.d, t("Days", "Días"))}
          {cell(tick.h, t("Hours", "Horas"))}
          {cell(tick.m, t("Minutes", "Min"))}
          {cell(tick.s, t("Seconds", "Seg"))}
        </div>
      )}
      {sublabel && <p className="cd-sublabel mono">{sublabel}</p>}
    </div>
  );
}

Object.assign(window, { TopBar, Footer, useReveal, Marquee, SectionHead, YTEmbed, LangProvider, LangToggle, useLang, useT, Countdown });
