/* global React */
const { useState, useEffect, useRef, useMemo } = React;

// =============== TWEAKS DEFAULTS ===============
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "paper",
  "weight": "regular",
  "showBadges": true
}/*EDITMODE-END*/;

// =============== BRAND ===============
function Monogram({ size = 22, className = "" }) {
  // "II." — custom paired bars with a dot
  return (
    <span className={`monogram ${className}`} style={{ fontSize: size, lineHeight: 1 }}>
      II<span style={{ display: 'inline-block', transform: 'translateY(0)' }}>.</span>
    </span>
  );
}

function Nav({ onCta }) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 20);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <nav className={`nav ${scrolled ? 'scrolled' : ''}`}>
      <a href="#top" className="nav-brand" aria-label="Han Ai">
        <Monogram size={22} />
      </a>
      <div className="nav-links">
        <a href="#what" style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', fontWeight: 400 }}>What It Does</a>
        <a href="#systems" style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', fontWeight: 400 }}>Systems</a>
        <a href="#trust" style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', fontWeight: 400 }}>Han Studios</a>
        <a href="#waitlist" style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', fontWeight: 400 }}>Waitlist</a>
      </div>
      <button className="btn btn-primary" onClick={onCta} style={{ padding: '10px 18px', fontSize: 11, fontFamily: 'var(--font-mono)', letterSpacing: '0.24em', textTransform: 'uppercase', fontWeight: 400 }}>
        Join the Waitlist
        <Arrow />
      </button>
    </nav>
  );
}

function Arrow({ size = 14 }) {
  return (
    <svg className="btn-arrow" width={size} height={size} viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 10h12M11 5l5 5-5 5" />
    </svg>
  );
}

// =============== REVEAL HOOK ===============
function useReveal() {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(
      (entries) => { entries.forEach(e => { if (e.isIntersecting) { setShown(true); obs.disconnect(); } }); },
      { threshold: 0.15, rootMargin: '0px 0px -60px 0px' }
    );
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);
  return [ref, shown];
}

function Reveal({ children, delay = 0, as: Tag = 'div', className = '', style = {} }) {
  const [ref, shown] = useReveal();
  return (
    <Tag ref={ref} className={`reveal ${shown ? 'in' : ''} ${className}`} style={{ transitionDelay: `${delay}s`, ...style }}>
      {children}
    </Tag>
  );
}

// =============== SECTION NUMBER WHEEL ===============
function NumberWheel() {
  const [sections, setSections] = useState([]);
  const [activeIndex, setActiveIndex] = useState(0);

  useEffect(() => {
    const collect = () => {
      const els = Array.from(document.querySelectorAll('[data-screen-label]'));
      return els
        .map(el => {
          const label = el.dataset.screenLabel || '';
          const m = label.match(/^(\d+)\s+(.+)$/);
          return m ? { num: m[1].padStart(2, '0'), title: m[2], el } : null;
        })
        .filter(Boolean);
    };
    const init = collect();
    setSections(init);

    let raf = 0;
    const compute = () => {
      raf = 0;
      const trigger = window.innerHeight * 0.45;
      let active = 0;
      for (let i = 0; i < init.length; i++) {
        const r = init[i].el.getBoundingClientRect();
        if (r.top <= trigger) active = i;
        else break;
      }
      setActiveIndex(active);
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(compute); };
    compute();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  if (!sections.length) return null;

  const ARC_STEP = 9;
  const RADIUS = 340;
  const rotation = -activeIndex * ARC_STEP;

  return (
    <div className="wheel" aria-hidden="true">
      <div className="wheel-rotor" style={{ transform: `rotate(${rotation}deg)` }}>
        {sections.map((s, i) => (
          <div
            key={i}
            className={`wheel-num ${i === activeIndex ? 'active' : ''}`}
            style={{ transform: `rotate(${i * ARC_STEP}deg) translateX(${RADIUS}px)` }}
          >
            {s.num}
          </div>
        ))}
      </div>
      <div className="wheel-title-wrap">
        <div className="wheel-title" key={activeIndex}>
          {sections[activeIndex].title}
        </div>
      </div>
    </div>
  );
}

// =============== SCENE SHAPES (scroll-bound parallax) ===============
function Scene({ shapes }) {
  const ref = useRef(null);
  useEffect(() => {
    const wrap = ref.current;
    if (!wrap) return;
    const parent = wrap.parentElement;
    const els = wrap.querySelectorAll('.scene-shape');
    let raf = 0;
    const compute = () => {
      raf = 0;
      const rect = parent.getBoundingClientRect();
      const center = rect.top + rect.height / 2;
      const offset = center - window.innerHeight / 2;
      els.forEach(el => {
        const speed = parseFloat(el.dataset.speed || '0.18');
        el.style.setProperty('--sy', (-offset * speed).toFixed(1));
      });
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(compute); };
    compute();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);
  return (
    <div className="scene-clip" ref={ref} aria-hidden="true">
      {shapes.map((s, i) => (
        <div
          key={i}
          className={`scene-shape shape-${s.variant} pos-${s.position}`}
          style={{ '--sz': s.size }}
          data-speed={s.speed ?? 0.18}
        />
      ))}
    </div>
  );
}

// =============== HERO VIDEO (scroll-scrub on desktop, autoplay-loop on mobile) ===============
function HeroVideo() {
  const trackRef = useRef(null);
  const videoRef = useRef(null);
  const [pinned, setPinned] = useState(false);
  const [isMobile, setIsMobile] = useState(
    typeof window !== 'undefined' && window.matchMedia('(max-width: 760px)').matches
  );

  // Pick source based on viewport; switch if the user rotates/resizes across breakpoint
  useEffect(() => {
    const mq = window.matchMedia('(max-width: 760px)');
    const onChange = (e) => setIsMobile(e.matches);
    mq.addEventListener ? mq.addEventListener('change', onChange) : mq.addListener(onChange);
    return () => {
      mq.removeEventListener ? mq.removeEventListener('change', onChange) : mq.removeListener(onChange);
    };
  }, []);

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

    // Mobile: autoplay + loop, skip scroll-scrub (iOS can't reliably seek a paused video)
    if (isMobile) {
      const tryPlay = () => { v.play().catch(() => {}); };
      if (v.readyState >= 2) tryPlay();
      else v.addEventListener('loadeddata', tryPlay, { once: true });

      const onScroll = () => {
        const rect = track.getBoundingClientRect();
        setPinned(rect.top <= 0 && rect.bottom >= window.innerHeight);
      };
      window.addEventListener('scroll', onScroll, { passive: true });
      window.addEventListener('resize', onScroll);
      onScroll();
      return () => {
        window.removeEventListener('scroll', onScroll);
        window.removeEventListener('resize', onScroll);
        v.removeEventListener('loadeddata', tryPlay);
      };
    }

    // Desktop: scroll-scrub
    let raf = 0;
    const update = () => {
      raf = 0;
      const rect = track.getBoundingClientRect();
      const scrollRange = rect.height - window.innerHeight;
      const progress = Math.max(0, Math.min(1, -rect.top / Math.max(1, scrollRange)));
      const dur = v.duration;
      if (dur && isFinite(dur)) {
        const target = progress * dur;
        if (Math.abs(target - v.currentTime) > 0.01) v.currentTime = target;
      }
      setPinned(rect.top <= 0 && rect.bottom >= window.innerHeight);
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); };
    const onLoaded = () => { update(); };

    v.addEventListener('loadedmetadata', onLoaded);
    if (v.readyState >= 1) onLoaded();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    update();

    return () => {
      v.removeEventListener('loadedmetadata', onLoaded);
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, [isMobile]);

  const videoSrc = isMobile ? 'assets/han-ai-hero-mobile.mp4' : 'assets/han-ai-hero.mp4';

  return (
    <div className="hero-video-track" ref={trackRef}>
      <div className="hero-video-sticky">
        <video
          ref={videoRef}
          key={videoSrc}
          className="hero-video"
          src={videoSrc}
          poster="assets/han-ai-hero-poster.jpg"
          muted
          playsInline
          autoPlay={isMobile}
          loop={isMobile}
          preload="auto"
          aria-hidden="true"
        />
        <div className={`hero-cards ${pinned ? 'in' : ''}`}>
          <div className="hero-card card-tl">
            <span className="mono-num card-label">THIS WEEK</span>
            <span className="card-body">12 items shipped · 4 approved</span>
          </div>
          <div className="hero-card card-tr">
            <span className="card-dot" />
            <span className="card-body">Always running</span>
          </div>
          <div className="hero-card card-br">
            <span className="mono-num card-label">NEEDS YOU</span>
            <span className="card-body">1 call waiting</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// =============== HERO ===============
function Hero({ onCta }) {
  return (
    <section className="section" id="top" data-screen-label="01 Hero" style={{ paddingTop: 'clamp(168px, 19vw, 240px)', paddingBottom: 0 }}>
      <Scene shapes={[
        { variant: 'violet', position: 'tl', size: '95vh', speed: 0.22 },
        { variant: 'sky',    position: 'br', size: '78vh', speed: -0.14 },
      ]} />
      <div className="container narrow text-center">
        <Reveal>
          <div className="eyebrow" style={{ marginBottom: 28, fontFamily: '"DM Mono"' }}>Han Ai — Where intelligence meets execution</div>
        </Reveal>
        <Reveal delay={0.08}>
          <h1 className="h-display-xl">
            AI operating system<br/>for real-world execution.
          </h1>
        </Reveal>
        <Reveal delay={0.2}>
          <p className="lede" style={{ margin: '32px auto 0', maxWidth: '640px' }}>
            Content, growth, and operations — run through a single system.
          </p>
        </Reveal>
        <Reveal delay={0.28}>
          <p className="body" style={{ margin: '20px auto 0', maxWidth: 540, color: 'var(--ink)', fontWeight: 500 }}>
            Directed from your phone. Running continuously.
          </p>
        </Reveal>
        <Reveal delay={0.32}>
          <p className="body" style={{ margin: '14px auto 0', maxWidth: 540, color: 'var(--faint)', fontWeight: 400, fontSize: 15, letterSpacing: '-0.005em' }}>
            No dashboards. No chasing. Just execution.
          </p>
        </Reveal>
        <Reveal delay={0.36}>
          <div style={{ display: 'flex', gap: 12, justifyContent: 'center', marginTop: 44, flexWrap: 'wrap' }}>
            <button className="btn btn-primary" onClick={onCta}>
              Join the waitlist
              <Arrow />
            </button>
            <a className="btn btn-ghost" href="#what">
              See how it runs
            </a>
          </div>
        </Reveal>
      </div>

      <HeroVideo />
    </section>
  );
}

// =============== PROBLEM ===============
function Problem() {
  return (
    <section className="section" data-screen-label="02 Problem" style={{ paddingTop: 'clamp(96px, 14vw, 192px)', paddingBottom: 'clamp(96px, 14vw, 192px)' }}>
      <div className="container narrow">
        <Reveal>
          <div className="eyebrow" style={{ marginBottom: 40 }}>01 — The problem</div>
        </Reveal>
        <Reveal delay={0.1}>
          <h2 className="h-section">
            Most teams don't lack ideas.<br/>
            <span style={{ color: 'var(--muted)' }}>They lack execution.</span>
          </h2>
        </Reveal>
        <Reveal delay={0.22}>
          <div style={{ marginTop: 56, display: 'grid', gridTemplateColumns: '1fr', gap: 0 }}>
            {[
              'Work slows down.',
              'Decisions get delayed.',
              'Output becomes inconsistent.',
              'The problem isn\u2019t strategy — it\u2019s the system.',
            ].map((line, i) => (
              <div key={i} style={{
                padding: '24px 0',
                borderTop: '1px solid var(--hair)',
                display: 'flex', gap: 24, alignItems: 'baseline',
                fontSize: 'clamp(20px, 2.2vw, 28px)',
                fontWeight: 500,
                letterSpacing: '-0.02em',
                color: 'var(--ink)',
              }}>
                <span className="mono-num" style={{ width: 40, flexShrink: 0 }}>{String(i + 1).padStart(2, '0')}</span>
                <span>{line}</span>
              </div>
            ))}
            <div style={{ borderTop: '1px solid var(--hair)' }} />
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// =============== SHIFT ===============
function Shift() {
  return (
    <section className="section section-tight" data-screen-label="03 Shift" style={{ background: 'var(--paper-2)', paddingTop: 'clamp(68px, 10vw, 132px)', paddingBottom: 'clamp(68px, 10vw, 132px)' }}>
      <div className="container narrow">
        <Reveal>
          <div className="eyebrow" style={{ marginBottom: 40 }}>02 — The shift</div>
        </Reveal>
        <Reveal delay={0.1}>
          <h2 className="h-section">
            We don't add more tools.<br/>
            <span style={{ color: 'var(--muted)' }}>We replace the way work gets executed.</span>
          </h2>
        </Reveal>
        <Reveal delay={0.22}>
          <p className="lede" style={{ marginTop: 32, maxWidth: 640 }}>
            One system. Planning, execution, and optimization — running continuously.
          </p>
        </Reveal>
      </div>
    </section>
  );
}

Object.assign(window, { Monogram, Nav, Arrow, Reveal, useReveal, Scene, NumberWheel, HeroVideo, Hero, Problem, Shift, TWEAK_DEFAULTS });
