/* Prisma landing page — scroll-scrubbed video hero + About + Features. */
const {
  WordsPullUp, WordsPullUpMultiStyle, ScrollRevealText,
  CardReveal, FadeUp, ArrowRight, Check
} = window;
const { useEffect } = React;

const HERO_VIDEO = 'assets/clouds-laptop-scrub.mp4?v=2';
const IDLE_HERO_VIDEO = 'assets/hero-idle-loop.mp4';
const IDLE_LOOP_END = 4;             // before scroll, loop the opening four seconds of the idle clip
const HERO_DURATION = 8;            // seconds
const SCRUB_END = 7.55;             // end the scrub a touch early...
const WHITE_START = 0.82;           // ...and dissolve the last stretch to pure white
const WHITE_END = 0.98;
const SCREEN_WHITE = '#ECEBE6';     // warm white of the laptop screen end-frame
const CANVAS_VIDEO = 'https://d8j0ntlcm91z4.cloudfront.net/user_38xzZboKViGWJOttwIXH07lWA1P/hf_20260406_133058_0504132a-0cf3-4450-a370-8ea3b05c95d4.mp4';

const ICON_STORYBOARD = 'https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzZboKViGWJOttwIXH07lWA1P%2Fhf_20260405_171918_4a5edc79-d78f-4637-ac8b-53c43c220606.png&w=1280&q=85';
const ICON_CRITIQUES = 'https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzZboKViGWJOttwIXH07lWA1P%2Fhf_20260405_171741_ed9845ab-f5b2-4018-8ce7-07cc01823522.png&w=1280&q=85';
const ICON_CAPSULE = 'https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzZboKViGWJOttwIXH07lWA1P%2Fhf_20260405_171809_f56666dc-c099-4778-ad82-9ad4f209567b.png&w=1280&q=85';

const CREAM = '#E1E0CC';
const ABOUT_INK = '#1A1812';     // heading ink on the white screen
const ABOUT_BODY = '#2E2B22';    // body ink on the white screen
const ABOUT_MUTED = '#8A8473';   // muted label on the white screen
const NAV_ITEMS = ['About', 'Work', 'Sessions', 'Inquiries'];

/* ---------------- HERO (scroll-scrubbed video) ---------------- */
function HeroScroll() {
  return (
    <div id="hero-track" style={{ position: 'relative', height: '420vh' }}>
      <div id="hero-sticky" style={{ position: 'sticky', top: 0, height: '100lvh', minHeight: '100dvh', overflow: 'hidden', background: '#000' }}>
        <video id="hero-idle-video"
          autoPlay muted playsInline preload="auto" tabIndex={-1} aria-hidden="true"
          src={IDLE_HERO_VIDEO}
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', opacity: 1, zIndex: 0, willChange: 'opacity' }} />
        <video id="hero-video"
          muted playsInline preload="auto" tabIndex={-1} aria-hidden="true"
          src={HERO_VIDEO}
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', opacity: 0, zIndex: 1, willChange: 'opacity' }} />

        {/* Final-stretch dissolve to a whole-white screen */}
        <div id="hero-white" style={{ position: 'absolute', inset: 0, background: SCREEN_WHITE, opacity: 0, pointerEvents: 'none' }} />

        {/* About copy appears inside the final laptop-screen phase. Designed as a
            screen surface rather than loose type, so the handoff feels intentional. */}
        <div id="hero-about-preview" aria-hidden="true"
          className="absolute inset-0 flex items-center justify-center px-5 sm:px-7 md:px-10"
          style={{ color: ABOUT_INK, opacity: 0, pointerEvents: 'none', zIndex: 6, transform: 'translateY(64px)', willChange: 'opacity, transform' }}>
          <div className="w-full max-w-5xl overflow-hidden rounded-[26px] md:rounded-[34px] border border-[#D8D2BF]/80 bg-[#ECEBE6]/[0.90] shadow-[0_30px_120px_rgba(26,24,18,0.20)] backdrop-blur-sm">
            <div className="flex items-center justify-between border-b border-[#D8D2BF]/70 px-5 py-3 md:px-8 md:py-4">
              <div className="flex items-center gap-3">
                <span className="h-2 w-2 rounded-full bg-[#7A5C3C] shadow-[0_0_0_6px_rgba(122,92,60,0.08)]" />
                <span className="text-[10px] sm:text-xs uppercase tracking-[0.28em]" style={{ color: ABOUT_MUTED }}>Hanmat / About</span>
              </div>
              <span className="hidden sm:inline text-[10px] uppercase tracking-[0.22em]" style={{ color: ABOUT_MUTED }}>Screen 01</span>
            </div>

            <div className="grid gap-5 px-5 py-5 text-left sm:px-7 sm:py-6 md:grid-cols-[0.85fr_1.35fr] md:gap-8 md:px-8 md:py-7 lg:px-10 lg:py-8">
              <div>
                <p className="mb-4 text-[10px] uppercase tracking-[0.24em]" style={{ color: ABOUT_MUTED }}>Profile</p>
                <h2 className="text-2xl leading-[1.05] tracking-[-0.04em] sm:text-3xl md:text-4xl" style={{ color: ABOUT_INK }}>
                  Mat Hanson, <span className="italic font-serif text-[#7A5C3C]">self-confessed geek, let loose with AI.</span>
                </h2>
              </div>

              <div className="grid gap-2.5 sm:grid-cols-2 lg:grid-cols-3">
                {[
                  'Tinker',
                  'Prototype',
                  'Solve practical problems',
                  'Automate the boring bits',
                  'Challenge “we’ve always done it this way”',
                  'Build useful systems',
                  'Find efficiencies',
                  'Make impactful comms',
                  'Embrace change'
                ].map((item, i) => (
                  <div key={item} className="rounded-2xl border border-[#D8D2BF]/70 bg-white/[0.30] px-3.5 py-2.5 shadow-[inset_0_1px_0_rgba(255,255,255,0.35)]">
                    <span className="mb-2 block text-[10px] tracking-[0.18em]" style={{ color: ABOUT_MUTED }}>{String(i + 1).padStart(2, '0')}</span>
                    <span className="text-sm leading-snug sm:text-base" style={{ color: ABOUT_BODY }}>{item}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>

        {/* Branding overlay — fades out as the camera pushes into the screen */}
        <div id="hero-ui" style={{ position: 'absolute', inset: 0, willChange: 'opacity, transform' }}>
          {/* legibility gradient (part of the UI layer so it fades with the branding) */}
          <div className="absolute inset-0 bg-gradient-to-b from-black/30 via-transparent to-black/70 pointer-events-none" />
          <div className="noise-overlay absolute inset-0 opacity-[0.5] mix-blend-overlay pointer-events-none" />

          {/* Navbar */}
          <nav className="absolute top-0 left-1/2 -translate-x-1/2 z-20 bg-black rounded-b-2xl md:rounded-b-3xl px-4 py-2 md:px-8">
            <ul className="flex items-center gap-3 sm:gap-6 md:gap-12 lg:gap-14">
              {NAV_ITEMS.map((item) => (
                <li key={item}>
                  <a href="#" className="nav-link text-[10px] sm:text-xs md:text-sm whitespace-nowrap">{item}</a>
                </li>
              ))}
            </ul>
          </nav>

          {/* Bottom content */}
          <div className="absolute bottom-8 left-0 right-0 p-5 sm:bottom-0 sm:p-7 md:p-10 lg:p-12">
            <div className="grid grid-cols-12 gap-4 md:gap-6 items-end">
              <div className="col-span-12 lg:col-span-8">
                <h1 className="font-medium leading-[0.85] tracking-[-0.07em] text-[26vw] sm:text-[24vw] md:text-[22vw] lg:text-[20vw] xl:text-[19vw] 2xl:text-[20vw]"
                  style={{ color: CREAM }}>
                  <WordsPullUp text="Mat H" showAsterisk />
                </h1>
              </div>
              <div className="col-span-12 lg:col-span-4 flex flex-col gap-5 md:gap-6 lg:pb-3">
                <FadeUp delay={0.5}
                  className="text-xs sm:text-sm md:text-base flex flex-col gap-3"
                  style={{ lineHeight: 1.4, color: '#E1E0CC' }}>
                  <p>I work at the intersection of CRM transformation, customer engagement, automation and practical AI.</p>
                  <p>My focus is turning complex organisational problems into clearer operating models, useful systems and working prototypes — especially where customer data, marketing technology, internal knowledge and delivery teams need to line up.</p>
                </FadeUp>
                <FadeUp delay={0.7} className="self-start">
                  <button className="group bg-primary rounded-full text-black font-medium text-sm sm:text-base flex items-center gap-2 hover:gap-3 transition-all duration-300 pl-5 pr-1.5 py-1.5">
                    Read more
                    <span className="bg-black rounded-full w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center transition-transform duration-300 group-hover:scale-110">
                      <ArrowRight className="w-4 h-4" style={{ color: CREAM }} />
                    </span>
                  </button>
                </FadeUp>
              </div>
            </div>
          </div>

          {/* Scroll cue */}
          <div id="scroll-cue" className="absolute left-1/2 -translate-x-1/2 bottom-4 flex flex-col items-center gap-1.5 pointer-events-none">
            <span className="text-[10px] uppercase" style={{ color: CREAM, letterSpacing: '0.25em' }}>Scroll</span>
            <span style={{ width: 1, height: 26, background: `linear-gradient(${CREAM}, transparent)` }} />
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------------- ABOUT (the white laptop screen content) ---------------- */
function About() {
  return (
    <section id="about-screen"
      className="relative min-h-screen flex items-start justify-center px-6 md:px-10 pt-16 pb-28 sm:pt-20 md:pt-24 md:pb-36"
      style={{ background: SCREEN_WHITE, color: ABOUT_INK }}>
      <div className="max-w-5xl mx-auto text-center">
        <p className="text-[10px] sm:text-xs uppercase tracking-[0.25em] mb-8 md:mb-12"
          style={{ color: ABOUT_MUTED }}>About</p>
        <ScrollRevealText
          className="text-xl sm:text-2xl md:text-3xl lg:text-4xl max-w-4xl mx-auto"
          style={{ color: ABOUT_INK, lineHeight: 1.4 }}
          segments={[
            { text: 'I am Mat Hanson, ', className: 'font-normal' },
            { text: 'a self-confessed geek (let loose with AI).', className: 'italic font-serif text-[#7A5C3C]' },
            { text: '\nI like to tinker,\nprototype,\nsolve problems,\nautomate,\nchallenge “this is how we’ve always done it”,\nbuild,\nfind efficiencies,\nmake impactful comms,\nembrace change.', className: 'font-normal' }
          ]} />
      </div>
    </section>
  );
}

/* ---------------- FEATURES ---------------- */
function FeatureCard({ index, number, title, icon, items }) {
  return (
    <CardReveal index={index}
      className="bg-[#212121] rounded-2xl p-5 sm:p-6 flex flex-col min-h-[340px] lg:min-h-0 lg:h-full">
      <div className="flex items-start justify-between">
        <img src={icon} alt="" className="w-10 h-10 sm:w-12 sm:h-12 rounded-lg object-cover" />
        <span className="text-gray-500 text-xs">{number}</span>
      </div>
      <h3 className="mt-5 text-base sm:text-lg text-primary font-medium leading-tight">{title}</h3>
      <ul className="mt-4 space-y-3 flex-1">
        {items.map((it, i) => (
          <li key={i} className="flex items-start gap-2 text-gray-400 text-xs sm:text-sm">
            <Check className="text-primary w-4 h-4 mt-[2px] shrink-0" />
            <span style={{ lineHeight: 1.45 }}>{it}</span>
          </li>
        ))}
      </ul>
      <a href="#" className="group mt-5 inline-flex items-center gap-1.5 text-primary text-xs sm:text-sm hover:opacity-70 transition-opacity whitespace-nowrap">
        Learn more
        <ArrowRight className="w-3.5 h-3.5 shrink-0 transition-transform group-hover:translate-x-0.5" style={{ transform: 'rotate(-45deg)' }} />
      </a>
    </CardReveal>
  );
}

function Features() {
  return (
    <section id="features-section" className="relative min-h-screen bg-black px-4 md:px-6 py-16 md:py-24">
      <div className="bg-noise absolute inset-0 opacity-[0.15] pointer-events-none" />
      <div className="relative max-w-7xl mx-auto">
        <div className="mb-10 md:mb-16 text-xl sm:text-2xl md:text-3xl lg:text-4xl font-normal leading-tight">
          <div>
            <WordsPullUpMultiStyle align="flex-start"
              segments={[{ text: 'Studio-grade workflows for visionary creators.', className: '' }]}
              className="text-[#E1E0CC]" />
          </div>
          <div>
            <WordsPullUpMultiStyle align="flex-start"
              segments={[{ text: 'Built for pure vision. Powered by art.', className: '' }]}
              className="text-gray-500" />
          </div>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-2 md:gap-1 lg:h-[480px]">
          <CardReveal index={0}
            className="relative overflow-hidden rounded-2xl min-h-[340px] lg:min-h-0 lg:h-full">
            <video className="absolute inset-0 w-full h-full object-cover"
              autoPlay loop muted playsInline src={CANVAS_VIDEO} />
            <div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent pointer-events-none" />
            <p className="absolute bottom-5 left-5 right-5 text-lg sm:text-xl font-medium" style={{ color: CREAM }}>
              Your creative canvas.
            </p>
          </CardReveal>

          <FeatureCard index={1} number="01" title="Project Storyboard." icon={ICON_STORYBOARD}
            items={[
              'Drag-and-drop scene sequencing',
              'Frame-accurate shot annotations',
              'Shared timelines with your collective',
              'Version history on every cut'
            ]} />
          <FeatureCard index={2} number="02" title="Smart Critiques." icon={ICON_CRITIQUES}
            items={[
              'AI analysis of pacing and tone',
              'Threaded creative notes in context',
              'Integrations with your editing tools'
            ]} />
          <FeatureCard index={3} number="03" title="Immersion Capsule." icon={ICON_CAPSULE}
            items={[
              'Silence every notification on cue',
              'Curated ambient soundscapes',
              'Syncs with your shooting schedule'
            ]} />
        </div>
      </div>
    </section>
  );
}

/* ---------------- Scroll scrub + screen-handoff controller ---------------- */
function useHeroScrub() {
  useEffect(() => {
    const video = document.getElementById('hero-video');
    const idleVideo = document.getElementById('hero-idle-video');
    const track = document.getElementById('hero-track');
    const ui = document.getElementById('hero-ui');
    const cue = document.getElementById('scroll-cue');
    const boot = document.getElementById('boot-flash');
    const heroWhite = document.getElementById('hero-white');
    const heroAbout = document.getElementById('hero-about-preview');
    if (!video || !track) return;

    const clamp = (x, a, b) => Math.min(b, Math.max(a, x));
    const smooth = (e0, e1, x) => { const t = clamp((x - e0) / (e1 - e0), 0, 1); return t * t * (3 - 2 * t); };

    let target = 0, current = 0, raf = 0, lastSeekAt = 0;

    function compute() {
      const vh = window.innerHeight;
      const range = track.offsetHeight - vh;
      const scrolled = clamp(-track.getBoundingClientRect().top, 0, range);
      const p = range > 0 ? scrolled / range : 0;
      target = p * SCRUB_END;

      // At rest, play the ambient idle loop. As soon as the user scrolls, crossfade
      // to the scrubbed laptop video so one element is never asked to both loop and seek.
      const scrubIn = smooth(0.002, 0.035, p);
      if (idleVideo) {
        idleVideo.style.opacity = String(1 - scrubIn);
        if (p < 0.004 && idleVideo.paused) {
          if (idleVideo.currentTime >= IDLE_LOOP_END) {
            try { idleVideo.currentTime = 0; } catch (e) {}
          }
          const idlePlay = idleVideo.play();
          if (idlePlay && idlePlay.catch) idlePlay.catch(() => {});
        }
        if (p > 0.06 && !idleVideo.paused) idleVideo.pause();
      }
      video.style.opacity = String(scrubIn);

      // Final stretch dissolves to a whole-white screen, then reveals the About
      // copy inside the hero before the separate About section takes over.
      if (heroWhite) heroWhite.style.opacity = String(smooth(WHITE_START, WHITE_END, p));
      if (heroAbout) {
        const aboutIn = smooth(0.88, 0.98, p);
        heroAbout.style.opacity = String(aboutIn);
        heroAbout.style.transform = 'translateY(' + ((1 - aboutIn) * 24) + 'px)';
      }

      // Branding fades + drifts up as the camera pushes in (kept on screen longer)
      const uiHide = smooth(0.34, 0.58, p);
      if (ui) {
        ui.style.opacity = String(1 - uiHide);
        ui.style.transform = 'translateY(' + (-uiHide * 36) + 'px)';
        ui.style.pointerEvents = uiHide > 0.9 ? 'none' : '';
      }
      if (cue) cue.style.opacity = String(1 - smooth(0.02, 0.12, p));

      // The About preview now provides the handoff. Keep the old white flash
      // disabled so it doesn't blank out the laptop-screen content at the seam.
      if (boot) boot.style.opacity = '0';
    }

    function loop(ts = 0) {
      current += (target - current) * 0.18;            // lerp → smooth, eased scrub
      if (Math.abs(target - current) < 0.006) current = target;
      if (idleVideo && !idleVideo.paused && idleVideo.currentTime >= IDLE_LOOP_END) {
        try { idleVideo.currentTime = 0; } catch (e) {}
      }
      if (video.readyState >= 1) {
        const diff = Math.abs(video.currentTime - current);
        const canSeek = !video.seeking || diff > 0.22;
        if (diff > 0.016 && canSeek && (ts - lastSeekAt > 30 || diff > 0.18)) {
          try { video.currentTime = current; lastSeekAt = ts; } catch (e) {}
        }
      }
      raf = requestAnimationFrame(loop);
    }

    // Prime decoding on first interaction (helps mobile seek smoothly)
    let primed = false;
    const prime = () => {
      if (primed) return; primed = true;
      const pr = video.play();
      if (pr && pr.then) pr.then(() => video.pause()).catch(() => {});
    };
    ['wheel', 'touchstart', 'pointerdown', 'keydown'].forEach((e) =>
      window.addEventListener(e, prime, { once: true, passive: true }));

    const showFirst = () => { try { video.currentTime = 0; } catch (e) {} };
    if (video.readyState >= 1) showFirst(); else video.addEventListener('loadeddata', showFirst, { once: true });
    if (idleVideo) {
      const idlePlay = idleVideo.play();
      if (idlePlay && idlePlay.catch) idlePlay.catch(() => {});
    }

    compute();
    window.addEventListener('scroll', compute, { passive: true });
    window.addEventListener('resize', compute);
    raf = requestAnimationFrame(loop);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('scroll', compute);
      window.removeEventListener('resize', compute);
    };
  }, []);
}

function App() {
  useHeroScrub();
  return (
    <React.Fragment>
      <HeroScroll />
      <Features />

      {/* White "screen-on" beat that the portfolio emerges from (fixed, JS-driven opacity) */}
      <div id="boot-flash" style={{
        position: 'fixed', inset: 0, background: SCREEN_WHITE, opacity: 0,
        pointerEvents: 'none', zIndex: 60
      }} />
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
