function SurveyMock({ compact = false }) {
  const scaleColors = [
    'bg-[#e53935]', // 1
    'bg-[#e8513a]', // 2
    'bg-[#e07a2e]', // 3
    'bg-[#cf9230]', // 4
    'bg-[#a8b53d]', // 5
    'bg-[#86c241]', // 6
    'bg-[#5fb83e]', // 7
    'bg-[#3aa53a]', // 8
    'bg-[#33a033]', // 9
    'bg-[#2f9c2f]', // 10
  ];

  if (compact) {
    return (
      <div className="px-2 pt-4 pb-2 h-full flex flex-col">
        <div className="text-[7px] font-semibold text-slate-900 leading-snug mb-1.5">
          How motivated have you felt about your work in the last month? <span className="text-rose-500">*</span>
        </div>
        <div className="flex items-center justify-between text-[5.5px] text-slate-500 mb-1">
          <span>Not at all motivated</span>
          <span>Extremely motivated</span>
        </div>
        <div className="grid grid-cols-5 gap-1">
          {[1,2,3,4,5,6,7,8,9,10].map((n, i) => (
            <div
              key={n}
              className={`${scaleColors[i]} aspect-square rounded-[3px] text-white text-[7px] font-bold flex items-center justify-center shadow-sm`}
            >
              {n}
            </div>
          ))}
        </div>
        <div className="mt-auto flex justify-end pt-2">
          <span className="inline-flex items-center text-[6px] font-semibold text-white bg-blue-600 rounded px-2 py-0.5">
            Next →
          </span>
        </div>
      </div>
    );
  }

  return (
    <div className="px-3.5 py-2 h-full flex flex-col">
      <div className="text-[10px] font-semibold text-slate-900 leading-snug mb-1">
        How motivated have you felt about your work in the last month? <span className="text-rose-500">*</span>
      </div>
      <div className="flex items-center justify-between text-[8px] text-slate-500 mb-1">
        <span>Not at all motivated</span>
        <span>Extremely motivated</span>
      </div>
      <div className="grid grid-cols-10 gap-1">
        {[1,2,3,4,5,6,7,8,9,10].map((n, i) => (
          <div
            key={n}
            className={`${scaleColors[i]} rounded-[4px] text-white text-[10px] font-bold flex items-center justify-center shadow-sm`}
            style={{ aspectRatio: '1 / 1' }}
          >
            {n}
          </div>
        ))}
      </div>
      <div className="mt-auto flex justify-end pt-1.5">
        <span className="inline-flex items-center gap-1 text-[9px] font-semibold text-white bg-blue-600 rounded-md px-2 py-1 shadow-sm">
          Next →
        </span>
      </div>
    </div>
  );
}

function ScreenMessaging({ playing = false }) {
  const [t, setT] = useStateFS(0);

  const LOOP = 14; // seconds — two scenes: builder, then devices.

  React.useEffect(() => {
    if (!playing) { setT(0); return; }
    let start = performance.now();
    let raf;
    const tick = (now) => {
      setT(((now - start) / 1000) % LOOP);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [playing]);

  // Channel checkbox centers (% of the relative stage). Order matches the grid below.
  // Two columns: left col ≈ 11% x, right col ≈ 51% x. Two rows in channels card.
  // Y values are tuned for the full 440px stage so the cursor lands on the actual checkboxes.
  const targets = [
    { x: 11, y: 44 },  // Work Email
    { x: 51, y: 44 },  // Personal Email
    { x: 11, y: 52 },  // Work Mobile
    { x: 51, y: 52 },  // Personal Mobile
  ];

  // Idle/home for the cursor — bottom-right corner before action.
  const HOME = { x: 88, y: 72 };

  // Per-channel beats: arrive → click → settled. Spaced across the loop so the
  // last channel finishes around 7.5s, leaving the final ~4s to hold the
  // "every channel reached" state.
  const beats = [
    { arrive: 0.6, click: 1.4 },   // Work Email
    { arrive: 2.1, click: 2.7 },   // Personal Email
    { arrive: 3.5, click: 4.1 },   // Work Mobile
    { arrive: 5.1, click: 5.8 },   // Personal Mobile
  ];

  const easeInOut = (p) => (p < 0.5 ? 2 * p * p : 1 - Math.pow(-2 * p + 2, 2) / 2);

  // Walk through beats to find current cursor position and channel state.
  let cursorX = HOME.x, cursorY = HOME.y;
  let prev = HOME;
  let clickPulse = 0; // 0..1 ripple intensity
  const checked = [false, false, false, false];
  let hovered = -1;

  for (let i = 0; i < beats.length; i++) {
    const b = beats[i];
    const tgt = targets[i];
    const prevClickT = i === 0 ? 0 : beats[i - 1].click + 0.05;

    if (t >= prevClickT && t < b.arrive) {
      // Glide from prev → tgt
      const p = easeInOut((t - prevClickT) / (b.arrive - prevClickT));
      cursorX = prev.x + (tgt.x - prev.x) * p;
      cursorY = prev.y + (tgt.y - prev.y) * p;
      break;
    }
    if (t >= b.arrive && t < b.click) {
      cursorX = tgt.x;
      cursorY = tgt.y;
      hovered = i;
      break;
    }
    if (t >= b.click) {
      // Click has happened.
      checked[i] = true;
      // Ripple for 0.35s after click.
      if (t < b.click + 0.35) {
        clickPulse = 1 - (t - b.click) / 0.35;
      }
      cursorX = tgt.x;
      cursorY = tgt.y;
      hovered = i;
      prev = tgt;
      // Don't break — let later beats overwrite checked/cursor as time advances.
    }
  }

  // After the last click, drift cursor down to HOME by the final hold.
  const lastClick = beats[beats.length - 1].click;
  if (t > lastClick + 0.5) {
    const p = easeInOut(Math.min(1, (t - (lastClick + 0.5)) / 1.2));
    cursorX = targets[3].x + (HOME.x - targets[3].x) * p;
    cursorY = targets[3].y + (HOME.y - targets[3].y) * p;
    hovered = -1;
  }

  const onCount = checked.filter(Boolean).length;

  // Dynamic headline copy keyed to how many channels are live.
  const headlines = [
    'Pick the channels that actually reach them.',
    'Work email, for people at a desk.',
    '…and personal email, for after hours.',
    '…and work SMS, for people on the move.',
    'Every channel · every colleague reached.',
  ];
  const headline = headlines[onCount];

  // Audience number ticks up as more channels go live.
  const audience = [238, 412, 588, 712, 842][onCount];

  // ── Scene gating ────────────────────────────────────────────────────
  // Scene A (builder): 0 → 6.6s visible, then exits.
  // Scene B (devices): 7.0s → 13.2s visible, then exits before loop restarts.
  const A_OUT_START = 6.6;  // builder begins exit
  const A_OUT_END   = 7.2;
  const B_IN_START  = 7.0;  // devices begin entering
  const B_HOLD_END  = 12.8; // devices begin exit
  const B_OUT_END   = 13.6;

  // Builder opacity/scale during its exit.
  let builderOpacity = 1;
  let builderScale = 1;
  if (t >= A_OUT_START) {
    const p = Math.min(1, (t - A_OUT_START) / (A_OUT_END - A_OUT_START));
    builderOpacity = 1 - p;
    builderScale = 1 - 0.06 * p;
  }
  if (t < 0.4) {
    // Soft fade-in at loop start so the reset isn't a hard cut.
    const p = t / 0.4;
    builderOpacity = Math.min(builderOpacity, p);
  }
  const builderVisible = t < A_OUT_END;

  // Once devices scene is active we hide the cursor / freeze its state.
  const devicesVisible = t >= B_IN_START;

  // Device entry/exit progress.
  const clamp01 = (v) => Math.max(0, Math.min(1, v));
  const devIn  = clamp01((t - B_IN_START) / 0.6);
  const devOut = clamp01((t - B_HOLD_END) / (B_OUT_END - B_HOLD_END));
  const phoneStagger = clamp01((t - (B_IN_START + 0.25)) / 0.6);

  // Big copy that floats above the devices scene — cycles to drive the point.
  let deviceCopy = 'Every channel · every colleague reached.';
  if (t > 9.0 && t < 11.0) deviceCopy = 'Inbox, pocket, anywhere they are.';
  else if (t >= 11.0) deviceCopy = 'No one left out, not even the frontline.';


  const channels = [
    { label: 'Work Email',      desc: 'Send to employee work email',    Icon: IconMail,       color: 'text-slate-900'  },
    { label: 'Personal Email',  desc: 'Send to personal email',         Icon: IconMail,       color: 'text-sky-500'    },
    { label: 'Work Mobile',     desc: 'SMS to work mobile numbers',     Icon: IconSmartphone, color: 'text-emerald-500'},
    { label: 'Personal Mobile', desc: 'SMS to personal mobile numbers', Icon: IconSmartphone, color: 'text-amber-500'  },
  ];

  return (
    <div className="relative w-full h-full bg-white">
      <div className="relative w-full h-full bg-slate-50/60 overflow-hidden select-none">
        {/* ── Scene A — Campaign builder (with its own faux window chrome) ── */}
        {builderVisible && (
        <div
          className="absolute inset-0"
          style={{
            opacity: builderOpacity,
            transform: `scale(${builderScale})`,
            transformOrigin: 'center center',
            transition: 'none',
          }}
        >
        {/* Faux top bar — part of Scene A only, disappears with builder */}
        <div className="flex items-center gap-2 px-4 py-3 border-b border-slate-100 bg-slate-50">
          <span className="h-2.5 w-2.5 rounded-full bg-slate-300" />
          <span className="h-2.5 w-2.5 rounded-full bg-slate-300" />
          <span className="h-2.5 w-2.5 rounded-full bg-slate-300" />
          <span className="ml-3 text-[12px] font-medium text-slate-500 truncate">Messaging · campaign builder</span>
        </div>
        <div className="p-4 sm:p-5 space-y-2.5">
          {/* Audience */}
          <div className="rounded-lg bg-white border border-slate-200 p-3">
            <div className="flex items-center justify-between">
              <div className="text-[10px] uppercase tracking-wider font-semibold text-slate-500">Audience</div>
              <div className={`text-[11px] font-semibold text-blue-700 transition-all duration-300 ${onCount > 0 ? 'scale-100' : 'scale-95 opacity-70'}`}>
                {audience} will receive this
              </div>
            </div>
            <div className="mt-1.5 flex flex-wrap gap-1">
              {['Repairs operatives','Started in last 14 days','Patch: South','Active'].map(tag => (
                <span key={tag} className="inline-flex items-center text-[10px] font-medium bg-blue-50 border border-blue-100 text-blue-800 px-1.5 py-0.5 rounded-md">{tag}</span>
              ))}
            </div>
          </div>

          {/* Channels */}
          <div className="rounded-lg bg-white border border-slate-200 p-3 relative">
            <div className="flex items-center justify-between mb-2">
              <div className="text-[10px] uppercase tracking-wider font-semibold text-slate-500">Channels</div>
              <div className="text-[10px] font-semibold text-slate-500">{onCount} of 4 selected</div>
            </div>
            <div className="grid grid-cols-2 gap-x-3 gap-y-2">
              {channels.map(({ label, desc, Icon, color }, i) => {
                const isOn = checked[i];
                const isHover = hovered === i && !isOn;
                return (
                  <div
                    key={label}
                    className={`flex items-start gap-1.5 rounded-md px-1.5 py-1 -mx-1.5 -my-1 transition-colors duration-150 ${isHover ? 'bg-blue-50/70' : ''}`}
                  >
                    <span
                      className={`mt-0.5 inline-flex items-center justify-center h-3.5 w-3.5 rounded-sm border shrink-0 transition-all duration-200 ${isOn ? 'bg-blue-600 border-blue-600 text-white scale-110' : 'bg-white border-slate-300'}`}
                    >
                      {isOn && <IconCheck size={10} strokeWidth={3.5} />}
                    </span>
                    <Icon size={13} className={`${color} mt-0.5 shrink-0`} />
                    <div className="min-w-0">
                      <div className="text-[11px] font-semibold text-slate-900 leading-tight">{label}</div>
                      <div className="text-[10px] text-slate-500 leading-tight mt-0.5 truncate">{desc}</div>
                    </div>
                  </div>
                );
              })}
            </div>

            {/* Dynamic headline strip — sits under the channels grid, swaps on each tick */}
            <div className="mt-2.5 h-[18px] overflow-hidden relative">
              <div
                key={onCount}
                className="text-[11px] font-semibold text-slate-800 absolute inset-0 flex items-center"
                style={{ animation: 'fsm-slideUp 360ms ease-out both' }}
              >
                {headline}
              </div>
            </div>
          </div>

          {/* Schedule */}
          <div className="rounded-lg bg-white border border-slate-200 p-3">
            <div className="text-[10px] uppercase tracking-wider font-semibold text-slate-500 mb-1">Schedule</div>
            <div className="text-[12px] text-slate-800">Monday 09:00, repeating fortnightly until 31 Mar 2026</div>
          </div>
        </div>

        {/* Cursor — only on the builder scene */}
        <div
          className="absolute pointer-events-none z-50 select-none"
          style={{ left: `${cursorX}%`, top: `${cursorY}%`, transition: 'none' }}
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path
              d="M4.5 3V19.5L9.75 14.25H18.75L4.5 3Z"
              fill="white"
              stroke="#0f172a"
              strokeWidth="2.5"
              strokeLinejoin="round"
            />
          </svg>
        </div>

        {clickPulse > 0 && (
          <span
            className="absolute pointer-events-none border-2 border-blue-500 rounded-full z-40"
            style={{
              left: `${cursorX}%`,
              top: `${cursorY}%`,
              width: `${10 + (1 - clickPulse) * 18}px`,
              height: `${10 + (1 - clickPulse) * 18}px`,
              marginLeft: `-${(10 + (1 - clickPulse) * 18) / 2}px`,
              marginTop: `-${(10 + (1 - clickPulse) * 18) / 2}px`,
              opacity: clickPulse,
              transition: 'none',
            }}
          />
        )}
        </div>
        )}

        {/* ── Scene B — Devices (laptop + phone), both showing the survey ── */}
        {devicesVisible && (
        <div
          className="absolute inset-0 flex flex-col items-center justify-center gap-3 px-6 pt-3"
          style={{ opacity: devIn * (1 - devOut), transition: 'none' }}
        >
          {/* Dynamic headline above the devices */}
          <div
            key={deviceCopy}
            className="text-[15px] font-semibold text-slate-900 text-center"
            style={{ animation: 'fsm-slideUp 380ms ease-out both' }}
          >
            {deviceCopy}
          </div>
          <div className="flex items-center justify-center gap-4 w-full">
          {/* Laptop — slides in from the left, 16:10 screen */}
          <div
            className="relative"
            style={{
              width: '62%',
              transform: `translateX(${(1 - devIn) * -32}px) scale(${0.95 + devIn * 0.05})`,
              transformOrigin: 'center center',
              transition: 'none',
            }}
          >
            <div className="rounded-[10px] bg-slate-900 p-1.5 shadow-cardlg">
              <div className="rounded-[6px] bg-white overflow-hidden flex flex-col" style={{ aspectRatio: '16 / 11' }}>
                {/* Faux browser bar */}
                <div className="flex items-center gap-1 px-2 py-1 bg-slate-100 border-b border-slate-200 shrink-0">
                  <span className="h-1.5 w-1.5 rounded-full bg-slate-300" />
                  <span className="h-1.5 w-1.5 rounded-full bg-slate-300" />
                  <span className="h-1.5 w-1.5 rounded-full bg-slate-300" />
                  <span className="ml-1.5 text-[8px] font-medium text-slate-400 truncate">colleaguepulse.co.uk/survey/q3-pulse</span>
                </div>
                <div className="flex-1 min-h-0">
                  <SurveyMock scale={1} />
                </div>
              </div>
            </div>
            <div className="h-1.5 mx-auto w-[72%] rounded-b-[6px] bg-slate-800/90" />
            <div className="h-0.5 mx-auto w-[16%] rounded-b-md bg-slate-700" />
          </div>

          {/* Phone — slides in from the right, staggered */}
          <div
            className="relative shrink-0"
            style={{
              width: '17%',
              transform: `translateY(${(1 - phoneStagger) * 24}px) scale(${0.9 + phoneStagger * 0.1})`,
              transformOrigin: 'center center',
              opacity: phoneStagger,
              transition: 'none',
            }}
          >
            <div className="rounded-[18px] bg-slate-900 p-1 shadow-cardlg">
              <div className="rounded-[14px] bg-white overflow-hidden relative" style={{ aspectRatio: '9 / 18' }}>
                {/* Notch */}
                <div className="absolute top-1 left-1/2 -translate-x-1/2 h-1 w-6 rounded-full bg-slate-900/90 z-10" />
                <SurveyMock scale={0.62} compact />
              </div>
            </div>
          </div>
          </div>
        </div>
        )}

        <style>{`
          @keyframes fsm-slideUp {
            from { transform: translateY(8px); opacity: 0; }
            to   { transform: translateY(0);   opacity: 1; }
          }
          @keyframes fsm-fadeIn {
            from { opacity: 0; transform: translateY(2px); }
            to   { opacity: 1; transform: translateY(0); }
          }
        `}</style>
      </div>
    </div>
  );
}

