// Sobella Meditations — animated visualization section for the landing
// A living "breathing orb" that demonstrates what a Sobella meditation feels like.
// Six library tracks; selecting one changes the theme, guided phrases, and wave.

const { useState: useMS, useEffect: useME, useRef: useMR, useMemo: useMM } = React;
function useWindowWidth() {
  const [w, setW] = useMS(window.innerWidth);
  useME(() => {
    const h = () => setW(window.innerWidth);
    window.addEventListener('resize', h);
    return () => window.removeEventListener('resize', h);
  }, []);
  return w;
}

const MEDITATIONS = [
  {
    id: 'urge',
    eyebrow: 'For a craving',
    title: 'Urge Surfing',
    duration: '4 min',
    theme: { bg: '#0B2017', ring: 'rgba(255,255,255,0.09)', orb: '#154734', glow: '#1f6b4f', accent: '#D6B98C' },
    phrases: [
      'The wave is already cresting.',
      'Feel where it lives in your body.',
      'Breathe in — slow, unhurried.',
      'Breathe out — softer than before.',
      'The wave is passing. You are still here.',
    ],
    breath: { inhale: 4.0, hold: 1.0, exhale: 6.0 },
  },
  {
    id: 'tuesday',
    eyebrow: 'For a quiet evening',
    title: '9pm on a Tuesday',
    duration: '6 min',
    theme: { bg: '#1a2e24', ring: 'rgba(230,197,155,0.10)', orb: '#2d4a3a', glow: '#3a6b52', accent: '#E8C89B' },
    phrases: [
      'Nothing has to happen tonight.',
      'This is not a night to get through.',
      'This is just a night.',
      'You are exactly where you should be.',
      'Breathe into the ordinary.',
    ],
    breath: { inhale: 4.0, hold: 2.0, exhale: 6.0 },
  },
  {
    id: 'morning',
    eyebrow: 'To begin the day',
    title: 'Morning Clarity',
    duration: '3 min',
    theme: { bg: '#1F2A1F', ring: 'rgba(255,220,180,0.10)', orb: '#2E4A32', glow: '#5A8560', accent: '#F4C77A' },
    phrases: [
      'This is a clear morning.',
      'Your mind has room today.',
      'Inhale — that is yours.',
      'Exhale — so is this.',
      'Step gently into the day.',
    ],
    breath: { inhale: 4.0, hold: 0.5, exhale: 5.0 },
  },
  {
    id: 'party',
    eyebrow: 'Before the room',
    title: 'Before the Party',
    duration: '2 min',
    theme: { bg: '#1a1626', ring: 'rgba(220,200,255,0.10)', orb: '#2d2550', glow: '#5a4a8c', accent: '#C9B8E8' },
    phrases: [
      'You know why you\'re going.',
      'You know what\'s in your glass.',
      'Nothing to prove tonight.',
      'You can leave when you want.',
      'Breathe. Walk in.',
    ],
    breath: { inhale: 3.5, hold: 1.0, exhale: 5.0 },
  },
  {
    id: 'slip',
    eyebrow: 'After a hard day',
    title: 'After a Slip',
    duration: '8 min',
    theme: { bg: '#2a1a1a', ring: 'rgba(255,180,150,0.09)', orb: '#4a2d2d', glow: '#8c5a4a', accent: '#E8A88C' },
    phrases: [
      'One day is not the whole story.',
      'You are allowed to begin again.',
      'Softness, not punishment.',
      'Breathe — this is still Chapter 2.',
      'Tomorrow is waiting, unjudging.',
    ],
    breath: { inhale: 4.0, hold: 2.0, exhale: 7.0 },
  },
  {
    id: 'win',
    eyebrow: 'On a good day',
    title: 'The Quiet Win',
    duration: '3 min',
    theme: { bg: '#1a2420', ring: 'rgba(200,255,220,0.10)', orb: '#2d4a3d', glow: '#4a8c6b', accent: '#A8E8C0' },
    phrases: [
      'This day. This breath. This one.',
      'Nobody else has to know.',
      'The small win is the whole win.',
      'You chose this — again.',
      'Let yourself feel it.',
    ],
    breath: { inhale: 4.0, hold: 1.0, exhale: 5.0 },
  },
];

// ── Breathing orb ─────────────────────────────────────────────
// Phase: 0..1 where inhale(0..0.4) → hold(0.4..0.5) → exhale(0.5..1)
function useBreathPhase(breath, playing) {
  const [t, setT] = useMS(0);
  const frame = useMR();
  const start = useMR(performance.now());
  const total = breath.inhale + breath.hold + breath.exhale;

  useME(() => {
    if (!playing) {
      cancelAnimationFrame(frame.current);
      return;
    }
    const loop = (now) => {
      const elapsed = ((now - start.current) / 1000) % total;
      setT(elapsed);
      frame.current = requestAnimationFrame(loop);
    };
    start.current = performance.now() - t * 1000;
    frame.current = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(frame.current);
  }, [playing, total]);

  let phase, label, ratio;
  if (t < breath.inhale) {
    phase = 'inhale';
    label = 'Breathe in';
    ratio = t / breath.inhale; // 0→1 swelling
  } else if (t < breath.inhale + breath.hold) {
    phase = 'hold';
    label = 'Hold';
    ratio = 1;
  } else {
    phase = 'exhale';
    label = 'Breathe out';
    const e = t - breath.inhale - breath.hold;
    ratio = 1 - (e / breath.exhale); // 1→0 shrinking
  }

  // smooth bell curve via ease-in-out-sine for orb size
  const eased = 0.5 - 0.5 * Math.cos(Math.PI * ratio);
  return { phase, label, ratio: eased, rawT: t, total };
}

function BreathingOrb({ meditation, playing }) {
  const { theme, breath } = meditation;
  const { ratio, label } = useBreathPhase(breath, playing);

  // Orb radius: 140 → 230 px
  const base = 140;
  const expand = 100;
  const r = base + ratio * expand;
  const blur = 40 + ratio * 30;

  return (
    <div style={{
      position: 'relative', width: 520, height: 520,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      {/* Outer fading rings */}
      {[0, 1, 2, 3].map(i => {
        const delay = i * 1.1;
        return (
          <div key={i} style={{
            position: 'absolute',
            width: 260 + i * 80,
            height: 260 + i * 80,
            borderRadius: '50%',
            border: `1px solid ${theme.ring}`,
            opacity: 0.6 - i * 0.12,
          }}/>
        );
      })}

      {/* Emitted pulse rings (CSS-driven, loop with breath total) */}
      <div className="med-pulse" style={{
        position: 'absolute', width: 300, height: 300, borderRadius: '50%',
        border: `1.5px solid ${theme.accent}`,
        opacity: 0,
        animation: `medPulse ${breath.inhale + breath.hold + breath.exhale}s ease-out infinite`,
      }}/>
      <div className="med-pulse" style={{
        position: 'absolute', width: 300, height: 300, borderRadius: '50%',
        border: `1.5px solid ${theme.accent}`,
        opacity: 0,
        animation: `medPulse ${breath.inhale + breath.hold + breath.exhale}s ease-out infinite`,
        animationDelay: `${(breath.inhale + breath.hold + breath.exhale) / 2}s`,
      }}/>

      {/* Glow halo */}
      <div style={{
        position: 'absolute',
        width: r * 2 + 200,
        height: r * 2 + 200,
        borderRadius: '50%',
        background: `radial-gradient(circle, ${theme.glow}55 0%, transparent 60%)`,
        filter: `blur(${blur}px)`,
        opacity: 0.7 + ratio * 0.3,
        transition: 'width 80ms linear, height 80ms linear, opacity 120ms linear',
      }}/>

      {/* Main orb */}
      <div style={{
        position: 'relative',
        width: r, height: r,
        borderRadius: '50%',
        background: `radial-gradient(circle at 35% 30%, ${theme.glow} 0%, ${theme.orb} 55%, ${theme.bg} 100%)`,
        boxShadow: `
          inset 0 -30px 60px rgba(0,0,0,0.3),
          inset 0 20px 40px ${theme.accent}22,
          0 0 80px ${theme.glow}44
        `,
        transition: 'width 80ms linear, height 80ms linear',
      }}>
        {/* Inner shine */}
        <div style={{
          position: 'absolute', top: '15%', left: '22%',
          width: '35%', height: '30%',
          borderRadius: '50%',
          background: `radial-gradient(ellipse, ${theme.accent}55 0%, transparent 70%)`,
          filter: 'blur(12px)',
        }}/>
        {/* Breath label */}
        <div style={{
          position: 'absolute', inset: 0,
          display: 'flex', flexDirection: 'column',
          alignItems: 'center', justifyContent: 'center',
          color: '#fff', textAlign: 'center',
        }}>
          <div style={{
            fontSize: 11, fontWeight: 900, letterSpacing: '0.35em',
            textTransform: 'uppercase',
            color: theme.accent,
            opacity: 0.8,
          }}>{label}</div>
          <div style={{
            marginTop: 12, fontSize: 56, fontWeight: 300,
            letterSpacing: '-0.03em',
            fontVariantNumeric: 'tabular-nums',
            color: '#fff',
            opacity: 0.95,
          }}>
            {Math.ceil(
              label === 'Breathe in' ? breath.inhale * (1 - ratio) :
              label === 'Hold' ? breath.hold :
              breath.exhale * (1 - ratio)
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Phrase cycler (crossfades on beat) ───────────────────────
function PhraseCycler({ meditation, playing, mob }) {
  const [idx, setIdx] = useMS(0);
  const { phrases, breath } = meditation;
  const total = breath.inhale + breath.hold + breath.exhale;
  const timer = useMR();

  useME(() => {
    setIdx(0);
    if (!playing) return;
    timer.current = setInterval(() => {
      setIdx(i => (i + 1) % phrases.length);
    }, total * 1000);
    return () => clearInterval(timer.current);
  }, [meditation.id, playing]);

  return (
    <div style={{
      height: mob ? 60 : 80, position: 'relative',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      {phrases.map((p, i) => (
        <div key={i} style={{
          position: 'absolute', textAlign: 'center',
          fontSize: mob ? 18 : 24, fontWeight: 500, lineHeight: 1.35,
          letterSpacing: '-0.01em', color: 'rgba(255,255,255,0.9)',
          maxWidth: mob ? 320 : 520, padding: '0 20px',
          opacity: idx === i ? 1 : 0,
          transform: `translateY(${idx === i ? 0 : 8}px)`,
          transition: 'opacity 1200ms ease, transform 1200ms ease',
          pointerEvents: 'none',
        }}>"{p}"</div>
      ))}
    </div>
  );
}

// ── Waveform progress ────────────────────────────────────────
function Waveform({ meditation, playing }) {
  const { theme, breath } = meditation;
  const bars = 48;
  const total = breath.inhale + breath.hold + breath.exhale;
  const [t, setT] = useMS(0);
  const frame = useMR();
  const start = useMR(performance.now());

  useME(() => {
    if (!playing) return;
    const loop = (now) => {
      setT((now - start.current) / 1000);
      frame.current = requestAnimationFrame(loop);
    };
    start.current = performance.now();
    frame.current = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(frame.current);
  }, [playing, meditation.id]);

  return (
    <div style={{
      display: 'flex', gap: 4, alignItems: 'center',
      justifyContent: 'center', height: 44, width: '100%',
    }}>
      {Array.from({ length: bars }).map((_, i) => {
        // Pseudo waveform: combine a slow sine (breath) and faster noise
        const breathPhase = (t / total) * Math.PI * 2;
        const barPhase = (i / bars) * Math.PI * 4;
        const noise = Math.sin(i * 2.718 + i * 0.3) * 0.5 + 0.5;
        const h = 6 + (Math.sin(breathPhase + barPhase) * 0.5 + 0.5) * 22 * noise + noise * 8;
        const active = (t / total * bars) % bars > i
          && (t / total * bars) % bars < i + bars * 0.3;
        return (
          <div key={i} style={{
            width: 3, height: h, borderRadius: 2,
            background: active ? theme.accent : 'rgba(255,255,255,0.25)',
            transition: 'background 200ms',
          }}/>
        );
      })}
    </div>
  );
}

// ── Main Meditations section ─────────────────────────────────
function Meditations() {
  const [selected, setSelected] = useMS(0);
  const [playing, setPlaying] = useMS(true);
  const [elapsed, setElapsed] = useMS(0);
  const med = MEDITATIONS[selected];
  const w = useWindowWidth();
  const mob = w < 768;

  useME(() => {
    setElapsed(0);
    if (!playing) return;
    const start = performance.now();
    const iv = setInterval(() => {
      setElapsed(Math.floor((performance.now() - start) / 1000));
    }, 500);
    return () => clearInterval(iv);
  }, [selected, playing]);

  const fmt = (s) => `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;

  return (
    <section id="meditations" style={{
      background: med.theme.bg,
      color: '#fff',
      padding: mob ? '80px 20px' : '140px 40px',
      position: 'relative', overflow: 'hidden',
      transition: 'background 1200ms ease',
    }}>
      <style>{`
        @keyframes medPulse {
          0%   { transform: scale(0.7); opacity: 0; }
          20%  { opacity: 0.5; }
          100% { transform: scale(2.6); opacity: 0; }
        }
      `}</style>

      {/* Soft vignette top/bottom to transition with neighbors */}
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0, height: 80,
        background: `linear-gradient(to bottom, ${med.theme.bg}, transparent)`,
        pointerEvents: 'none', zIndex: 2,
      }}/>

      {/* Header */}
      <div style={{
        maxWidth: 1240, margin: mob ? '0 auto 40px' : '0 auto 64px',
        display: 'flex', justifyContent: 'space-between',
        alignItems: 'flex-end', gap: 40, flexWrap: 'wrap',
        position: 'relative', zIndex: 3,
      }}>
        <div>
          <div style={{
            fontWeight: 900, fontSize: 11, letterSpacing: '0.3em',
            textTransform: 'uppercase', color: med.theme.accent,
            opacity: 0.75,
          }}>Meditations · a library for the hard moments</div>
          <h2 style={{
            marginTop: 16, fontSize: mob ? 34 : 56, fontWeight: 700,
            letterSpacing: '-0.03em', lineHeight: 1.05,
            color: '#fff', maxWidth: 720, textWrap: 'balance',
          }}>
            A practice that{' '}
            <span style={{ color: 'rgba(255,255,255,0.5)' }}>
              breathes with you.
            </span>
          </h2>
        </div>
        {!mob && (
          <p style={{
            fontSize: 17, lineHeight: 1.55, color: 'rgba(255,255,255,0.6)',
            maxWidth: 360, margin: 0,
          }}>
            Short, kind, specific. Not generic mindfulness — each track is built for a particular moment in the sober day.
          </p>
        )}
        {mob && (
          <p style={{ fontSize: 15, lineHeight: 1.55, color: 'rgba(255,255,255,0.6)', margin: '12px 0 0' }}>
            Short, kind, specific. Built for a particular moment in the sober day.
          </p>
        )}
      </div>

      {/* Stage */}
      <div style={{
        maxWidth: 1240, margin: '0 auto',
        display: 'grid',
        gridTemplateColumns: mob ? '1fr' : '1fr 380px',
        gap: mob ? 40 : 60, alignItems: 'center',
        position: 'relative', zIndex: 3,
      }}>
        {/* Orb + phrase + waveform */}
        <div style={{
          display: 'flex', flexDirection: 'column',
          alignItems: 'center', gap: mob ? 24 : 40,
        }}>
          {/* Orb: clip to a smaller container on mobile */}
          <div style={{
            width: '100%', height: mob ? 300 : 520,
            overflow: 'hidden',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <div style={{ transform: mob ? 'scale(0.58)' : 'scale(1)', flexShrink: 0 }}>
              <BreathingOrb meditation={med} playing={playing}/>
            </div>
          </div>

          <PhraseCycler meditation={med} playing={playing} mob={mob}/>

          {/* Player chrome */}
          <div style={{
            width: '100%', maxWidth: 560,
            background: 'rgba(255,255,255,0.04)',
            border: '1px solid rgba(255,255,255,0.08)',
            borderRadius: 32, padding: '20px 24px',
            display: 'flex', flexDirection: 'column', gap: 14,
            backdropFilter: 'blur(10px)',
            WebkitBackdropFilter: 'blur(10px)',
          }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 16,
            }}>
              <button onClick={() => setPlaying(p => !p)} style={{
                width: 48, height: 48, borderRadius: '50%',
                background: med.theme.accent, color: med.theme.bg,
                border: 'none', cursor: 'pointer',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexShrink: 0,
              }}>
                {playing ? (
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                    <rect x="6" y="4" width="4" height="16" rx="1"/>
                    <rect x="14" y="4" width="4" height="16" rx="1"/>
                  </svg>
                ) : (
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M6 4l14 8-14 8z"/>
                  </svg>
                )}
              </button>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 14, fontWeight: 700, color: '#fff',
                }}>{med.title}</div>
                <div style={{
                  fontSize: 12, color: 'rgba(255,255,255,0.55)',
                  fontVariantNumeric: 'tabular-nums', marginTop: 2,
                }}>{fmt(elapsed)} · {med.duration}</div>
              </div>
            </div>
            <Waveform meditation={med} playing={playing}/>
          </div>
        </div>

        {/* Library list */}
        <div style={{
          display: 'flex', flexDirection: 'column', gap: 8,
        }}>
          <div style={{
            fontWeight: 900, fontSize: 11, letterSpacing: '0.3em',
            textTransform: 'uppercase', color: 'rgba(255,255,255,0.4)',
            paddingLeft: 12, marginBottom: 8,
          }}>The library · {MEDITATIONS.length} tracks</div>
          {MEDITATIONS.map((m, i) => {
            const active = i === selected;
            return (
              <button key={m.id} onClick={() => setSelected(i)}
                style={{
                  textAlign: 'left', border: 'none', cursor: 'pointer',
                  fontFamily: 'inherit',
                  background: active ? 'rgba(255,255,255,0.08)' : 'transparent',
                  borderLeft: `3px solid ${active ? m.theme.accent : 'transparent'}`,
                  padding: '16px 18px 16px 15px', borderRadius: 12,
                  display: 'flex', alignItems: 'center', gap: 14,
                  transition: 'background 250ms',
                }}>
                {/* mini breathing dot */}
                <div style={{
                  width: 10, height: 10, borderRadius: '50%',
                  background: m.theme.accent,
                  opacity: active ? 1 : 0.4,
                  animation: active ? 'medDotPulse 3s ease-in-out infinite' : 'none',
                  flexShrink: 0,
                }}/>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{
                    fontSize: 10, fontWeight: 900, letterSpacing: '0.2em',
                    textTransform: 'uppercase',
                    color: active ? m.theme.accent : 'rgba(255,255,255,0.4)',
                  }}>{m.eyebrow}</div>
                  <div style={{
                    marginTop: 4,
                    fontSize: 17, fontWeight: 700,
                    color: active ? '#fff' : 'rgba(255,255,255,0.7)',
                    letterSpacing: '-0.01em',
                  }}>{m.title}</div>
                </div>
                <div style={{
                  fontSize: 12, fontWeight: 600,
                  color: 'rgba(255,255,255,0.45)',
                  fontVariantNumeric: 'tabular-nums',
                }}>{m.duration}</div>
              </button>
            );
          })}
          <style>{`
            @keyframes medDotPulse {
              0%, 100% { transform: scale(1); opacity: 1; }
              50% { transform: scale(1.6); opacity: 0.5; }
            }
          `}</style>
        </div>
      </div>

      {/* Bottom vignette */}
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, height: 80,
        background: `linear-gradient(to top, ${med.theme.bg}, transparent)`,
        pointerEvents: 'none', zIndex: 2,
      }}/>
    </section>
  );
}

window.LandingMeditations = Meditations;
