/* =========================================================
   Shared helpers, icons, Nav, Hero, Story, Gallery
   ========================================================= */
const { useState, useEffect, useRef, useCallback } = React;

/* ---------- Leaf + icons ---------- */
function Leaf({ size = 18, className = "", style }) {
  return (
    <svg className={"leaf " + className} style={style} width={size} height={size}
         viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <path d="M12 2C5 7 4 14 5 21c7 1 14-3 17-11C18 7 15 4 12 2Z"
            fill="currentColor" opacity="0.9" />
      <path d="M7 19C10 14 14 10 19 7" stroke="#f6efdf" strokeWidth="1.2"
            strokeLinecap="round" opacity="0.7" />
    </svg>
  );
}

function Sprig({ size = 22, color = "currentColor", style, className }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" style={style}
         className={className} aria-hidden="true">
      <path d="M12 22V5" stroke={color} strokeWidth="1.4" strokeLinecap="round" />
      <path d="M12 9C9 9 7 7 6 4c3 0 5 1 6 4Z" fill={color} opacity="0.85" />
      <path d="M12 13c3 0 5-2 6-5-3 0-5 1-6 4Z" fill={color} opacity="0.85" />
      <path d="M12 17c-3 0-5-2-6-5 3 0 5 1 6 4Z" fill={color} opacity="0.85" />
    </svg>
  );
}

/* simple line icons for BM cards */
const BMIcons = {
  water: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3s6 6.5 6 11a6 6 0 0 1-12 0c0-4.5 6-11 6-11Z"/></svg>),
  dust: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"><path d="M3 8h13M3 12h17M5 16h12M8 20h9"/></svg>),
  gift: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"><rect x="3" y="9" width="18" height="12" rx="1.5"/><path d="M3 13h18M12 9v12M12 9c-1.5-4-6-4-6-1.5S9 9 12 9Zm0 0c1.5-4 6-4 6-1.5S15 9 12 9Z"/></svg>),
  bike: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="6" cy="17" r="3.5"/><circle cx="18" cy="17" r="3.5"/><path d="M6 17l3.5-7H15l3 7M9.5 10h5"/></svg>),
  leaf: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M5 19C4 12 8 5 19 5c1 11-6 15-14 14Z"/><path d="M5 19c4-6 8-9 12-11"/></svg>),
  sun: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M2 12h2M20 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4"/></svg>),
  money: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><path d="M9.5 14.5c0 1 1 1.7 2.5 1.7s2.5-.6 2.5-1.8c0-2.6-5-1.4-5-4 0-1 1-1.7 2.5-1.7s2.5.7 2.5 1.6M12 7v1.5M12 16v1.5"/></svg>),
  health: (p) => (<svg viewBox="0 0 24 24" width={p.s} height={p.s} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12h4l2 5 4-12 2 7h6"/></svg>),
};

/* ---------- scroll reveal ---------- */
function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll(".reveal");
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("is-in"); io.unobserve(e.target); } });
    }, { threshold: 0.12 });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  });
}

/* ---------- placeholder image ---------- */
function Ph({ label, className = "", style }) {
  return <div className={"ph " + className} data-label={label} style={style} />;
}

/* ---------- divider ---------- */
function Divider() {
  return (<div className="divider"><Sprig size={20} /></div>);
}

/* =====================  NAV  ===================== */
const NAV_LINKS = [
  ["story", "Our Story"],
  ["gallery", "Gallery"],
  ["batman", "Batman"],
  ["schedule", "Schedule"],
  ["burningman", "Burning Man"],
  ["travel", "Getting There"],
  ["faq", "FAQ"],
];

function Nav() {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  const [active, setActive] = useState("");

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 24);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  useEffect(() => {
    const ids = ["story", "gallery", "batman", "schedule", "burningman", "travel", "rsvp", "faq"];
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) setActive(e.target.id); });
    }, { rootMargin: "-45% 0px -50% 0px" });
    ids.forEach((id) => { const el = document.getElementById(id); if (el) io.observe(el); });
    return () => io.disconnect();
  }, []);

  const go = (e, id) => {
    e.preventDefault();
    setOpen(false);
    document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" });
  };

  return (
    <header className={"nav" + (scrolled ? " is-scrolled" : "")}>
      <div className="nav__inner">
        <a href="#top" className="nav__brand" onClick={(e) => go(e, "top")}>
          <span className="nav__brand-mark">Lily <span className="nav__brand-amp">&amp;</span> Igor</span>
          <span className="nav__brand-tag">perfectos barabectos</span>
        </a>
        <nav className="nav__links">
          {NAV_LINKS.map(([id, label]) => (
            <a key={id} href={"#" + id} onClick={(e) => go(e, id)}
               className={"nav__link" + (active === id ? " is-active" : "")}>{label}</a>
          ))}
          <a href="#rsvp" onClick={(e) => go(e, "rsvp")} className="btn btn--solid nav__cta">RSVP</a>
        </nav>
        <button className="nav__toggle" onClick={() => setOpen((o) => !o)} aria-label="Menu">
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
            {open ? <path d="M6 6l12 12M18 6L6 18" /> : <path d="M3 7h18M3 12h18M3 17h18" />}
          </svg>
        </button>
      </div>
      <div className={"mobile-menu" + (open ? " is-open" : "")}>
        {NAV_LINKS.map(([id, label]) => (
          <a key={id} href={"#" + id} onClick={(e) => go(e, id)}>{label}</a>
        ))}
        <a href="#rsvp" onClick={(e) => go(e, "rsvp")} style={{ color: "var(--green-700)" }}>RSVP →</a>
      </div>
    </header>
  );
}

/* =====================  HERO  ===================== */
const WEDDING_DATE = new Date("2026-09-03T18:00:00-07:00");

function Countdown() {
  const calc = () => {
    const diff = Math.max(0, WEDDING_DATE - new Date());
    const d = Math.floor(diff / 86400000);
    const h = Math.floor((diff % 86400000) / 3600000);
    const m = Math.floor((diff % 3600000) / 60000);
    const s = Math.floor((diff % 60000) / 1000);
    return { d, h, m, s };
  };
  const [t, setT] = useState(calc());
  useEffect(() => { const id = setInterval(() => setT(calc()), 1000); return () => clearInterval(id); }, []);
  const units = [["Days", t.d], ["Hrs", t.h], ["Min", t.m], ["Sec", t.s]];
  return (
    <div className="countdown">
      {units.map(([label, val]) => (
        <div className="countdown__unit" key={label}>
          <div className="countdown__num">{String(val).padStart(2, "0")}</div>
          <div className="countdown__label">{label}</div>
        </div>
      ))}
    </div>
  );
}

function Hero() {
  const leaves = [
    { top: "11%", left: "4%", size: 60, rot: -20 },
    { top: "16%", right: "5%", size: 84, rot: 30 },
    { bottom: "14%", left: "4%", size: 70, rot: 160 },
    { bottom: "12%", right: "4%", size: 54, rot: -150 },
  ];
  const go = (e, id) => { e.preventDefault(); document.getElementById(id)?.scrollIntoView({ behavior: "smooth" }); };
  return (
    <section className="hero" id="top">
      <div className="hero__leaves">
        {leaves.map((l, i) => (
          <Sprig key={i} size={l.size} color="var(--green-500)"
                 className="hero__leaf"
                 style={{ top: l.top, left: l.left, right: l.right, bottom: l.bottom, transform: `rotate(${l.rot}deg)` }} />
        ))}
      </div>
      <div className="hero__inner wrap">
        <div className="hero__topline">
          <Leaf size={16} /> We're getting hitched on the playa <Leaf size={16} style={{ transform: "scaleX(-1)" }} />
        </div>
        <h1 className="hero__names">
          <span className="hero__name">Lily</span>
          <span className="hero__amp">&amp;</span>
          <span className="hero__name">Igor</span>
        </h1>
        <div className="hero__sub">are getting married on the playa</div>
        <div className="hero__meta">
          <span>Black Rock City, NV</span>
          <span className="dot"></span>
          <span>September 3, 2026</span>
          <span className="dot"></span>
          <span>Burning Man</span>
        </div>
        <Countdown />
        <div className="hero__cta">
          <a href="#rsvp" className="btn btn--solid" onClick={(e) => go(e, "rsvp")}>RSVP</a>
          <a href="#burningman" className="btn btn--ghost" onClick={(e) => go(e, "burningman")}>Burning Man 101</a>
        </div>
      </div>
      <div className="scroll-cue"><span>Scroll</span><span>↓</span></div>
    </section>
  );
}

/* =====================  OUR STORY  ===================== */
const STORY = [
  { title: "Falling fast", body: "One festival turned into late-night chats, shared playlists, and the easy feeling of having known each other for years. When you know, you know.", label: "PHOTO · those first months" },
  { title: "A big leap south", body: "After 14 years in San Francisco, Lily packed up and moved to San Diego in January 2026 — Batman riding shotgun. New city, same person worth crossing the state for.", label: "PHOTO · SF → SD" },
  { title: "Batman's seal of approval", body: "Lily's 15-year-old Yorkie has very high standards and approximately zero patience. He took one look at Igor and decided he'd allow it. The highest honor there is.", label: "PHOTO · batman + igor" },
  { title: "The question", body: "No grand stage — just the two of us, the little dog underfoot, and a question that took about two seconds to answer. (It was yes. Obviously.)", label: "PHOTO · the yes" },
  { title: "Out to the playa", body: "From a chance meeting at LIB to saying 'I do' at Burning Man — we're doing this our way, in the desert, surrounded by the people we love.", label: "PHOTO · this is us" },
];

function Story() {
  return (
    <section className="section" id="story">
      <div className="wrap">
        <div className="story__head reveal">
          <span className="eyebrow">How it started</span>
          <h2 className="section-title">Our Love Story</h2>
          <p className="lede" style={{ margin: "16px auto 0" }}>We met in 2025 and we already know. A festival, a very judgmental Yorkie, and a love that keeps growing — like everything Lily refuses to stop watering.</p>
        </div>
      </div>

      <MeetScrolly />

      <div className="wrap">
        <div className="timeline" style={{ marginTop: "clamp(40px,6vw,80px)" }}>
          {STORY.map((s, i) => (
            <div className="tl-item reveal" key={i}>
              <div className="tl-node"></div>
              <div className="tl-text">
                <h3 className="tl-title">{s.title}</h3>
                <p className="tl-body">{s.body}</p>
              </div>
              <div className="tl-media"><Ph label={s.label} /></div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* =====================  GALLERY  ===================== */
const GALLERY = [
  { cls: "g-a", label: "PHOTO · us on the playa" },
  { cls: "g-b", label: "PHOTO · golden hour" },
  { cls: "g-c", label: "PHOTO · batman" },
  { cls: "g-d", label: "PHOTO · the greenhouse" },
  { cls: "g-e", label: "PHOTO · road trip" },
  { cls: "g-f", label: "PHOTO · art installation" },
  { cls: "g-g", label: "PHOTO · dancing at dusk" },
];

function Gallery() {
  const [idx, setIdx] = useState(null);
  const open = idx !== null;

  const close = useCallback(() => setIdx(null), []);
  const prev = useCallback((e) => { e?.stopPropagation(); setIdx((i) => (i + GALLERY.length - 1) % GALLERY.length); }, []);
  const next = useCallback((e) => { e?.stopPropagation(); setIdx((i) => (i + 1) % GALLERY.length); }, []);

  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === "Escape") close();
      if (e.key === "ArrowLeft") prev();
      if (e.key === "ArrowRight") next();
    };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = ""; };
  }, [open, close, prev, next]);

  return (
    <section className="section section--tint" id="gallery">
      <div className="wrap">
        <div className="gallery__head reveal">
          <span className="eyebrow">Moments</span>
          <h2 className="section-title">The Gallery</h2>
          <p className="lede" style={{ margin: "16px auto 0" }}>A few of our favorites. Tap any photo to open it up.</p>
        </div>
        <div className="gallery-grid reveal">
          {GALLERY.map((g, i) => (
            <button className={"g-item " + g.cls} key={i} onClick={() => setIdx(i)} aria-label={"Open " + g.label}>
              <Ph label={g.label} />
            </button>
          ))}
        </div>
      </div>

      {open && (
        <div className="lightbox" onClick={close}>
          <button className="lb-btn lb-close" onClick={close} aria-label="Close">✕</button>
          <button className="lb-btn lb-prev" onClick={prev} aria-label="Previous">‹</button>
          <button className="lb-btn lb-next" onClick={next} aria-label="Next">›</button>
          <div onClick={(e) => e.stopPropagation()}>
            <div className="lightbox__stage"><Ph label={GALLERY[idx].label} /></div>
            <div className="lightbox__cap">{GALLERY[idx].label.replace("PHOTO · ", "")} — {idx + 1} / {GALLERY.length}</div>
          </div>
        </div>
      )}
    </section>
  );
}

Object.assign(window, { Leaf, Sprig, BMIcons, useReveal, Ph, Divider, Nav, Hero, Story, Gallery });
