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

// =================================================================
// §3 SERVICES JOURNEY — sticky phone, scroll-driven step
// =================================================================
const JOURNEY_STEPS = [
  {
    num: "01",
    id: "click",
    eyebrow: "LIVE IN UNDER 48 HOURS",
    ttl: <>Built in 24 hours. <span className="it">Bookings by Day 2.</span></>,
    body: "Day 1 we plug in. Day 2 your ads are live. Multiple hyper-targeted ads and content pieces drop in front of the exact people you want to land — not browsers, not tire-kickers. They tap. They qualify, apply, or call. They book before doubt sets in.",
    points: [
      "Full creative + landing page + CRM live in <48 hours",
      "Multiple ads + content · multiple angles, daily testing",
      "Lead lands in your CRM in <30 seconds — Sophie's already calling",
    ],
  },
  {
    num: "02",
    id: "followup",
    eyebrow: "SOPHIE CALLS IN UNDER 30 SECONDS",
    ttl: <>Sophie calls. Texts. <span className="it">Every lead — constantly.</span></>,
    body: "You do nothing. Sophie does everything. Every opt-in, form submission, and phone call — Sophie picks it up in under 30 seconds. No pickup on the call? She texts. She qualifies, books, and filters tire-kickers before they hit your calendar. 60% more bookings. Zero wasted time. Zero missed leads.",
    points: [
      "Trained on your business, offer & objections · male or female voice (your call)",
      "Picks up every opt-in, form, and phone call · 24/7",
      "Books only qualified leads · auto-handles reschedules, no-shows, deposits",
    ],
  },
  {
    num: "03",
    id: "booking",
    eyebrow: "BOOKED & PAID IN UNDER 60 SECONDS",
    ttl: <>Booked. Paid. <span className="it">Ready to show up.</span></>,
    body: "The booking lands on your team's calendar — instantly. Everyone on your team gets pinged with the full file. Deposit auto-charged. Forms auto-sent. Whether it's a consult, sales call, or install — they're qualified, paid, and locked in before the day arrives.",
    points: [
      "Your whole team notified the second they book — Slack + iOS",
      "Auto-charged deposit · cuts no-shows 70%",
      "Intake forms / contracts / pre-call docs sent automatically",
    ],
  },
  {
    num: "04",
    id: "flip",
    eyebrow: "ALWAYS ON — WE NEVER STOP",
    ttl: <>We work for you. <span className="it">24/7.</span></>,
    body: "Your account isn't set-and-forget — it's set-and-scaled. New ad sets & content every week. Daily optimization. Replies under 60 seconds. We're in your account daily — killing what doesn't work, doubling down on what does. Treating it like our own.",
    points: [
      "New ad sets & content every week · multiple angles, hooks, formats",
      "Daily optimization · pause losers, scale winners",
      "Slack replies in <1 minute · daily standups on your account",
      "You own every ad account · Meta, Google, TikTok, YouTube — forever",
    ],
  },
];

function MetaFrame({ progress }) {
  // progress 0..1 within step 0
  const typed = "555-0142";
  const focusedNum = progress > 0.4;
  const submitting = progress > 0.7;
  return (
    <div className="meta-frame">
      <div className="meta-bar">
        <div className="dots"><span/><span/><span/></div>
        <div className="url">drjoeyalcantara.com/back-pain</div>
        <div className="lock">🔒</div>
      </div>
      <div className="meta-body">
        <div className="meta-brand">
          <div className="meta-logo">JA</div>
          <div className="meta-brand-meta">
            <div className="bn">Dr. Joey Alcantara</div>
            <div className="bs">★ 4.9 · 1,284 reviews · Calgary</div>
          </div>
        </div>

        <div className="meta-hero">
          <div className="meta-tag">FREE BACK PAIN ASSESSMENT</div>
          <h4>Stop the back pain.<br/><i>Without surgery.</i></h4>
          <p>30-min consult with Dr. Joey. No referral. Same-week openings.</p>
        </div>

        <div className="meta-form">
          <label className="lab">Full name</label>
          <div className="field filled">Sarah Mendez</div>
          <label className="lab">Email</label>
          <div className="field filled">sarah.mendez@gmail.com</div>
          <label className="lab">Phone</label>
          <div className={"field" + (focusedNum ? " focused filled" : "")}>
            <span className="typed">{focusedNum ? "(403) " + typed : "Phone number"}</span>
            {focusedNum && !submitting && <span className="cur" />}
          </div>
          <button className={submitting ? "submitting" : ""}>
            {submitting ? "✓ Submitted · Sophie will call in 47s" : "Book my free consult →"}
          </button>
          <div className="meta-trust">
            <span>🔒 HIPAA secure</span>
            <span>· No spam</span>
            <span>· Book in 60s</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function IMessageScreen({ progress }) {
  const messages = [
    { side: "in",  text: "Hey Sarah! It's Sophie from Dr. Joey's office.", showAt: 0.0 },
    { side: "in",  text: "Want me to lock in tomorrow at 2pm or Thursday at 10am for your back assessment?", showAt: 0.15, same: true },
    { side: "out", text: "Tomorrow at 2 works 🙏", showAt: 0.45 },
    { side: "in",  text: "All booked. See you then 🙌", showAt: 0.7 },
    { side: "in",  text: "I'll text the address + intake form now.", showAt: 0.78, same: true },
  ];
  const visible = messages.filter(m => progress >= m.showAt);
  const showTyping = progress > 0.85 && progress < 1;
  return (
    <div className="imessage">
      <div className="imessage-hd">
        <div className="av">S</div>
        <div className="nm">Sophie · Ad Scaling AI</div>
        <div className="sub">iMessage · just now</div>
      </div>
      <div className="imessage-body">
        {visible.map((m, i) => (
          <div key={i} className={"bubble " + m.side + (m.same ? " same" : "")}>
            {m.text}
          </div>
        ))}
        {showTyping && (
          <div className="bubble typing"><span/><span/><span/></div>
        )}
      </div>
    </div>
  );
}

function PushScreen({ progress }) {
  // 4 weeks, mark booked days
  const days = Array.from({ length: 28 }, (_, i) => i + 1);
  const booked = [3, 8, 12, 17, 19, 22];
  const newBook = 22;
  const showCard = progress > 0.2;
  return (
    <div className="push-screen">
      <div className="time">2:14</div>
      <div className="date">Tuesday, March 19</div>
      {showCard && (
        <div className="push-card">
          <div className="ico">📅</div>
          <div className="body">
            <div className="top">
              <span className="app">DR. JOEY · BOOKINGS</span>
              <span className="when">now</span>
            </div>
            <div className="ttl">📅 New booking · Sarah Mendez</div>
            <div className="desc">Tomorrow 2pm · Dr. Joey's office · $50 deposit charged</div>
          </div>
        </div>
      )}
      <div className="push-cal">
        <div className="push-cal-hd">
          <span>March</span>
          <span style={{ color: "rgba(255,255,255,0.5)" }}>47 booked</span>
        </div>
        <div className="push-cal-grid">
          {days.map(d => (
            <div key={d} className={"d" + (booked.includes(d) ? " book" : "") + (d === newBook && progress > 0.5 ? " new" : "")}>
              {d}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function YourAccount({ progress }) {
  return (
    <div className="your-account">
      <svg width="0" height="0">
        <defs>
          <linearGradient id="yaGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="oklch(0.62 0.22 295)" stopOpacity="0.6"/>
            <stop offset="100%" stopColor="oklch(0.62 0.22 295)" stopOpacity="0"/>
          </linearGradient>
        </defs>
      </svg>
      <div className="hd">
        <span>YOUR ACCOUNT · LIVE</span>
        <span style={{ color: "var(--ok)" }}>● ON</span>
      </div>
      <div className="title">Dr. Joey Alcantara</div>
      <div className="ya-sub">Renuva Spine &amp; Wellness · Calgary · April 2026</div>

      <div className="grid">
        <div className="ya-tile">
          <div className="l">Leads · April</div>
          <div className="v">324</div>
          <div className="delta">↑ 1.6× vs Feb</div>
        </div>
        <div className="ya-tile">
          <div className="l">CPL · April</div>
          <div className="v">$4.70</div>
          <div className="delta">vs $3.41 in Mar</div>
        </div>
        <div className="ya-tile span2">
          <div className="l">CPL · trailing 3 months</div>
          <div className="v">$3.96<span className="sub"> avg</span></div>
          <svg className="ya-chart" viewBox="0 0 220 60" preserveAspectRatio="none">
            {/* Feb $3.78 → Mar $3.41 (peak/low) → Apr $4.70 — lower is better, so invert */}
            <path className="fill" d="M0 24 L110 36 L220 12 L220 60 L0 60 Z" />
            <path className="line" d="M0 24 L110 36 L220 12" />
          </svg>
        </div>
      </div>

      <div className="ya-row">
        <div className="ya-row-l">AD SPEND · APRIL</div>
        <div className="ya-row-v">$1,524</div>
      </div>
      <div className="ya-row">
        <div className="ya-row-l">COST PER LEAD</div>
        <div className="ya-row-v">$4.70</div>
        <div className="ya-row-d">↑ $1.29</div>
      </div>
      <div className="ya-row">
        <div className="ya-row-l">CTR</div>
        <div className="ya-row-v">4.86%</div>
      </div>
      <div className="ya-row">
        <div className="ya-row-l">REACH</div>
        <div className="ya-row-v">40,093</div>
      </div>

      <div className="ya-section">3-MONTH TRAJECTORY</div>
      <div className="ya-list">
        <div className="ya-li"><span className="t">FEB</span><span className="n">323 leads · $3.78 CPL</span><span className="b">$1,222</span></div>
        <div className="ya-li"><span className="t">MAR</span><span className="n">442 leads · $3.41 CPL</span><span className="b new">PEAK</span></div>
        <div className="ya-li"><span className="t">APR</span><span className="n">324 leads · $4.70 CPL</span><span className="b">$1,524</span></div>
      </div>

      <div className="ya-foot">
        <span>META · MESSAGING ADS</span>
        <span>SOURCE: META ADS MANAGER</span>
      </div>
    </div>
  );
}

function Journey() {
  const [step, setStep] = useState(0);
  const [stepProgress, setStepProgress] = useState(0);
  const stepRefs = useRef([]);
  const railRef = useRef(null);
  const phoneStickyRef = useRef(null);

  // Mobile: per-step animated progress (0→1 driven by IntersectionObserver)
  const [mobileProgress, setMobileProgress] = useState([0, 0, 0, 0]);
  const mobileStepRefs = useRef([]);

  useEffect(() => {
    const cleanups = mobileStepRefs.current.map((el, i) => {
      if (!el) return null;
      let started = false;
      const obs = new IntersectionObserver(([entry]) => {
        if (entry.isIntersecting && !started) {
          started = true;
          let t0 = null;
          const DURATION = 1500;
          const tick = (ts) => {
            if (!t0) t0 = ts;
            const p = Math.min((ts - t0) / DURATION, 1);
            setMobileProgress(prev => {
              const next = [...prev];
              next[i] = p;
              return next;
            });
            if (p < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
          obs.disconnect();
        }
      }, { threshold: 0.25 });
      obs.observe(el);
      return () => obs.disconnect();
    });
    return () => cleanups.forEach(c => c && c());
  }, []);

  useEffect(() => {
    const onScroll = () => {
      let active = 0;
      let progress = 0;
      stepRefs.current.forEach((el, i) => {
        if (!el) return;
        const r = el.getBoundingClientRect();
        const vh = window.innerHeight;
        const center = r.top + r.height / 2;
        if (center < vh * 0.7 && r.bottom > 0) {
          active = i;
          const p = (vh * 0.7 - center) / (vh * 0.4);
          progress = Math.max(0, Math.min(1, p));
        }
      });
      setStep(active);
      setStepProgress(progress);

      // JS sticky: manually translateY the phone to stay in view the full journey
      if (railRef.current && phoneStickyRef.current) {
        const railRect = railRef.current.getBoundingClientRect();
        const phoneH = phoneStickyRef.current.offsetHeight;
        const TOP = 80; // px from viewport top
        const rawY = TOP - railRect.top;
        const maxY = railRect.height - phoneH;
        const translateY = Math.max(0, Math.min(rawY, maxY));
        phoneStickyRef.current.style.transform = `translateY(${translateY}px)`;
      }
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  const getPhoneFaceAt = (i, p) => {
    if (i === 0) return <MetaFrame progress={p} />;
    if (i === 1) return <IMessageScreen progress={p} />;
    if (i === 2) return <PushScreen progress={p} />;
    return <YourAccount progress={p} />;
  };

  const getPhoneFace = (i) => {
    const p = i === step ? stepProgress : (i < step ? 1 : 0);
    return getPhoneFaceAt(i, p);
  };

  return (
    <section className="sec journey" id="how">
      <div className="sec-inner" style={{ marginBottom: 24, textAlign: "center" }}>
        <span className="eyebrow"><span className="dot" /> ONE REAL CUSTOMER</span>
        <h2 className="display" style={{ marginTop: 24 }}>
          Our Scaling System In Action.<br/><span className="it">Watch what happens.</span>
        </h2>
      </div>

      {/* MOBILE layout — shown via CSS at ≤920px */}
      <div className="journey-mobile">
        {JOURNEY_STEPS.map((s, i) => (
          <div key={s.id} className="journey-mobile-step" ref={el => mobileStepRefs.current[i] = el}>
            {/* 1. STEP HEADER — above phone */}
            <div className="journey-mobile-label">
              <div className="step-num">
                <span>STEP {s.num}</span>
                <span className="line" />
                <span className="step-eyebrow">{s.eyebrow}</span>
              </div>
            </div>
            {/* 2. PHONE — middle */}
            <div className="journey-mobile-phone">
              <IPhone><IOSStatus />{getPhoneFaceAt(i, mobileProgress[i])}</IPhone>
            </div>
            {/* 3. BODY TEXT — below phone */}
            <div className="journey-mobile-content">
              <h3>{s.ttl}</h3>
              <p>{s.body}</p>
              <ul>{s.points.map((p, j) => <li key={j}><span className="check">✓</span> {p}</li>)}</ul>
            </div>
          </div>
        ))}
      </div>

      {/* DESKTOP layout — shown via CSS at >920px */}
      <div className="journey-rail" ref={railRef}>
        <div className="journey-phone-col">
          <div className="journey-phone-sticky" ref={phoneStickyRef}>
            <IPhone><IOSStatus />{getPhoneFace(step)}</IPhone>
          </div>
        </div>
        <div className="journey-steps">
          {JOURNEY_STEPS.map((s, i) => (
            <div key={s.id} className="journey-step" ref={el => stepRefs.current[i] = el}>
              <div className="step-num">
                <span>STEP {s.num}</span>
                <span className="line" />
                <span className="step-eyebrow">{s.eyebrow}</span>
              </div>
              <h3>{s.ttl}</h3>
              <p>{s.body}</p>
              <ul>{s.points.map((p, j) => <li key={j}><span className="check">✓</span> {p}</li>)}</ul>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Journey });
