// ====== Hooks ======
function useReveal() {
  React.useEffect(() => {
    let io;
    const observe = () => {
      const els = document.querySelectorAll(".rv:not(.in)");
      if (!els.length) return;
      io && io.disconnect();
      io = new IntersectionObserver((entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); }
        });
      }, { threshold: 0.05, rootMargin: "0px 0px -4% 0px" });
      els.forEach((el) => io.observe(el));
    };

    // Run after layout settles; re-run on resize and scroll (cheap, observer is the gatekeeper).
    const t1 = setTimeout(observe, 50);
    const t2 = setTimeout(observe, 400);
    window.addEventListener("scroll", observe, { passive: true });
    window.addEventListener("resize", observe);

    // Safety net: after 1.2s, force everything visible so the page never has invisible content.
    const failsafe = setTimeout(() => {
      document.querySelectorAll(".rv:not(.in)").forEach((el) => el.classList.add("in"));
    }, 1200);

    return () => {
      clearTimeout(t1); clearTimeout(t2); clearTimeout(failsafe);
      window.removeEventListener("scroll", observe);
      window.removeEventListener("resize", observe);
      io && io.disconnect();
    };
  }, []);
}

function useParallax(ref, factor = 0.25) {
  React.useEffect(() => {
    if (!ref.current) return;
    let raf = 0;
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        if (!ref.current) return;
        const r = ref.current.getBoundingClientRect();
        const vh = window.innerHeight || 800;
        const t = (vh - r.top) / (vh + r.height);
        const y = (t - 0.5) * 100 * factor;
        ref.current.style.transform = `translate3d(0, ${y.toFixed(2)}px, 0)`;
      });
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => { window.removeEventListener("scroll", onScroll); cancelAnimationFrame(raf); };
  }, [ref, factor]);
}

// ====== Skymotion wordmark (real logo) ======
function Wordmark({ size = 18, invert = false }) {
  // The real logo is "Sky" in blue + "motion" in white/grey with "AERIAL CINEMATOGRAPHY AMSTERDAM" tagline.
  // Aspect ratio of the source PNG is 1500×562 ≈ 2.67.
  const h = size * 2.4;
  const w = h * (1500 / 562);
  return (
    <img
      src="assets/logo.png"
      alt="Skymotion — Aerial Cinematography Amsterdam"
      style={{
        height: h,
        width: w,
        display: "block",
        filter: invert ? "invert(1)" : "none",
      }}
    />
  );
}

// ====== Top nav ======
function TopBar({ lang, setLang }) {
  const c = window.COPY[lang];
  return (
    <header style={{
      position: "fixed", top: 0, left: 0, right: 0, zIndex: 50,
      padding: "20px 32px",
      display: "grid", gridTemplateColumns: "1fr auto 1fr", alignItems: "center",
      pointerEvents: "none",
      mixBlendMode: "difference",
    }}>
      <div style={{ pointerEvents: "auto" }}>
        <Wordmark size={18} />
      </div>
      <nav style={{ display: "flex", gap: 28, justifyContent: "center", pointerEvents: "auto" }} className="micro">
        <a href="#work">{c.nav.work}</a>
        <a href="#services">{c.nav.services}</a>
        <a href="#equipment">{c.nav.equipment}</a>
        <a href="#about">{c.nav.about}</a>
        <a href="#contact">{c.nav.contact}</a>
      </nav>
      <div data-magnetic="1" style={{ display: "flex", justifyContent: "flex-end", pointerEvents: "auto" }}>
        <LangSwitch lang={lang} setLang={setLang} />
      </div>
    </header>
  );
}

function LangSwitch({ lang, setLang }) {
  const Btn = ({ k, label }) => (
    <button
      onClick={() => setLang(k)}
      className="micro"
      style={{
        padding: "6px 10px",
        color: lang === k ? "#fff" : "#8a8780",
        background: "transparent",
        position: "relative",
      }}
    >
      {label}
      {lang === k && (
        <span style={{
          position: "absolute", left: 6, right: 6, bottom: 2, height: 1, background: "#fff",
        }} />
      )}
    </button>
  );
  return (
    <div className="micro" style={{
      display: "inline-flex", alignItems: "center",
      border: "1px solid var(--hair)",
      padding: "0 2px",
    }}>
      <Btn k="en" label="EN" />
      <span style={{ width: 1, height: 14, background: "var(--hair)" }} />
      <Btn k="nl" label="NL" />
    </div>
  );
}

// ====== Section header used across the page ======
function SectionHead({ kicker, title, lead, align = "left" }) {
  return (
    <div className="container" style={{ paddingTop: 160, paddingBottom: 64 }}>
      <div style={{
        display: "grid",
        gridTemplateColumns: "minmax(180px, 220px) 1fr",
        gap: 64,
        alignItems: "start",
      }}>
        <div className="micro rv" style={{ paddingTop: 12 }}>{kicker}</div>
        <div>
          <h2 className="rv rv-2" style={{
            margin: 0,
            fontFamily: "Inter Tight, sans-serif",
            fontWeight: 600,
            fontSize: "clamp(48px, 6vw, 96px)",
            letterSpacing: "-0.035em",
            lineHeight: 0.96,
            maxWidth: 1200,
          }}>{title}</h2>
          {lead && (
            <p className="rv rv-3" style={{
              marginTop: 32, marginBottom: 0,
              maxWidth: 620,
              color: "var(--muted)",
              fontSize: 17, lineHeight: 1.5,
              fontWeight: 300,
            }}>{lead}</p>
          )}
        </div>
      </div>
    </div>
  );
}

// ====== Scroll-cue arrow ======
function ScrollCue({ label = "Scroll" }) {
  return (
    <div style={{
      position: "absolute", left: "50%", bottom: 36, transform: "translateX(-50%)",
      display: "flex", flexDirection: "column", alignItems: "center", gap: 14,
      color: "var(--muted)",
    }}>
      <span className="micro">{label}</span>
      <svg width="1" height="44" viewBox="0 0 1 44" style={{ overflow: "visible" }}>
        <line x1="0.5" y1="0" x2="0.5" y2="44" stroke="rgba(255,255,255,0.18)" />
        <line x1="0.5" y1="0" x2="0.5" y2="14" stroke="#fff" className="cue-line" />
      </svg>
    </div>
  );
}

// ====== Sound / mute toggle for the hero ======
function SoundToggle({ muted, onToggle, onLabel, offLabel }) {
  return (
    <button
      onClick={onToggle}
      style={{
        display: "inline-flex", alignItems: "center", gap: 12,
        border: "1px solid var(--hair-strong)",
        padding: "12px 16px",
        background: "rgba(0,0,0,0.35)",
        backdropFilter: "blur(6px)",
        WebkitBackdropFilter: "blur(6px)",
      }}
      className="micro"
    >
      <SpeakerIcon muted={muted} />
      <span>{muted ? offLabel : onLabel}</span>
    </button>
  );
}

function SpeakerIcon({ muted }) {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
      <path d="M1 5 H4 L8 2 V12 L4 9 H1 Z" stroke="#fff" strokeWidth="1" />
      {muted ? (
        <g stroke="#fff" strokeWidth="1">
          <line x1="10" y1="5" x2="13" y2="9" />
          <line x1="13" y1="5" x2="10" y2="9" />
        </g>
      ) : (
        <g stroke="#fff" strokeWidth="1" fill="none">
          <path d="M10.5 5.2 Q12 7 10.5 8.8" />
          <path d="M11.8 3.6 Q14 7 11.8 10.4" opacity="0.5" />
        </g>
      )}
    </svg>
  );
}

// ====== Image frame — real photo if `src` present, striped placeholder otherwise ======
function ImagePlaceholder({ label, ratio = "16/9", strong = false, children, code, src, objectPosition = "center" }) {
  return (
    <div className={src ? "" : (strong ? "striped-strong" : "striped")} style={{
      position: "relative",
      width: "100%",
      aspectRatio: ratio,
      overflow: "hidden",
      border: "1px solid var(--hair)",
      background: src ? "#0a0908" : undefined,
    }}>
      {src && (
        <img
          src={src}
          alt={label}
          style={{
            position: "absolute", inset: 0,
            width: "100%", height: "100%",
            objectFit: "cover",
            objectPosition,
            filter: "saturate(0.8) contrast(1.05)",
          }}
        />
      )}
      {!src && (
        <>
          <Tick pos="tl" /><Tick pos="tr" /><Tick pos="bl" /><Tick pos="br" />
          <div className="micro" style={{
            position: "absolute", top: 12, left: 12,
            color: "rgba(255,255,255,0.55)",
          }}>{code || "PLACEHOLDER"}</div>
          <div className="micro" style={{
            position: "absolute", bottom: 12, left: 12, right: 12,
            color: "rgba(255,255,255,0.55)",
            display: "flex", justifyContent: "space-between", gap: 12,
          }}>
            <span>{label}</span>
            <span>↗ DROP STILL</span>
          </div>
        </>
      )}
      {children}
    </div>
  );
}
function Tick({ pos }) {
  const s = { position: "absolute", width: 10, height: 10, borderColor: "rgba(255,255,255,0.35)", borderStyle: "solid", borderWidth: 0 };
  if (pos === "tl") Object.assign(s, { top: 0, left: 0, borderTopWidth: 1, borderLeftWidth: 1 });
  if (pos === "tr") Object.assign(s, { top: 0, right: 0, borderTopWidth: 1, borderRightWidth: 1 });
  if (pos === "bl") Object.assign(s, { bottom: 0, left: 0, borderBottomWidth: 1, borderLeftWidth: 1 });
  if (pos === "br") Object.assign(s, { bottom: 0, right: 0, borderBottomWidth: 1, borderRightWidth: 1 });
  return <span style={s} />;
}

// expose
Object.assign(window, {
  useReveal, useParallax,
  Wordmark, TopBar, LangSwitch, SectionHead,
  ScrollCue, SoundToggle, ImagePlaceholder,
});
