// scene.jsx — Onboarding animation scene
// Mid-fi: clear geometric shapes, muted palette, single accent.

const PALETTE = {
  card:    '#ffffff',
  cardBorder: 'rgba(15, 20, 30, 0.08)',
  ink:     '#1a1f2a',
  inkSoft: '#8a93a3',
  track:   '#eef0f4',
  accent:  'oklch(62% 0.14 250)',   // calm blue
  accentSoft: 'oklch(92% 0.04 250)',
  ok:      'oklch(64% 0.14 155)',   // green check
  okSoft:  'oklch(93% 0.05 155)',
  shadow:  '0 18px 40px -18px rgba(15, 20, 30, 0.22), 0 2px 6px -2px rgba(15, 20, 30, 0.06)',
};

// ── Root scene ──────────────────────────────────────────────────────────────
function OnboardingScene() {
  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <ChecklistCard />
      <Cursor />
    </div>
  );
}

// ── Main checklist card ─────────────────────────────────────────────────────
function ChecklistCard() {
  const t = useTime();

  // Card entry (0 → 0.6s)
  const cardOp = animate({ from: 0, to: 1, start: 0, end: 0.5, ease: Easing.easeOutCubic })(t);
  const cardScale = animate({ from: 0.96, to: 1, start: 0, end: 0.6, ease: Easing.easeOutBack })(t);

  // Card exit at very end (8.4 → 8.9)
  const cardFade = animate({ from: 1, to: 0, start: 8.4, end: 8.9, ease: Easing.easeInCubic })(t);

  // 4 steps, each with check + hold times
  const steps = [
    { label: 'Account', checkAt: 1.4, fillStart: 1.0 },
    { label: 'Profile picture', checkAt: 3.1, fillStart: 2.5 },
    { label: 'Preferences', checkAt: 4.8, fillStart: 4.2 },
    { label: 'Invite team', checkAt: 6.5, fillStart: 5.9 },
  ];

  // Progress bar (0 → 4/4 over steps)
  const progress = interpolate(
    [0.8, 1.4, 3.1, 4.8, 6.5],
    [0, 0.25, 0.5, 0.75, 1],
    Easing.easeOutCubic
  )(t);

  // Complete celebration at 6.8
  const completeOp = animate({ from: 0, to: 1, start: 6.7, end: 7.2, ease: Easing.easeOutBack })(t);
  const completeY  = animate({ from: 8, to: 0, start: 6.7, end: 7.2, ease: Easing.easeOutBack })(t);

  const W = 520, H = 540;
  return (
    <div style={{
      position: 'absolute',
      left: '50%', top: '50%',
      width: W, height: H,
      marginLeft: -W/2, marginTop: -H/2,
      opacity: cardOp * cardFade,
      transform: `scale(${cardScale})`,
      transformOrigin: 'center',
      background: PALETTE.card,
      border: `1px solid ${PALETTE.cardBorder}`,
      borderRadius: 18,
      boxShadow: PALETTE.shadow,
      padding: '32px 36px',
      boxSizing: 'border-box',
      fontFamily: 'Inter, system-ui, sans-serif',
      color: PALETTE.ink,
      overflow: 'hidden',
    }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
        <div style={{
          width: 10, height: 10, borderRadius: 3,
          background: PALETTE.accent,
        }}/>
        <div style={{ fontSize: 13, fontWeight: 500, color: PALETTE.inkSoft, letterSpacing: '0.02em' }}>
          GETTING STARTED
        </div>
      </div>

      <div style={{ fontSize: 26, fontWeight: 600, letterSpacing: '-0.02em', marginBottom: 4 }}>
        Let's set things up
      </div>
      <div style={{ fontSize: 14, color: PALETTE.inkSoft, marginBottom: 22 }}>
        Four quick steps to get you started.
      </div>

      {/* Progress bar */}
      <div style={{
        position: 'relative',
        height: 6,
        background: PALETTE.track,
        borderRadius: 3,
        overflow: 'hidden',
        marginBottom: 26,
      }}>
        <div style={{
          position: 'absolute', left: 0, top: 0, bottom: 0,
          width: `${progress * 100}%`,
          background: PALETTE.accent,
          borderRadius: 3,
          transition: 'none',
        }}/>
      </div>

      {/* Steps */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {steps.map((s, i) => (
          <StepRow key={i} index={i} label={s.label}
                   checkAt={s.checkAt} fillStart={s.fillStart} />
        ))}
      </div>

      {/* "All set" celebration appears over last item */}
      <div style={{
        position: 'absolute',
        left: 36, right: 36, bottom: 32,
        opacity: completeOp,
        transform: `translateY(${completeY}px)`,
        display: 'flex', alignItems: 'center', gap: 10,
        padding: '12px 14px',
        background: PALETTE.okSoft,
        borderRadius: 10,
        border: `1px solid oklch(85% 0.06 155)`,
      }}>
        <CheckIcon size={16} color={PALETTE.ok} bg="transparent" progress={1} />
        <div style={{ fontSize: 14, fontWeight: 500, color: 'oklch(40% 0.08 155)' }}>
          You're all set
        </div>
      </div>
    </div>
  );
}

// ── Step row ────────────────────────────────────────────────────────────────
function StepRow({ index, label, checkAt, fillStart }) {
  const t = useTime();

  const isActive = t >= fillStart && t < checkAt + 0.3;
  const isDone = t >= checkAt;

  // Row highlight
  const activeOp = animate({ from: 0, to: 1, start: fillStart - 0.1, end: fillStart + 0.2, ease: Easing.easeOutCubic })(t);
  const deactivateOp = animate({ from: 1, to: 0, start: checkAt + 0.2, end: checkAt + 0.5, ease: Easing.easeInCubic })(t);
  const highlight = Math.min(activeOp, 1 - (t > checkAt + 0.2 ? (deactivateOp === 0 ? 1 : 1 - deactivateOp) : 0));
  const bgOpacity = isDone ? 0 : activeOp * (t > checkAt + 0.2 ? deactivateOp : 1);

  // Check animation: circle fills, check draws
  const checkProgress = animate({ from: 0, to: 1, start: checkAt, end: checkAt + 0.4, ease: Easing.easeOutCubic })(t);

  // Mini previews swap in when active
  return (
    <div style={{
      position: 'relative',
      display: 'flex', alignItems: 'center', gap: 14,
      padding: '10px 12px',
      borderRadius: 10,
      background: `oklch(97% 0.015 250 / ${bgOpacity})`,
      transition: 'none',
    }}>
      {/* Check circle */}
      <CheckIcon
        size={24}
        color={PALETTE.ok}
        bg={isDone ? PALETTE.okSoft : 'transparent'}
        border={isDone ? 'transparent' : (isActive ? PALETTE.accent : '#d6dae2')}
        progress={checkProgress}
        pulse={isActive && !isDone}
      />

      {/* Label */}
      <div style={{
        flex: 1,
        fontSize: 15,
        fontWeight: 500,
        color: isDone ? PALETTE.inkSoft : PALETTE.ink,
        textDecoration: isDone ? 'line-through' : 'none',
        textDecorationColor: 'rgba(138,147,163,0.5)',
      }}>
        {label}
      </div>

      {/* Per-step mini preview */}
      <StepPreview index={index} fillStart={fillStart} checkAt={checkAt} />
    </div>
  );
}

// ── Check icon (animated SVG) ───────────────────────────────────────────────
function CheckIcon({ size = 24, color, bg, border = 'transparent', progress = 0, pulse = false }) {
  const t = useTime();
  const pulseScale = pulse ? 1 + Math.sin(t * 6) * 0.04 : 1;
  // Stroke-dash animated check
  const pathLen = 14;
  const dashOffset = pathLen * (1 - progress);

  return (
    <div style={{
      width: size, height: size,
      flexShrink: 0,
      borderRadius: '50%',
      background: bg,
      border: `1.5px solid ${border}`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      transform: `scale(${pulseScale})`,
      boxSizing: 'border-box',
    }}>
      {progress > 0.02 && (
        <svg width={size * 0.55} height={size * 0.55} viewBox="0 0 12 12" fill="none">
          <path
            d="M2.5 6.2 L5 8.5 L9.5 3.8"
            stroke={color}
            strokeWidth="1.8"
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeDasharray={pathLen}
            strokeDashoffset={dashOffset}
          />
        </svg>
      )}
    </div>
  );
}

// ── Step previews (tiny animated vignettes) ─────────────────────────────────
function StepPreview({ index, fillStart, checkAt }) {
  const t = useTime();
  const activeStart = fillStart;
  const activeEnd = checkAt + 0.3;
  const active = t >= activeStart - 0.1 && t <= activeEnd + 0.3;
  if (!active) return <DonePreview index={index} checkAt={checkAt} />;

  const localT = t - activeStart;
  const dur = checkAt - activeStart;
  const p = clamp(localT / dur, 0, 1);

  const common = {
    width: 90, height: 28,
    display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: 4,
  };

  if (index === 0) return <AccountPreview p={p} style={common} />;
  if (index === 1) return <AvatarPreview p={p} style={common} />;
  if (index === 2) return <TogglePreview p={p} style={common} />;
  if (index === 3) return <TeamPreview p={p} style={common} />;
  return null;
}

function DonePreview({ index, checkAt }) {
  const t = useTime();
  const op = animate({ from: 0, to: 1, start: checkAt + 0.2, end: checkAt + 0.5, ease: Easing.easeOutCubic })(t);
  const label = ['Verified', 'Added', 'Saved', '3 invited'][index];
  return (
    <div style={{
      width: 90, display: 'flex', justifyContent: 'flex-end',
      fontSize: 12, color: PALETTE.inkSoft, opacity: op,
      fontVariantNumeric: 'tabular-nums',
    }}>
      {label}
    </div>
  );
}

// Account: email field being typed
function AccountPreview({ p, style }) {
  // Fake chars appearing
  const chars = Math.floor(p * 9);
  const dots = '●'.repeat(Math.min(chars, 8));
  return (
    <div style={{
      ...style,
      padding: '0 8px',
      background: '#f3f5f8',
      border: '1px solid #e4e7ec',
      borderRadius: 6,
      fontSize: 11,
      color: PALETTE.ink,
      letterSpacing: '0.1em',
      fontFamily: 'ui-monospace, SFMono-Regular, monospace',
      justifyContent: 'flex-start',
    }}>
      <span style={{ color: PALETTE.inkSoft }}>@</span>
      <span style={{ marginLeft: 2 }}>{dots}</span>
      {p < 0.95 && (
        <span style={{
          display: 'inline-block', width: 1, height: 12,
          background: PALETTE.accent, marginLeft: 1,
          opacity: (Math.sin(p * 30) + 1) / 2,
        }}/>
      )}
    </div>
  );
}

// Profile picture: avatar fills in from grey placeholder to initials
function AvatarPreview({ p, style }) {
  const fill = Easing.easeOutCubic(p);
  return (
    <div style={style}>
      <div style={{
        width: 28, height: 28, borderRadius: '50%',
        background: `oklch(${92 - fill * 32}% ${0.02 + fill * 0.10} 250)`,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: `rgba(255,255,255,${fill})`,
        fontSize: 11, fontWeight: 600,
        border: fill < 0.3 ? '1px dashed #c8ccd5' : 'none',
        transition: 'none',
        position: 'relative',
        overflow: 'hidden',
      }}>
        {fill > 0.5 ? 'JS' : (
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none" style={{ opacity: 1 - fill * 2 }}>
            <circle cx="7" cy="5" r="2.2" stroke="#a5acb8" strokeWidth="1.2"/>
            <path d="M3 12c1-2 2.5-3 4-3s3 1 4 3" stroke="#a5acb8" strokeWidth="1.2" strokeLinecap="round"/>
          </svg>
        )}
      </div>
    </div>
  );
}

// Preferences: two toggles flipping on
function TogglePreview({ p, style }) {
  const t1 = clamp(p * 2, 0, 1);       // first toggle at 0 → 0.5
  const t2 = clamp((p - 0.45) * 2.2, 0, 1); // second toggle later
  return (
    <div style={style}>
      <Toggle on={t1} />
      <Toggle on={t2} />
    </div>
  );
}
function Toggle({ on }) {
  const e = Easing.easeOutBack(clamp(on, 0, 1));
  return (
    <div style={{
      width: 28, height: 16, borderRadius: 8,
      background: `oklch(${92 - e * 30}% ${0.02 + e * 0.12} 250)`,
      position: 'relative', transition: 'none',
      border: '1px solid rgba(15,20,30,0.06)',
      boxSizing: 'border-box',
    }}>
      <div style={{
        position: 'absolute',
        top: 1, left: 1 + e * 12,
        width: 12, height: 12,
        borderRadius: '50%',
        background: '#fff',
        boxShadow: '0 1px 2px rgba(0,0,0,0.2)',
      }}/>
    </div>
  );
}

// Team: 3 avatars popping in
function TeamPreview({ p, style }) {
  const t1 = clamp(p * 3, 0, 1);
  const t2 = clamp((p - 0.25) * 3, 0, 1);
  const t3 = clamp((p - 0.5) * 3, 0, 1);
  const colors = ['oklch(68% 0.14 30)', 'oklch(72% 0.13 180)', 'oklch(70% 0.14 300)'];
  const tVals = [t1, t2, t3];
  return (
    <div style={{ ...style, gap: 0 }}>
      {tVals.map((tv, i) => {
        const e = Easing.easeOutBack(tv);
        return (
          <div key={i} style={{
            width: 22, height: 22, borderRadius: '50%',
            background: colors[i],
            marginLeft: i === 0 ? 0 : -6,
            border: '2px solid #fff',
            transform: `scale(${e})`,
            opacity: tv,
            boxSizing: 'border-box',
          }}/>
        );
      })}
    </div>
  );
}

// ── Floating accent cursor that moves between steps ─────────────────────────
function Cursor() {
  const t = useTime();
  // Cursor path: moves between step rows and clicks each
  const path = interpolate(
    [0.7, 1.4, 1.5, 2.4, 3.1, 3.2, 4.1, 4.8, 4.9, 5.8, 6.5, 6.8],
    // y positions for each step row
    [280, 280, 280, 340, 340, 340, 400, 400, 400, 460, 460, 460],
    Easing.easeInOutCubic
  )(t);

  const xPath = interpolate(
    [0.7, 1.4, 2.4, 3.1, 4.1, 4.8, 5.8, 6.5, 6.8],
    [440, 440, 440, 440, 440, 440, 440, 440, 460],
    Easing.easeInOutCubic
  )(t);

  // Click pulse on checkAts
  const clickTimes = [1.35, 3.05, 4.75, 6.45];
  const clickPulse = clickTimes.reduce((acc, ct) => {
    const d = t - ct;
    if (d >= 0 && d < 0.5) {
      return Math.max(acc, 1 - d / 0.5);
    }
    return acc;
  }, 0);

  const op = animate({ from: 0, to: 1, start: 0.4, end: 0.8 })(t)
           * animate({ from: 1, to: 0, start: 6.8, end: 7.3 })(t);

  return (
    <>
      {/* Click ripple */}
      {clickPulse > 0 && (
        <div style={{
          position: 'absolute',
          left: xPath - 18, top: path - 18,
          width: 36, height: 36,
          borderRadius: '50%',
          border: `2px solid ${PALETTE.accent}`,
          opacity: clickPulse * 0.7,
          transform: `scale(${1 + (1 - clickPulse) * 0.6})`,
          pointerEvents: 'none',
        }}/>
      )}
      {/* Cursor */}
      <svg
        width="22" height="22"
        viewBox="0 0 22 22"
        style={{
          position: 'absolute',
          left: xPath, top: path,
          opacity: op,
          filter: 'drop-shadow(0 2px 4px rgba(15,20,30,0.2))',
          pointerEvents: 'none',
        }}
      >
        <path
          d="M4 3 L4 17 L8 13 L10.5 18 L13 17 L10.5 12 L16 12 Z"
          fill="#1a1f2a"
          stroke="#fff"
          strokeWidth="1.2"
          strokeLinejoin="round"
        />
      </svg>
    </>
  );
}

Object.assign(window, { OnboardingScene, ChecklistCard, Cursor });
