// Pineapple Robot — full hi-fi site, premium tiki-bar feel
const { useState, useEffect, useRef } = React;

// ========== NAV ==========
const Nav = () => {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);

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

  // Lock body scroll while drawer is open
  useEffect(() => {
    if (menuOpen) {
      const prev = document.body.style.overflow;
      document.body.style.overflow = "hidden";
      return () => { document.body.style.overflow = prev; };
    }
  }, [menuOpen]);

  // Close drawer on resize past mobile breakpoint
  useEffect(() => {
    const onResize = () => { if (window.innerWidth > 720) setMenuOpen(false); };
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);

  const links = [
    { label: "Cocktails", href: "#cocktails" },
    { label: "Pizza Paradiso", href: "https://pizzaparadiso.com", external: true },
    { label: "Private Events", href: "#events" },
    { label: "Visit Us", href: "#visit" },
  ];

  const closeAnd = (fn) => () => { setMenuOpen(false); fn && fn(); };

  return (
    <>
      <nav className={`pr-nav ${scrolled || menuOpen ? "pr-nav--scrolled" : ""}`}>
        <div className="wrap pr-nav__row">
          <a href="#top" className="pr-nav__logo" onClick={closeAnd()}>
            <img src="assets/brand-logo-transparent.png" alt="Pineapple Robot" />
          </a>

          {/* Desktop links */}
          <div className="pr-nav__links">
            {links.map(l => (
              <a key={l.label} href={l.href} target={l.external ? "_blank" : undefined} rel={l.external ? "noopener noreferrer" : undefined}>{l.label}</a>
            ))}
          </div>

          {/* Desktop right side — mirrors the mobile bottom bar (MobileBottomBar
              in sections.jsx): same two destinations, same cream/accent split.
              Keep the URLs in sync with that component. */}
          <div className="pr-nav__actions">
            <a href="https://www.order.store/store/pizza-paradiso/EkcG-5cMVvGXKejiQ7Q8Xg" target="_blank" rel="noopener noreferrer" className="btn btn--ghost pr-nav__order">Delivery ↗</a>
            <a href="https://pizzaparadiso.toast.site/order" target="_blank" rel="noopener noreferrer" className="btn pr-nav__order">Takeout ↗</a>
          </div>

          {/* Mobile hamburger */}
          <button
            type="button"
            className="pr-nav__burger"
            onClick={() => setMenuOpen(o => !o)}
            aria-label={menuOpen ? "Close menu" : "Open menu"}
            aria-expanded={menuOpen}
          >
            <span /><span /><span />
          </button>
        </div>
      </nav>

      {/* Mobile drawer — rendered as sibling of nav so its position:fixed is
          relative to the viewport, not the nav (the nav uses backdrop-filter
          which would otherwise become its containing block) */}
      <div className={`pr-nav__drawer ${menuOpen ? "is-open" : ""}`} aria-hidden={!menuOpen}>
        <div className="pr-nav__drawer-inner">
          <div className="pr-nav__drawer-links">
            {links.map(l => (
              <a key={l.label} href={l.href} target={l.external ? "_blank" : undefined} rel={l.external ? "noopener noreferrer" : undefined} onClick={closeAnd()}>{l.label}</a>
            ))}
          </div>
          <div className="pr-nav__drawer-foot">
            <a href="https://pizzaparadiso.toast.site/order" target="_blank" rel="noopener noreferrer" className="btn pr-nav__drawer-order" onClick={closeAnd()}>
              Order food ↗
            </a>
          </div>
        </div>
      </div>
    </>
  );
};

// Small pineapple glyph for the nav corner
const PineappleMark = ({ size = 32 }) => (
  <svg width={size} height={size * 1.2} viewBox="0 0 32 38" xmlns="http://www.w3.org/2000/svg">
    <path d="M16 2 L11 12 L16 9 L21 12 Z" fill="var(--jungle)" stroke="var(--ink)" strokeWidth="1.2" strokeLinejoin="round" />
    <path d="M16 4 L8 14 L14 11 Z" fill="var(--jungle-deep)" stroke="var(--ink)" strokeWidth="1.2" strokeLinejoin="round" />
    <path d="M16 4 L24 14 L18 11 Z" fill="var(--jungle-deep)" stroke="var(--ink)" strokeWidth="1.2" strokeLinejoin="round" />
    <rect x="6" y="11" width="20" height="24" rx="3" fill="var(--gold)" stroke="var(--ink)" strokeWidth="1.5" />
    <line x1="6" y1="17" x2="26" y2="17" stroke="var(--gold-deep)" strokeWidth="1" opacity="0.6" />
    <line x1="6" y1="23" x2="26" y2="23" stroke="var(--gold-deep)" strokeWidth="1" opacity="0.6" />
    <line x1="6" y1="29" x2="26" y2="29" stroke="var(--gold-deep)" strokeWidth="1" opacity="0.6" />
    <line x1="11" y1="11" x2="11" y2="35" stroke="var(--gold-deep)" strokeWidth="1" opacity="0.6" />
    <line x1="16" y1="11" x2="16" y2="35" stroke="var(--gold-deep)" strokeWidth="1" opacity="0.6" />
    <line x1="21" y1="11" x2="21" y2="35" stroke="var(--gold-deep)" strokeWidth="1" opacity="0.6" />
  </svg>
);

// ========== HERO ==========
const Hero = ({ heroLayout, copyTone }) => {
  const [singing, setSinging] = useState(false);

  // Auto-fade back to idle ~4s after activation
  useEffect(() => {
    if (!singing) return;
    const id = setTimeout(() => setSinging(false), 4000);
    return () => clearTimeout(id);
  }, [singing]);

  const headlines = {
    chill:  ["Eat.", "Sip.", "Sing."],
    hype:   ["Drink.", "Sing.", "Be heard."],
    poetic: ["Aloha,", "neon", "soul."],
  };
  const subs = {
    chill:  "A late-night tiki bar in Honokowai. Karaoke nightly, cocktails by the sea, pizza under the same roof.",
    hype:   "West Maui's loudest karaoke bar. Tiki cocktails 'til 1:30 AM. Pizza Paradiso under the same roof. You're already family.",
    poetic: "A small bar with a big voice. Tropical drinks, late-night songs, slices of paradise — all in one place on the west side of Maui.",
  };
  const lines = headlines[copyTone] || headlines.hype;
  const sub = subs[copyTone] || subs.hype;

  return (
    <section id="top" style={{
      position: "relative",
      minHeight: "100vh",
      background: `
        radial-gradient(ellipse at 20% 10%, rgba(232, 181, 71, 0.20), transparent 50%),
        radial-gradient(ellipse at 80% 90%, rgba(217, 75, 63, 0.16), transparent 50%),
        var(--bg)
      `,
      overflow: "hidden",
    }} className="grain">
      <BackgroundLeaves />

      <div className="wrap pr-hero__grid" style={{
        position: "relative", zIndex: 2,
        paddingTop: 140, paddingBottom: 80,
        minHeight: "100vh",
        display: "grid",
        gridTemplateColumns: heroLayout === "stacked" ? "1fr" : "1.15fr 0.85fr",
        gap: 60, alignItems: "center",
      }}>
        <div className="pr-hero__copy" style={{ display: "grid", gap: 28, justifyItems: heroLayout === "stacked" ? "center" : "start", textAlign: heroLayout === "stacked" ? "center" : "left" }}>
          <div className="rule pr-hero__eyebrow" style={{ width: heroLayout === "stacked" ? "min(420px, 80%)" : 320 }}>
            ★ Honokowai · Maui · Open Daily ★
          </div>
          <h1 className="display pr-hero__h1" style={{
            fontSize: heroLayout === "stacked" ? "clamp(80px, 14vw, 240px)" : "clamp(72px, 10vw, 180px)",
            color: "var(--fg)",
          }}>
            {lines[0]}<br/>
            <span style={{ color: "var(--accent)" }}>{lines[1]}</span><br/>
            <span style={{ color: "var(--accent-2)" }}>{lines[2]}</span>
          </h1>
          <p style={{ maxWidth: 540, fontSize: 19, lineHeight: 1.55, color: "var(--fg-soft)", textWrap: "pretty" }}>
            {sub}
          </p>
          <div className="pr-cta-solo" style={{ display: "flex", gap: 12, flexWrap: "wrap", alignItems: "center" }}>
            <a href="#cocktails" className="btn">See the drink menu →</a>
          </div>
        </div>

        {heroLayout !== "stacked" && (
          <div style={{ position: "relative", display: "grid", placeItems: "center" }}>
            <HeroPhoto />
          </div>
        )}
      </div>

      {/* Bottom marquee */}
      <div style={{
        position: "relative", zIndex: 2,
        background: "var(--accent)", color: "var(--cream)",
        borderTop: "2.5px solid var(--ink)",
        borderBottom: "2.5px solid var(--ink)",
        padding: "18px 0", overflow: "hidden",
      }}>
        <div className="marquee" style={{ fontFamily: "var(--display)", fontSize: 30, color: "var(--cream)" }}>
          {Array.from({ length: 4 }).map((_, i) => (
            <div key={i} style={{ display: "flex", gap: 32, paddingRight: 32, alignItems: "center" }}>
              <span>Karaoke nightly · 9pm – 1:30am</span>
              <Diamond />
              <span style={{ color: "var(--accent-2)" }}>Happy Hour 12 – 5</span>
              <Diamond />
              <span>Mai Tai Mondays</span>
              <Diamond />
              <span style={{ color: "var(--accent-2)" }}>Open 7 days</span>
              <Diamond />
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

const Diamond = () => (
  <svg width="14" height="14" viewBox="0 0 14 14"><path d="M7 1 L13 7 L7 13 L1 7 Z" fill="var(--accent-2)" /></svg>
);

// ========== HERO VIDEO ==========
// Square hero video — looping karaoke-night clip. object-fit: cover crops the
// 3:2 source to the square frame.
//
// Deliberately NO poster image: this slot shows the video and nothing else.
// The frame carries the site's ink background so the box reads as part of the
// design while the first frame decodes, rather than flashing white.
//
// header-video.mp4 is a 960x640 encode of the 1620x1080 original
// (header-video.mov, kept in the repo but excluded from deploys via
// .vercelignore). `cover` scales by HEIGHT here since the source is wider than
// the square, so 640px of height covers the 520px slot with nothing upscaled —
// don't re-encode below 520px tall or the on-screen lyrics go soft.
//
// AUTOPLAY — this must never show a play button. Four layers, because no
// single one holds everywhere:
//
//   1. The file itself has NO AUDIO TRACK. WebKit treats a silent video like
//      an animated GIF, which is its most permissive autoplay class — more
//      permissive than a muted video that still carries audio. Re-encodes must
//      keep `-an` or this protection is lost.
//   2. muted/playsInline/autoplay set as DOM *properties*, not just JSX
//      attributes — iOS reads the property.
//   3. Relentless retry: every media event, every visibility/focus change,
//      scrolling into view, and a slow poll. Also the first user gesture
//      ANYWHERE on the page (tap, scroll, key) — so the video starts from the
//      user touching anything at all, never from finding a play control.
//   4. If playback still hasn't advanced after ~1.6s, fade in
//      assets/header-loop.webp — an animated WebP of the same clip. Animated
//      images are exempt from every autoplay policy, so the frame keeps moving
//      even in iOS Low Power Mode, Low Data Mode, and locked-down in-app
//      browsers, where the OS refuses <video> playback outright and nothing on
//      the page can override it. Loaded lazily: costs nothing unless needed,
//      and fades back out if the video does eventually start.
const HeroPhoto = () => {
  const videoRef = useRef(null);
  const [showLoop, setShowLoop] = useState(false);

  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;

    // Properties, not attributes — iOS checks these.
    v.muted = true;
    v.defaultMuted = true;
    v.volume = 0;
    v.autoplay = true;
    v.playsInline = true;
    v.setAttribute("webkit-playsinline", "true");

    let disposed = false;
    const tryPlay = () => {
      if (disposed) return;
      v.muted = true; // a stray unmute would re-arm the block
      const p = v.play();
      if (p && p.catch) p.catch(() => {});
    };

    // Anything that can mean "maybe it can start now".
    const MEDIA = ["loadedmetadata", "loadeddata", "canplay", "canplaythrough",
                   "pause", "stalled", "suspend", "waiting"];
    MEDIA.forEach((e) => v.addEventListener(e, tryPlay));

    // Any gesture anywhere unlocks playback — capture phase so it fires even
    // when a child stops propagation, passive so it never blocks scrolling.
    const GESTURES = ["pointerdown", "touchstart", "touchend", "mousedown",
                      "keydown", "click", "scroll", "wheel"];
    const gestureOpts = { passive: true, capture: true };
    GESTURES.forEach((e) => document.addEventListener(e, tryPlay, gestureOpts));

    // Returning to the tab / app, or restoring from the bfcache.
    const onVisible = () => { if (!document.hidden) tryPlay(); };
    document.addEventListener("visibilitychange", onVisible);
    window.addEventListener("pageshow", tryPlay);
    window.addEventListener("focus", tryPlay);

    // Scrolled into view (some browsers only allow playback while visible).
    let io = null;
    if ("IntersectionObserver" in window) {
      io = new IntersectionObserver((entries) => {
        entries.forEach((en) => { if (en.isIntersecting) tryPlay(); });
      });
      io.observe(v);
    }

    // Poll: is the clock actually advancing? `!paused` alone lies — a blocked
    // video can report playing while sitting at 0. Four dead ticks (~1.6s) is
    // the cue to bring up the animated fallback.
    let lastTime = -1;
    let dead = 0;
    const poll = setInterval(() => {
      if (disposed) return;
      const advancing = !v.paused && v.currentTime !== lastTime;
      lastTime = v.currentTime;
      if (advancing) { dead = 0; setShowLoop(false); return; }
      tryPlay();
      dead += 1;
      if (dead >= 4) setShowLoop(true);
    }, 400);

    tryPlay();

    return () => {
      disposed = true;
      clearInterval(poll);
      MEDIA.forEach((e) => v.removeEventListener(e, tryPlay));
      GESTURES.forEach((e) => document.removeEventListener(e, tryPlay, gestureOpts));
      document.removeEventListener("visibilitychange", onVisible);
      window.removeEventListener("pageshow", tryPlay);
      window.removeEventListener("focus", tryPlay);
      if (io) io.disconnect();
    };
  }, []);

  const fill = {
    position: "absolute",
    inset: 0,
    width: "100%",
    height: "100%",
    objectFit: "cover",
    objectPosition: "center 40%",
    display: "block",
  };

  return (
    <div style={{
      position: "relative",
      width: "100%",
      maxWidth: 520,
      aspectRatio: "1 / 1",
      borderRadius: 10,
      overflow: "hidden",
      background: "var(--ink)",
      boxShadow: "0 24px 48px -12px rgba(0,0,0,0.35), 0 8px 16px -8px rgba(0,0,0,0.25)",
    }}>
      <video
        ref={videoRef}
        src="assets/header-video.mp4"
        autoPlay
        muted
        loop
        playsInline
        preload="auto"
        disableRemotePlayback
        aria-label="Karaoke night at Pineapple Robot — a looping clip of the bar and crowd"
        style={fill}
      />
      {showLoop && (
        <img
          src="assets/header-loop.webp"
          alt=""
          aria-hidden="true"
          style={{ ...fill, animation: "prLoopIn 400ms ease-out both" }}
        />
      )}
    </div>
  );
};

// ========== HERO EQ ==========
// Large audio equalizer visualization. Two states:
//   - idle: slow gentle pulse, mostly mustard with occasional coral, low amplitude
//   - active: rapid full-height movement, all three colors
// Pure CSS — each bar gets a per-bar phase delay via inline style; the active
// class swaps the keyframe set and timing in one step.
const HeroEQ = ({ active }) => {
  // 24 bars, varied widths feel less mechanical than a perfect grid.
  // Color rotation: mustard dominant, coral accent, cream highlight.
  // In idle, only mustard + occasional coral animate; cream sits dim.
  const COUNT = 24;
  const palette = (i) => {
    // Mostly mustard, every 5th coral, every 8th cream.
    if (i % 8 === 3) return "cream";
    if (i % 5 === 2 || i % 7 === 4) return "coral";
    return "mustard";
  };
  // Per-bar pseudo-random phase + amplitude seeds, deterministic.
  const seeds = Array.from({ length: COUNT }, (_, i) => {
    const s = Math.sin(i * 12.9898) * 43758.5453;
    return s - Math.floor(s); // 0..1
  });

  return (
    <div className={`eq ${active ? "eq--active" : "eq--idle"}`}
      style={{ position: "relative", width: "100%", maxWidth: 520, height: 460, display: "flex", alignItems: "flex-end", justifyContent: "center", gap: 6, padding: "20px 4px" }}>
      {/* baseline rule under bars */}
      <div style={{ position: "absolute", left: 0, right: 0, bottom: 18, height: 2.5, background: "var(--ink)", opacity: 0.85 }} />

      {Array.from({ length: COUNT }).map((_, i) => {
        const tone = palette(i);
        const colorVar = tone === "coral" ? "var(--accent)" : tone === "cream" ? "var(--cream)" : "var(--accent-2)";
        // Slight width variation for visual rhythm
        const w = 12 + (i % 3) * 2; // 12, 14, 16
        const delay = `${(seeds[i] * -1.6).toFixed(3)}s`; // negative delays so bars start mid-cycle
        const ampJitter = 0.85 + seeds[i] * 0.3; // 0.85..1.15 multiplier in active
        return (
          <div key={i} className={`eq__bar eq__bar--${tone}`}
            style={{
              width: w,
              background: colorVar,
              border: "2.5px solid var(--ink)",
              borderRadius: 2,
              animationDelay: delay,
              ['--amp']: ampJitter,
            }}
          />
        );
      })}

      <style>{`
        .eq__bar {
          height: 12%;
          transform-origin: 50% 100%;
          will-change: transform, height;
        }

        /* ============ IDLE ============ */
        /* Mustard bars: slow gentle pulse, low amplitude. */
        @keyframes eq-idle-mustard {
          0%, 100% { height: 14%; }
          50%      { height: 26%; }
        }
        /* Coral bars: occasional taller pulse, slightly off-tempo. */
        @keyframes eq-idle-coral {
          0%, 100% { height: 18%; }
          40%      { height: 38%; }
          60%      { height: 22%; }
        }
        /* Cream bars: dim, barely moving in idle. */
        @keyframes eq-idle-cream {
          0%, 100% { height: 10%; }
          50%      { height: 16%; }
        }

        .eq--idle .eq__bar--mustard {
          animation: eq-idle-mustard 2.6s ease-in-out infinite;
        }
        .eq--idle .eq__bar--coral {
          animation: eq-idle-coral 3.2s ease-in-out infinite;
        }
        .eq--idle .eq__bar--cream {
          animation: eq-idle-cream 2.4s ease-in-out infinite;
          opacity: 0.55;
        }

        /* ============ ACTIVE ============ */
        /* Three different active curves so neighbors don't sync up.
           Heights peak near 90–100% and use the per-bar --amp multiplier
           to vary peak height bar-to-bar. */
        @keyframes eq-active-a {
          0%   { height: calc(30% * var(--amp)); }
          15%  { height: calc(95% * var(--amp)); }
          30%  { height: calc(45% * var(--amp)); }
          50%  { height: calc(80% * var(--amp)); }
          70%  { height: calc(35% * var(--amp)); }
          85%  { height: calc(70% * var(--amp)); }
          100% { height: calc(30% * var(--amp)); }
        }
        @keyframes eq-active-b {
          0%   { height: calc(50% * var(--amp)); }
          20%  { height: calc(70% * var(--amp)); }
          40%  { height: calc(100% * var(--amp)); }
          60%  { height: calc(40% * var(--amp)); }
          80%  { height: calc(85% * var(--amp)); }
          100% { height: calc(50% * var(--amp)); }
        }
        @keyframes eq-active-c {
          0%   { height: calc(40% * var(--amp)); }
          25%  { height: calc(60% * var(--amp)); }
          50%  { height: calc(30% * var(--amp)); }
          75%  { height: calc(90% * var(--amp)); }
          100% { height: calc(40% * var(--amp)); }
        }

        .eq--active .eq__bar--mustard {
          animation: eq-active-a 0.55s ease-in-out infinite;
        }
        .eq--active .eq__bar--coral {
          animation: eq-active-b 0.42s ease-in-out infinite;
        }
        .eq--active .eq__bar--cream {
          animation: eq-active-c 0.48s ease-in-out infinite;
          opacity: 1;
        }

        /* Smooth opacity handoff between states */
        .eq__bar { transition: opacity .5s ease; }

        @media (prefers-reduced-motion: reduce) {
          .eq__bar { animation: none !important; }
        }
      `}</style>
    </div>
  );
};

const BackgroundLeaves = () => (
  <div className="pr-hero__leaves" aria-hidden="true">
    <svg className="leaf-decor" style={{ top: 80, left: -60, width: 320 }} viewBox="0 0 200 200">
      <g style={{ transformOrigin: "100px 100px", transform: "rotate(-25deg)" }}>
        <path d="M100 20 Q 60 80 100 180 Q 140 80 100 20" fill="var(--jungle)" />
        <path d="M100 30 L100 170" stroke="var(--jungle-deep)" strokeWidth="1.5" />
        {Array.from({ length: 8 }).map((_, i) => {
          const y = 50 + i * 16;
          return <path key={i} d={`M100 ${y} Q ${75 - i*2} ${y + 8} ${65 - i*3} ${y + 14}`} stroke="var(--jungle-deep)" strokeWidth="1.5" fill="none" />;
        })}
      </g>
    </svg>
    <svg className="leaf-decor" style={{ bottom: 60, right: -80, width: 360, transform: "scaleX(-1)" }} viewBox="0 0 200 200">
      <g style={{ transformOrigin: "100px 100px", transform: "rotate(20deg)" }}>
        <path d="M100 20 Q 60 80 100 180 Q 140 80 100 20" fill="var(--jungle)" />
        <path d="M100 30 L100 170" stroke="var(--jungle-deep)" strokeWidth="1.5" />
      </g>
    </svg>
  </div>
);

window.Nav = Nav;
window.Hero = Hero;
window.PineappleMark = PineappleMark;
