const { useEffect, useRef, useState } = React;

function Hero() {
  const pinRef = React.useRef(null);
  const stageRef = React.useRef(null);
  const [phoneActive, setPhoneActive] = React.useState(false);
  // discrete mode purely for labels/buttons/captions; NOT for visuals
  const [mode, setMode] = React.useState('email');

  // Continuous scroll progress drives the crossfade via CSS vars on the stage.
  React.useEffect(() => {
    const pin = pinRef.current;
    const stage = stageRef.current;
    if (!pin || !stage) return;
    let raf = 0;

    // --- Mock-scale calculation (replaces the CSS clamp/min/calc that
    //     wasn't resolving reliably inside transform: scale()) ---
    // We compute the unitless scale ourselves and write it directly to
    // --mock-scale. Two factors:
    //   - height factor: stage_h must fit (mock 460px + 84px switcher
    //     row + 88px nav clearance + 56px bottom). Floor 0.6, ceil 1.22.
    //   - width factor:  on big monitors, scale up so the mock breathes.
    //     Linear from 1.0 at 1280px to 1.22 at 1920px.
    // Final = min(width-factor, height-factor) — the more constrained.
    const computeMockScale = () => {
      const vh = window.innerHeight;
      const vw = window.innerWidth;
      const hFactor = Math.max(0.6, Math.min(1.22, (vh - 180) / 640));
      const wFactor = Math.max(1, Math.min(1.22, 1 + (vw - 1280) / 3600));
      return Math.min(wFactor, hFactor);
    };
    const applyMockScale = () => {
      const s = computeMockScale();
      stage.style.setProperty('--mock-scale', s.toFixed(3));
    };
    applyMockScale();
    window.addEventListener('resize', applyMockScale);
    const update = () => {
      raf = 0;
      const rect = pin.getBoundingClientRect();
      // Offset so progress begins at scrollY=0 (before the pin reaches the viewport top).
      const startOffset = pin.offsetTop;
      const total = pin.offsetHeight - window.innerHeight + startOffset;
      if (total <= 0) return;
      const raw = (startOffset - rect.top) / total;
      const p = Math.max(0, Math.min(1, raw));
      // Apply an ease so the middle transition feels snappier
      const eased = p < 0.5 ?
      2 * p * p :
      1 - Math.pow(-2 * p + 2, 2) / 2;
      stage.style.setProperty('--p', eased.toFixed(4));
      // discrete label mode (for captions/buttons only)
      const next = p < 0.5 ? 'email' : 'sms';
      setMode((m) => m === next ? m : next);
      // Phone animation activation has hysteresis so a tiny scroll back
      // doesn't immediately rewind: trigger forward at 80%, only rewind
      // once we've come back below 60%. The CSS crossfade still spans 0–100%.
      setPhoneActive((prev) => {
        if (!prev && p > 0.8) return true;
        if (prev && p < 0.6) return false;
        return prev;
      });
    };
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(update);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    update();
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      window.removeEventListener('resize', applyMockScale);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  // Clicking the toggle smooth-scrolls to the right progress point
  const jumpToMode = (target) => {
    const pin = pinRef.current;
    if (!pin) return;
    const total = pin.offsetHeight - window.innerHeight;
    const fraction = target === 'email' ? 0 : 1;
    const top = pin.offsetTop + total * fraction;
    window.scrollTo({ top, behavior: 'smooth' });
  };

  const isEmail = mode === 'email';

  return (
    <div className="hero-pin" ref={pinRef}>
      <section className="hero hero-stage" ref={stageRef}>
        <div className="container hero-grid">
          <div className="hero-copy">
            <span className="nav-flagship hero-flagship">Live on a flagship TV series</span>

            <div className="hero-text-stack">
              {/* Both texts layered; opacity driven by --p */}
              <div className="hero-text hero-text-email">
                <h1>
                  <span className="word"><span style={{ animationDelay: '60ms' }}>Catch</span></span>{' '}
                  <span className="word"><span style={{ animationDelay: '120ms' }}>it&nbsp;early.</span></span><br />
                  <span className="word spark-word"><span style={{ animationDelay: '200ms' }}>Save&nbsp;the&nbsp;shoot.</span></span>
                </h1>
                <p className="hero-lead">
                  The mistakes that blow a budget are hiding in thousands of
                  documents... the schedule drift, a new location written in,
                  a conflict no one caught. Krew reads every page and catches
                  what humans miss.
                </p>
              </div>
              <div className="hero-text hero-text-sms">
                <h1>
                  <span className="word"><span style={{ animationDelay: '60ms' }}>Stop</span></span>{' '}
                  <span className="word"><span style={{ animationDelay: '120ms' }}>digging.</span></span><br />
                  <span className="word spark-word"><span style={{ animationDelay: '200ms' }}>Start&nbsp;shooting.</span></span>
                </h1>
                <p className="hero-lead">Everything grinds to a halt as you go digging through emails for the phone number, the date, or the location... Krew knows and answers right where you already work.



                </p>
              </div>
            </div>

            <div className="hero-ctas">
              <a href="#demo" className="btn spark">
                Book a demo
                <svg aria-hidden="true" focusable="false" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 5l7 7-7 7" /></svg>
              </a>
            </div>
          </div>

          <HeroMock mode={mode} setMode={jumpToMode} phoneActive={phoneActive} />
        </div>
      </section>
    </div>);

}

function HeroMock({ mode, setMode, phoneActive }) {
  const isEmail = mode === 'email';
  return (
    <div className="hero-mock">
      <div className="mock-stack">
        {/* Email card — its transform is driven by --p (front at p=0, back at p=1) */}
        <div className="mock-card mock-email">
          <EmailMock />
          {/* Mobile-only simplified version. Hidden on desktop via CSS;
              fewer elements, native font sizes (no scale shrink). */}
          <MobileEmailMock />
        </div>
        {/* SMS phone — inverse: back at p=0, front at p=1 */}
        <div className="mock-card mock-sms">
          <SmsMock active={phoneActive} />
          <MobileSmsMock active={phoneActive} />
        </div>
      </div>
      <div className="hero-switcher-row">
        <div className="hero-switcher">
          <button className={isEmail ? 'active' : ''} onClick={() => setMode('email')}>
            <span className="dot-mini" /> Email
          </button>
          <button className={!isEmail ? 'active' : ''} onClick={() => setMode('sms')}>
            <span className="dot-mini" /> SMS
          </button>
        </div>
        <div className="hero-caption font-script">
          {isEmail ?
          <>Email Krew like a coworker.</> :

          <>Or text. Same Krew.</>
          }
        </div>
      </div>
    </div>);

}

/* ---------- Vertical prelim schedule ghost ---------- */
function ScheduleGhost() {
  // Mon-Fri rows, each with scene strips and colored day strip
  const rows = [
  { day: "MON", date: "5/25", tag: "EXT · COFFEE SHOP", pages: "4 2/8", color: "#BBD4E8" },
  { day: "TUE", date: "5/26", tag: "INT · GYM (NIGHT)", pages: "3 6/8", color: "#BBD4E8" },
  { day: "WED", date: "5/27", tag: "EXT · PARKING LOT", pages: "5 0/8", color: "#C8DDB0" },
  { day: "THU", date: "5/28", tag: "INT · HOSPITAL", pages: "6 2/8", color: "#C8DDB0" },
  { day: "FRI", date: "5/29", tag: "EXT · ROOFTOP", pages: "2 4/8", color: "#E8B894" },
  { day: "MON", date: "6/01", tag: "INT · DINER", pages: "4 0/8", color: "#E8B894" },
  { day: "TUE", date: "6/02", tag: "EXT · BRIDGE", pages: "3 2/8", color: "#E8B894" }];

  return (
    <div className="ghost-card schedule-ghost">
      <div className="sg-head">
        <div className="sg-label">PRELIM BLUE · Wk 7</div>
        <div className="sg-badge">62 days</div>
      </div>
      <div className="sg-list">
        {rows.map((r, i) =>
        <div key={i} className="sg-row">
            <div className="sg-dayslot">
              <div className="sg-dayname">{r.day}</div>
              <div className="sg-date">{r.date}</div>
            </div>
            <div className="sg-bar" style={{ background: r.color }}>
              <span className="sg-tag">{r.tag}</span>
              <span className="sg-pages">{r.pages}</span>
            </div>
          </div>
        )}
      </div>
    </div>);

}

/* ---------- Email mock: elevated reveal ---------- */
function EmailMock() {
  return (
    <div className="email-card">
      <div className="email-header">
        <div className="dots"><i></i><i></i><i></i></div>
        <span>Inbox · 1 new</span>
      </div>
      <div className="email-meta">
        <div className="from">
          <div className="avatar-k" aria-label="Krew">
            <img src="/assets/krew-icon-circle.png" alt="Krew" />
          </div>
          <div className="who">
            <strong>Krew</strong>
            <span>to Matt · 7:14 AM</span>
          </div>
        </div>
      </div>

      <div className="email-subject">
        <span>BLUE Schedule Change Report<br />14 changes, 1 conflict</span>
      </div>

      <div className="email-body">
        <strong>Scene 42</strong> moved to <strong>June 4</strong>.
        Shawn's booked flight (AA 1917) lands LAX <strong>3:08 PM</strong>{' '}
        — 7 hrs after his 8 AM call. Consider rebooking travel or adjusting the shooting schedule.
      </div>

      <div className="email-cta-row">
        <button type="button" className="email-cta-btn">Open full report →</button>
      </div>

      <div className="sig-line">
        — Krew
        <em>Reply to ask a follow-up</em>
      </div>
    </div>);

}

/* ---------- SMS mock ---------- */
function SmsMock({ active = true }) {
  const userMsg = "Who's Shawn's assistant? Need to ask about a rebook.";
  const replyBubbles = [
  "Mike Delgado\n(312) 555-0144",
  "Email for non-urgent:\nmike@talentagency.com"];

  const [typedUser, setTypedUser] = useState('');
  const [typingIndicator, setTypingIndicator] = useState(false);
  const [repliesShown, setRepliesShown] = useState(0);

  // Track whether we're rewinding so bubbles use a soft fade-out instead
  // of the bouncy bubbleRise animation when leaving the thread.
  const [rewinding, setRewinding] = useState(false);

  // Run the animation whenever this mock becomes active (in front). When it
  // goes back to inactive, gracefully unwind in reverse so the next visit
  // starts from a clean empty state — never a hard cut.
  useEffect(() => {
    const timeouts = [];

    if (!active) {
      // Reverse playback: peel replies off newest-first, then typed text, then daystamp.
      setRewinding(true);
      setTypingIndicator(false);
      // Pull off the second reply, then the first reply
      timeouts.push(setTimeout(() => setRepliesShown((n) => Math.max(n - 1, 1)), 80));
      timeouts.push(setTimeout(() => setRepliesShown(0), 320));
      // Erase typed text character by character
      timeouts.push(setTimeout(() => {
        let j = 0;
        const eraseId = setInterval(() => {
          j++;
          setTypedUser((prev) => prev.slice(0, Math.max(prev.length - 2, 0)));
          if (j > 40) {
            clearInterval(eraseId);
            setTypedUser('');
            setRewinding(false);
          }
        }, 14);
        timeouts.push({ _interval: eraseId });
      }, 560));
      return () => {
        timeouts.forEach((t) => {
          if (t && t._interval) clearInterval(t._interval);else
          clearTimeout(t);
        });
      };
    }

    // Forward playback
    setRewinding(false);
    let i = 0;
    const typeId = setInterval(() => {
      i++;
      setTypedUser(userMsg.slice(0, i));
      if (i >= userMsg.length) {
        clearInterval(typeId);
        // First typing dots → first bubble
        timeouts.push(setTimeout(() => setTypingIndicator(true), 300));
        timeouts.push(setTimeout(() => {
          setTypingIndicator(false);
          setRepliesShown(1);
        }, 1100));
        // Brief pause, then second typing dots → second bubble
        timeouts.push(setTimeout(() => setTypingIndicator(true), 1700));
        timeouts.push(setTimeout(() => {
          setTypingIndicator(false);
          setRepliesShown(2);
        }, 2500));
      }
    }, 12);
    return () => {
      clearInterval(typeId);
      timeouts.forEach(clearTimeout);
    };
  }, [active]);

  return (
    <div className="sms-phone">
      <div className="sms-header">
        <span className="sms-back">‹</span>
        <div className="sms-who">
          <div className="sms-avatar">
            <img src="/assets/krew-icon-circle.png" alt="Krew" />
          </div>
          <span>Krew</span>
        </div>
        <span className="sms-video">ⓘ</span>
      </div>

      <div className={"sms-thread" + (rewinding ? " sms-rewind" : "")}>
        {typedUser && <div className="sms-daystamp">Today 5:02 PM</div>}

        {typedUser &&
        <div className="sms-bubble sms-out">{typedUser}</div>
        }

        {replyBubbles.slice(0, repliesShown).map((txt, i) =>
        <div key={i} className="sms-bubble sms-in sms-reply">
            <span className="reply-line" style={{ display: 'block' }}>{txt}</span>
          </div>
        )}

        {typingIndicator &&
        <div className="sms-bubble sms-in sms-typing">
            <div className="typing-dots"><i></i><i></i><i></i></div>
          </div>
        }
      </div>

      <div className="sms-footer">
        <span className="sms-plus">+</span>
        <span className="sms-input">Message Krew</span>
      </div>
    </div>);

}

/* ---------- MOBILE-ONLY simplified email mock ----------
   Renders inside the same .mock-card.mock-email but uses class
   `email-card-mobile` so CSS can swap which version shows. Trimmed
   chrome (no traffic-light header, no signature, no CTA button)
   and native-size text — designed to be readable at 320px without
   any transform scaling.
*/
function MobileEmailMock() {
  return (
    <div className="email-card-mobile" role="img" aria-label="Krew email mockup, simplified for mobile">
      <div className="emc-header">
        <div className="emc-dots"><i></i><i></i><i></i></div>
        <span>Inbox · 1 new</span>
      </div>
      <div className="emc-body-wrap">
        <div className="emc-meta">
          <div className="avatar-k emc-avatar" aria-label="Krew">
            <img src="/assets/krew-icon-circle.png" alt="" />
          </div>
          <div className="emc-who">
            <strong>Krew</strong>
            <span>to Matt · 7:14 AM</span>
          </div>
        </div>
        <div className="emc-subject">
          BLUE Schedule Change Report
        </div>
        <div className="emc-tag">14 changes · 1 conflict</div>
        <div className="emc-body">
          <strong>Scene 42</strong> moved to <strong>June 4</strong>.
          Shawn's flight (AA 1917) lands LAX <strong>3:08 PM</strong> —
          7 hrs after his 8 AM call.
        </div>
      </div>
    </div>);

}

/* ---------- MOBILE-ONLY simplified SMS mock ----------
   Same animation hooks (typing → reply) but only ONE reply bubble,
   larger text, slightly taller phone for breathing room.
*/
function MobileSmsMock({ active = true }) {
  // Mirrors the desktop SmsMock context (rebook ask) but trimmed
  // for the 280px-wide mobile phone bubble.
  const userMsg = "Need to rebook.. who's Shawn's assistant?";
  const reply = "Mike Delgado\n(312) 555-0144";

  const [typedUser, setTypedUser] = useState('');
  const [typingIndicator, setTypingIndicator] = useState(false);
  const [replyShown, setReplyShown] = useState(false);
  const [rewinding, setRewinding] = useState(false);

  useEffect(() => {
    const timeouts = [];
    if (!active) {
      setRewinding(true);
      setTypingIndicator(false);
      timeouts.push(setTimeout(() => setReplyShown(false), 200));
      timeouts.push(setTimeout(() => {
        let j = 0;
        const eraseId = setInterval(() => {
          j++;
          setTypedUser((prev) => prev.slice(0, Math.max(prev.length - 2, 0)));
          if (j > 30) {
            clearInterval(eraseId);
            setTypedUser('');
            setRewinding(false);
          }
        }, 14);
        timeouts.push({ _interval: eraseId });
      }, 400));
      return () => {
        timeouts.forEach((t) => {
          if (t && t._interval) clearInterval(t._interval); else clearTimeout(t);
        });
      };
    }
    setRewinding(false);
    let i = 0;
    const typeId = setInterval(() => {
      i++;
      setTypedUser(userMsg.slice(0, i));
      if (i >= userMsg.length) {
        clearInterval(typeId);
        timeouts.push(setTimeout(() => setTypingIndicator(true), 280));
        timeouts.push(setTimeout(() => {
          setTypingIndicator(false);
          setReplyShown(true);
        }, 1000));
      }
    }, 14);
    return () => {
      clearInterval(typeId);
      timeouts.forEach(clearTimeout);
    };
  }, [active]);

  return (
    <div className="sms-phone-mobile">
      <div className="smsm-header">
        <span className="smsm-back">‹</span>
        <div className="smsm-who">
          <div className="smsm-avatar">
            <img src="/assets/krew-icon-circle.png" alt="" />
          </div>
          <span>Krew</span>
        </div>
        <span className="smsm-info">ⓘ</span>
      </div>
      <div className={"smsm-thread" + (rewinding ? " smsm-rewind" : "")}>
        {typedUser && <div className="smsm-bubble smsm-out">{typedUser}</div>}
        {replyShown && (
          <div className="smsm-bubble smsm-in">
            {reply.split('\n').map((line, i) => (
              <span key={i} style={{ display: 'block' }}>{line}</span>
            ))}
          </div>
        )}
        {typingIndicator && (
          <div className="smsm-bubble smsm-in smsm-typing">
            <div className="typing-dots"><i></i><i></i><i></i></div>
          </div>
        )}
      </div>
      <div className="smsm-footer">
        <span className="smsm-input">Message Krew</span>
      </div>
    </div>);

}

window.Hero = Hero;