/* APEX CLIPS — shared library: data, primitives, Thumb, Nav, Footer */

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

/* ----------------------------------------------------------------
   SUPABASE — lead capture (insert-only via the publishable key + RLS)
   The key below is safe in the client: row-level security allows INSERT
   only, never SELECT, so the public can submit but never read the data.
-----------------------------------------------------------------*/
const SUPABASE_URL = "https://oozamomtmwikmclzougq.supabase.co";
const SUPABASE_ANON = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9vemFtb210bXdpa21jbHpvdWdxIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODA5NDM1ODUsImV4cCI6MjA5NjUxOTU4NX0.aTAd0awJFZo2AZgIr-f1COH54Cprr06q2_BDmL0aOG8";
async function submitLead(table, payload) {
  try {
    const res = await fetch(SUPABASE_URL + "/rest/v1/" + table, {
      method: "POST",
      headers: {
        apikey: SUPABASE_ANON,
        Authorization: "Bearer " + SUPABASE_ANON,
        "Content-Type": "application/json",
        Prefer: "return=minimal",
      },
      body: JSON.stringify(payload),
    });
    return res.ok;
  } catch (e) {
    return false;
  }
}

/* ----------------------------------------------------------------
   ROUTING — tiny hash router
-----------------------------------------------------------------*/
const RouteCtx = createContext({ path: "/", go: () => {} });
function parseHash() {
  const h = (window.location.hash || "#/").replace(/^#/, "");
  return h.startsWith("/") ? h : "/" + h;
}
function useRouter() {
  const [path, setPath] = useState(parseHash());
  useEffect(() => {
    const on = () => { setPath(parseHash()); window.scrollTo({ top: 0, behavior: "instant" in window ? "instant" : "auto" }); };
    window.addEventListener("hashchange", on);
    return () => window.removeEventListener("hashchange", on);
  }, []);
  const go = (p) => { window.location.hash = p; };
  return { path, go };
}
function Link({ to, className, style, children, onClick }) {
  const { go } = useContext(RouteCtx);
  return (
    <a href={"#" + to} className={className} style={style}
       onClick={(e) => { e.preventDefault(); onClick && onClick(); go(to); }}>
      {children}
    </a>
  );
}

/* ----------------------------------------------------------------
   DATA
-----------------------------------------------------------------*/
// Each category carries a 3–4 stop gradient signature used by Thumb.
const CATEGORIES = [
  { key: "travel",   name: "Travel",                   tag: "TRV", count: 4820, blurb: "Cities, coastlines, culture & wanderlust.", grad: ["#0b3d91", "#1d6cff", "#27d3c4", "#0a1633"] },
  { key: "extreme",  name: "Extreme Sports",           tag: "XTR", count: 3110, blurb: "Surf, snow, cliff, send.",                grad: ["#ff3d54", "#ff8a1f", "#2a0f1a", "#7a1228"] },
  { key: "grass",    name: "Grassroots Sport",         tag: "GRS", count: 2640, blurb: "Street football, courts, clubs.",         grad: ["#1f8a4d", "#9bff5a", "#08221a", "#0c3a2a"] },
  { key: "outdoor",  name: "Adventure & Outdoors",      tag: "OUT", count: 3980, blurb: "Trails, peaks, expeditions.",            grad: ["#3a6b35", "#b9a05a", "#16241a", "#5a4a25"] },
  { key: "wildlife", name: "Wildlife & Nature",         tag: "WLD", count: 2255, blurb: "Encounters, oceans, the wild.",          grad: ["#0a5a4a", "#23c9a7", "#073b3a", "#0b2230"] },
  { key: "drone",    name: "POV & Drone",               tag: "DRN", count: 4410, blurb: "First-person & aerial.",                 grad: ["#5b2bd6", "#1d6cff", "#0a1640", "#2a0d4a"] },
  { key: "weather",  name: "Weather & Rescue",          tag: "WTR", count: 1290, blurb: "Storms, swells, rescues.",               grad: ["#243b6b", "#6f8bbd", "#0a1424", "#101c30"] },
  { key: "fails",    name: "Fails & Unexpected",        tag: "FLS", count: 1875, blurb: "Real, unscripted, unbelievable.",        grad: ["#d6a11f", "#ff5a1f", "#2a1606", "#5a2a08"] },
];
const CAT_BY_KEY = Object.fromEntries(CATEGORIES.map((c) => [c.key, c]));

const RIGHTS = {
  cleared:   { label: "Rights cleared",  cls: "ok",   short: "Cleared" },
  editorial: { label: "Editorial only",  cls: "warn", short: "Editorial" },
  exclusive: { label: "Exclusive",       cls: "excl", short: "Exclusive" },
  pending:   { label: "Clearing",        cls: "warn", short: "Clearing" },
};

const ORIENT = { v: "9:16", h: "16:9", s: "1:1" };

const CLIPS = [
  { id: "el-7741", title: "Backside 540 over Chamonix couloir", cat: "extreme",  loc: "Chamonix, FR",       dur: "0:18", or: "v", rights: "cleared",   creator: "Léa V.",      releases: "No people in frame" },
  { id: "el-6620", title: "Drone sweep over Nusa Penida cliffs", cat: "drone",    loc: "Bali, ID",           dur: "0:32", or: "h", rights: "cleared",   creator: "Arda P.",     releases: "Talent release on file" },
  { id: "el-9015", title: "Street football nutmeg, golden hour", cat: "grass",    loc: "Lagos, NG",          dur: "0:24", or: "v", rights: "editorial", creator: "Kola A.",     releases: "Crowd visible: editorial" },
  { id: "el-3382", title: "Humpback breach beside kayak",        cat: "wildlife", loc: "Hervey Bay, AU",     dur: "0:11", or: "h", rights: "cleared",   creator: "Mara D.",     releases: "No people in frame" },
  { id: "el-5573", title: "Reef break barrel, water POV",        cat: "extreme",  loc: "Teahupo'o, PF",      dur: "0:14", or: "h", rights: "exclusive", creator: "Niko R.",     releases: "Exclusive to Apex Clips" },
  { id: "el-1108", title: "Night train window, Tokyo to Kyoto",  cat: "travel",   loc: "Honshu, JP",         dur: "0:27", or: "v", rights: "cleared",   creator: "Saki M.",     releases: "Talent release on file" },
  { id: "el-4429", title: "Avalanche control blast, ridge POV",  cat: "weather",  loc: "Verbier, CH",        dur: "0:21", or: "h", rights: "editorial", creator: "Patrol",      releases: "Editorial: newsworthy" },
  { id: "el-8856", title: "Ultra runner crosses scree at dawn",  cat: "outdoor",  loc: "Torres del Paine, CL", dur: "0:35", or: "h", rights: "cleared", creator: "Bruno S.",    releases: "Talent release on file" },
  { id: "el-2204", title: "Festival crowd surf, drone pullback", cat: "travel",   loc: "Lisbon, PT",         dur: "0:19", or: "h", rights: "editorial", creator: "Inês F.",     releases: "Crowd visible: editorial" },
  { id: "el-6691", title: "Mountain bike gap jump, chase cam",   cat: "extreme",  loc: "Queenstown, NZ",     dur: "0:16", or: "v", rights: "cleared",   creator: "Theo W.",     releases: "Talent release on file" },
  { id: "el-3019", title: "Lightning over open-ocean swell",     cat: "weather",  loc: "Bay of Biscay",      dur: "0:13", or: "h", rights: "cleared",   creator: "Crew 4",      releases: "No people in frame" },
  { id: "el-7350", title: "Cliff jump misjudge, friends react",  cat: "fails",    loc: "Krk, HR",            dur: "0:09", or: "v", rights: "pending",   creator: "Duje K.",     releases: "Clearing: talent contacted" },
  { id: "el-5512", title: "Safari leopard crosses at dusk",      cat: "wildlife", loc: "Maasai Mara, KE",    dur: "0:22", or: "h", rights: "cleared",   creator: "Otieno",      releases: "No people in frame" },
  { id: "el-4471", title: "Wingsuit valley line, helmet POV",    cat: "drone",    loc: "Lauterbrunnen, CH",  dur: "0:28", or: "h", rights: "exclusive", creator: "Felix H.",    releases: "Exclusive to Apex Clips" },
  { id: "el-9938", title: "Grassroots derby, last-minute winner", cat: "grass",   loc: "Manchester, UK",     dur: "0:20", or: "v", rights: "editorial", creator: "Sam B.",      releases: "Crowd visible: editorial" },
  { id: "el-2876", title: "Sandboard wipeout, dune ridge",       cat: "fails",    loc: "Swakopmund, NA",     dur: "0:10", or: "v", rights: "cleared",   creator: "Anika T.",    releases: "Talent release on file" },
];

const PLATFORMS = ["Facebook", "Instagram", "TikTok", "Snapchat", "YouTube", "Website / OTT", "Broadcast TV", "Paid social"];
const USAGE_TYPES = ["Editorial / news", "Social publishing", "Brand campaign", "Documentary / film", "Paid media / ads", "OTT / streaming"];

/* ----------------------------------------------------------------
   THUMB — procedural cinematic clip stand-in
-----------------------------------------------------------------*/
function gradFor(grad, seed = 0) {
  const a = (seed * 47) % 360;
  const [c1, c2, c3, c4] = grad;
  return [
    `radial-gradient(120% 90% at ${20 + (seed * 13) % 60}% ${15 + (seed * 7) % 40}%, ${c2} 0%, transparent 55%)`,
    `radial-gradient(100% 80% at ${70 - (seed * 11) % 50}% ${80 - (seed * 9) % 40}%, ${c1} 0%, transparent 60%)`,
    `conic-gradient(from ${a}deg at 50% 50%, ${c4}, ${c3}, ${c1}, ${c4})`,
  ].join(", ");
}

function Thumb({ clip, cat, seed = 1, style, className = "", children, kenBurns = true }) {
  const c = cat ? CAT_BY_KEY[cat] : (clip ? CAT_BY_KEY[clip.cat] : CATEGORIES[seed % CATEGORIES.length]);
  const s = clip ? parseInt(clip.id.replace(/\D/g, "").slice(-3) || "1", 10) : seed;
  return (
    <div className={"thumb " + className} style={style}>
      <div className="thumb__media" style={{ background: gradFor(c.grad, s), animationPlayState: kenBurns ? "running" : "paused" }}></div>
      <div className="thumb__grain"></div>
      <div className="thumb__scan"></div>
      <div className="thumb__vig"></div>
      <div className="thumb__play"><span></span></div>
      {children}
    </div>
  );
}

/* Rights status pill */
function RightsPill({ rights, solid }) {
  const r = RIGHTS[rights];
  return (
    <span className={"pill pill--" + r.cls + (solid ? " pill--solid" : "")}>
      <span className="dot"></span>{r.short}
    </span>
  );
}

/* ----------------------------------------------------------------
   PRIMITIVES
-----------------------------------------------------------------*/
function Eyebrow({ children }) { return <span className="eyebrow">{children}</span>; }

function Reveal({ children, delay = 0, as = "div", className = "", style }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => { if (e.isIntersecting) { setSeen(true); io.unobserve(e.target); } });
    }, { threshold: 0.12 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const Tag = as;
  return <Tag ref={ref} className={"reveal " + (seen ? "in " : "") + className} style={{ transitionDelay: delay + "ms", ...style }}>{children}</Tag>;
}

function Stat({ value, label }) {
  return (
    <div>
      <div className="display" style={{ fontSize: "clamp(34px,4vw,52px)", color: "var(--ink)" }}>{value}</div>
      <div className="mono" style={{ fontSize: 12, letterSpacing: ".12em", textTransform: "uppercase", color: "var(--ink-3)", marginTop: 4 }}>{label}</div>
    </div>
  );
}

/* ----------------------------------------------------------------
   NAV
-----------------------------------------------------------------*/
const NAV_LINKS = [
  { to: "/library", label: "Explore Library" },
  { to: "/creators", label: "For Creators" },
  { to: "/publishers", label: "For Publishers" },
  { to: "/brands", label: "For Brands" },
  { to: "/tv", label: "For TV" },
  { to: "/rights", label: "Rights" },
  { to: "/pricing", label: "Pricing" },
  { to: "/about", label: "About" },
];

function Logo({ onClick }) {
  return (
    <Link to="/" onClick={onClick} className="logo" style={{ display: "inline-flex", alignItems: "center", gap: 11 }}>
      <span style={{ width: 26, height: 26, borderRadius: 7, background: "var(--accent)", display: "grid", placeItems: "center", boxShadow: "0 6px 18px -8px var(--accent-glow)" }}>
        <span style={{ width: 0, height: 0, marginLeft: 2, borderLeft: "9px solid var(--accent-ink)", borderTop: "6px solid transparent", borderBottom: "6px solid transparent" }}></span>
      </span>
      <span className="display" style={{ fontSize: 22, letterSpacing: ".02em", lineHeight: 1 }}>
        Apex<span style={{ color: "var(--accent)" }}>.</span>
      </span>
    </Link>
  );
}

function Nav() {
  const { path } = useContext(RouteCtx);
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    const on = () => setScrolled(window.scrollY > 14);
    on(); window.addEventListener("scroll", on, { passive: true });
    return () => window.removeEventListener("scroll", on);
  }, []);
  useEffect(() => { setOpen(false); }, [path]);
  return (
    <header style={{ position: "sticky", top: 0, zIndex: 60 }}>
      <div style={{
        borderBottom: "1px solid " + (scrolled ? "var(--line)" : "transparent"),
        background: scrolled ? "color-mix(in oklch, var(--bg) 78%, transparent)" : "transparent",
        backdropFilter: scrolled ? "blur(14px) saturate(1.2)" : "none",
        transition: "background .3s, border-color .3s",
      }}>
        <div className="wrap" style={{ display: "flex", alignItems: "center", gap: 22, height: 72 }}>
          <Logo />
          <nav className="nav-desktop" style={{ display: "flex", gap: 4, marginLeft: 8 }}>
            {NAV_LINKS.map((l) => {
              const active = path === l.to;
              return (
                <Link key={l.to} to={l.to} style={{
                  fontSize: 14, fontWeight: 600, padding: "8px 12px", borderRadius: 8,
                  color: active ? "var(--ink)" : "var(--ink-3)",
                  background: active ? "color-mix(in oklch,#fff 6%,transparent)" : "transparent",
                  transition: ".18s",
                }}>{l.label}</Link>
              );
            })}
          </nav>
          <div style={{ marginLeft: "auto", display: "flex", gap: 10, alignItems: "center" }}>
            <Link to="/submit" className="btn btn--line btn--sm nav-cta">Submit Clip</Link>
            <Link to="/license" className="btn btn--accent btn--sm">License Footage</Link>
            <button className="nav-burger" onClick={() => setOpen((o) => !o)} aria-label="Menu" style={{
              display: "none", background: "transparent", border: "1px solid var(--line)", borderRadius: 9, width: 40, height: 40, color: "var(--ink)",
            }}>
              <div style={{ width: 16, height: 1.5, background: "currentColor", margin: "4px auto", boxShadow: "0 5px 0 currentColor, 0 -5px 0 currentColor" }}></div>
            </button>
          </div>
        </div>
      </div>
      {open && (
        <div className="nav-mobile" style={{ background: "var(--bg-2)", borderBottom: "1px solid var(--line)" }}>
          <div className="wrap" style={{ padding: "16px 20px 22px", display: "flex", flexDirection: "column", gap: 2 }}>
            {NAV_LINKS.map((l) => (
              <Link key={l.to} to={l.to} style={{ padding: "12px 6px", fontSize: 17, fontWeight: 600, borderBottom: "1px solid var(--line-soft)" }}>{l.label}</Link>
            ))}
            <div style={{ display: "flex", gap: 10, marginTop: 14 }}>
              <Link to="/submit" className="btn btn--line btn--block">Submit Clip</Link>
              <Link to="/license" className="btn btn--accent btn--block">License Footage</Link>
            </div>
          </div>
        </div>
      )}
    </header>
  );
}

/* ----------------------------------------------------------------
   NEWSLETTER — creator-first capture
-----------------------------------------------------------------*/
function Newsletter() {
  const [email, setEmail] = useState("");
  const [sent, setSent] = useState(false);
  const [busy, setBusy] = useState(false);
  const submit = async (e) => {
    e.preventDefault();
    if (!email || busy) return;
    setBusy(true);
    await submitLead("newsletter_signups", { email, source: "footer" });
    setBusy(false); setSent(true);
  };
  return (
    <div className="newsletter">
      <div className="mono newsletter-tag">The creator drop</div>
      <p className="newsletter-copy">Get paid for your footage. Join the creator network for briefs, licensing tips and payout updates.</p>
      {sent ? (
        <div className="newsletter-done mono">✓ You're in. Watch your inbox.</div>
      ) : (
        <form className="newsletter-form" onSubmit={submit}>
          <input className="input" type="email" required aria-label="Email address" placeholder="you@email.com" value={email} onChange={(e) => setEmail(e.target.value)} />
          <button className="btn btn--accent" type="submit" disabled={busy}>{busy ? "…" : "Join →"}</button>
        </form>
      )}
    </div>
  );
}

/* ----------------------------------------------------------------
   FOOTER
-----------------------------------------------------------------*/
function Footer() {
  const cols = [
    { h: "Platform", links: [["Explore Library", "/library"], ["License Footage", "/license"], ["Submit Your Clip", "/submit"], ["Bespoke Sourcing", "/bespoke"], ["Pricing", "/pricing"]] },
    { h: "Audiences", links: [["For Creators", "/creators"], ["For Publishers", "/publishers"], ["For Brands & Agencies", "/brands"], ["For TV & Production", "/tv"], ["Rights & Verification", "/rights"]] },
    { h: "Company", links: [["About", "/about"], ["Contact", "/contact"], ["FAQ", "/faq"], ["Send a Brief", "/license"]] },
  ];
  return (
    <footer style={{ borderTop: "1px solid var(--line)", background: "var(--bg-2)", position: "relative" }} className="noise-bg">
      <div className="wrap" style={{ padding: "64px 28px 40px", position: "relative", zIndex: 1 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1.6fr repeat(3, 1fr)", gap: 40 }} className="footer-grid">
          <div>
            <Logo />
            <p style={{ color: "var(--ink-3)", maxWidth: 280, marginTop: 16, fontSize: 14.5 }}>
              Rights-cleared adventure, travel and sport footage, sourced from real creators, verified by us, licensed to you.
            </p>
            <div style={{ display: "flex", gap: 10, marginTop: 20 }}>
              <Link to="/submit" className="btn btn--line btn--sm">Submit Clip</Link>
              <Link to="/license" className="btn btn--accent btn--sm">License Footage</Link>
            </div>
            <Newsletter />
          </div>
          {cols.map((c) => (
            <div key={c.h}>
              <div className="mono" style={{ fontSize: 11, letterSpacing: ".16em", textTransform: "uppercase", color: "var(--ink-4)", marginBottom: 16 }}>{c.h}</div>
              <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
                {c.links.map(([t, to]) => (
                  <Link key={t} to={to} style={{ color: "var(--ink-2)", fontSize: 14.5, transition: ".15s", width: "fit-content" }}
                    onClick={() => {}}>{t}</Link>
                ))}
              </div>
            </div>
          ))}
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16, flexWrap: "wrap", marginTop: 48, paddingTop: 24, borderTop: "1px solid var(--line)" }}>
          <span className="mono" style={{ fontSize: 12, color: "var(--ink-4)" }}>© 2026 APEX CLIPS · ALL FOOTAGE RIGHTS-MANAGED</span>
          <div style={{ display: "flex", gap: 18 }}>
            {["Contributor terms", "Buyer terms", "Privacy", "Takedown"].map((t) => (
              <span key={t} className="mono" style={{ fontSize: 12, color: "var(--ink-4)", cursor: "pointer" }}>{t}</span>
            ))}
          </div>
        </div>
      </div>
    </footer>
  );
}

/* Page shell — nav + content + footer */
function Page({ children }) {
  return (
    <React.Fragment>
      <Nav />
      <main>{children}</main>
      <Footer />
    </React.Fragment>
  );
}

/* expose */
Object.assign(window, {
  RouteCtx, useRouter, Link,
  CATEGORIES, CAT_BY_KEY, RIGHTS, ORIENT, CLIPS, PLATFORMS, USAGE_TYPES,
  Thumb, gradFor, RightsPill, Eyebrow, Reveal, Stat,
  Nav, Footer, Logo, Page, Newsletter, submitLead,
});
