// 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: 'morning-reset',
    eyebrow: 'To begin the day',
    title: 'Morning Reset',
    duration: '8:47',
    desc: 'A slow, grounded start. Sets a clear intention before the day gets noisy.',
    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.', 'Step gently into the day.'],
    breath: { inhale: 4.0, hold: 0.5, exhale: 5.0 },
  },
  {
    id: 'beat-the-craving',
    eyebrow: 'For a craving',
    title: 'Beat the Craving',
    duration: '6:54',
    desc: 'Rides the urge wave with you. Helps you sit with the pull without acting on it.',
    theme: { bg: '#0B2017', ring: 'rgba(255,255,255,0.09)', orb: '#154734', glow: '#1f6b4f', accent: '#D6B98C' },
    phrases: ['The wave is already cresting.', 'Breathe in — slow, unhurried.', 'The wave is passing. You are still here.'],
    breath: { inhale: 4.0, hold: 1.0, exhale: 6.0 },
  },
  {
    id: 'after-a-bad-day',
    eyebrow: 'After a hard day',
    title: 'After a Bad Day',
    duration: '8:23',
    desc: 'For when things went wrong. Replaces self-blame with space to begin again.',
    theme: { bg: '#2a1a1a', ring: 'rgba(255,180,150,0.09)', orb: '#4a2d2d', glow: '#8c5a4a', accent: '#E8A88C' },
    phrases: ['One day is not the whole story.', 'Softness, not punishment.', 'Tomorrow is waiting, unjudging.'],
    breath: { inhale: 4.0, hold: 2.0, exhale: 7.0 },
  },
  {
    id: 'remember-why',
    eyebrow: 'For your mindset',
    title: 'Remember Why You Started',
    duration: '7:17',
    desc: 'Reconnects you to your reason when the motivation gets quiet.',
    theme: { bg: '#1a2420', ring: 'rgba(200,255,220,0.10)', orb: '#2d4a3d', glow: '#4a8c6b', accent: '#A8E8C0' },
    phrases: ['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 },
  },
  {
    id: 'calm-before-going-out',
    eyebrow: 'Before a social event',
    title: 'Calm Before Going Out',
    duration: '7:19',
    desc: 'Two minutes to settle nerves before walking into a room full of drinkers.',
    theme: { bg: '#1a1626', ring: 'rgba(220,200,255,0.10)', orb: '#2d2550', glow: '#5a4a8c', accent: '#C9B8E8' },
    phrases: ['Nothing to prove tonight.', 'You can leave when you want.', 'Breathe. Walk in.'],
    breath: { inhale: 3.5, hold: 1.0, exhale: 5.0 },
  },
  {
    id: 'be-kinder',
    eyebrow: 'For yourself',
    title: 'Be Kinder to Yourself',
    duration: '6:59',
    desc: 'Turns down the inner critic. You deserve the same softness you\'d give a friend.',
    theme: { bg: '#261a26', ring: 'rgba(255,200,240,0.09)', orb: '#4a2d4a', glow: '#8c4a8c', accent: '#E8A8E8' },
    phrases: ['No one is watching. This is just you.', 'Breathe out — let it soften.', 'You are doing better than you think.'],
    breath: { inhale: 4.0, hold: 1.5, exhale: 6.0 },
  },
  {
    id: 'lets-unwind',
    eyebrow: 'For the evening',
    title: "Let's Unwind",
    duration: '9:29',
    desc: 'For the quiet hours when old habits used to fill the gap. Nothing has to happen.',
    theme: { bg: '#1a2e24', ring: 'rgba(230,197,155,0.10)', orb: '#2d4a3a', glow: '#3a6b52', accent: '#E8C89B' },
    phrases: ['Nothing has to happen tonight.', 'You are exactly where you should be.', 'Breathe into the ordinary.'],
    breath: { inhale: 4.0, hold: 2.0, exhale: 6.0 },
  },
];

// ── Breathing orb ────────────────────────────────────────────
function useBreathPhase(breath) {
  const [t, setT] = useMS(0);
  const frame = useMR();
  const start = useMR(performance.now());
  const total = breath.inhale + breath.hold + breath.exhale;

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

  let label, ratio;
  if (t < breath.inhale) {
    label = 'Breathe in';
    ratio = t / breath.inhale;
  } else if (t < breath.inhale + breath.hold) {
    label = 'Hold';
    ratio = 1;
  } else {
    label = 'Breathe out';
    ratio = 1 - (t - breath.inhale - breath.hold) / breath.exhale;
  }
  const eased = 0.5 - 0.5 * Math.cos(Math.PI * ratio);
  return { label, ratio: eased };
}

function BreathingOrb({ med, size = 420 }) {
  const { theme, breath } = med;
  const { ratio, label } = useBreathPhase(breath);
  const base = size * 0.28, expand = size * 0.18;
  const r = base + ratio * expand;
  const blur = size * 0.09 + ratio * size * 0.06;

  return (
    <div style={{ position: 'relative', width: size, height: size, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
      {[0,1,2,3].map(i => (
        <div key={i} style={{
          position: 'absolute',
          width: size * 0.5 + i * size * 0.14,
          height: size * 0.5 + i * size * 0.14,
          borderRadius: '50%',
          border: `1px solid ${theme.ring}`,
          opacity: 0.55 - i * 0.1,
        }}/>
      ))}
      <div style={{
        position: 'absolute', width: 200, height: 200, borderRadius: '50%',
        border: `1.5px solid ${theme.accent}`,
        opacity: 0,
        animation: `medPulse ${breath.inhale + breath.hold + breath.exhale}s ease-out infinite`,
      }}/>
      <div style={{
        position: 'absolute',
        width: r * 2 + size * 0.4, height: r * 2 + size * 0.4,
        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',
      }}/>
      <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 -20px 40px rgba(0,0,0,0.3), inset 0 10px 30px ${theme.accent}22, 0 0 60px ${theme.glow}44`,
        transition: 'width 80ms linear, height 80ms linear',
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      }}>
        <div style={{ fontSize: size * 0.024, fontWeight: 900, letterSpacing: '0.3em', textTransform: 'uppercase', color: theme.accent, opacity: 0.85 }}>{label}</div>
        <div style={{ fontSize: size * 0.11, fontWeight: 300, color: '#fff', opacity: 0.9, marginTop: 6, fontVariantNumeric: 'tabular-nums' }}>
          {Math.ceil(label === 'Breathe in' ? breath.inhale * (1 - ratio) : label === 'Hold' ? breath.hold : breath.exhale * (1 - ratio)) || 1}
        </div>
      </div>
    </div>
  );
}

// ── Phrase cycler ─────────────────────────────────────────────
function PhraseCycler({ med }) {
  const [idx, setIdx] = useMS(0);
  const { phrases, breath } = med;
  const total = breath.inhale + breath.hold + breath.exhale;
  useME(() => {
    setIdx(0);
    const iv = setInterval(() => setIdx(i => (i + 1) % phrases.length), total * 1000);
    return () => clearInterval(iv);
  }, [med.id, total]);
  return (
    <div style={{ position: 'relative', height: 52, display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%' }}>
      {phrases.map((p, i) => (
        <div key={i} style={{
          position: 'absolute', textAlign: 'center',
          fontSize: 18, fontWeight: 500, lineHeight: 1.4,
          color: 'rgba(255,255,255,0.85)', padding: '0 24px',
          opacity: idx === i ? 1 : 0,
          transform: `translateY(${idx === i ? 0 : 8}px)`,
          transition: 'opacity 1000ms ease, transform 1000ms ease',
          pointerEvents: 'none', width: '100%',
        }}>"{p}"</div>
      ))}
    </div>
  );
}

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

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

      <div style={{ maxWidth: 1240, margin: '0 auto', padding: mob ? '0 20px' : '0 60px', position: 'relative', zIndex: 2 }}>

        {/* Header */}
        <div style={{ marginBottom: mob ? 48 : 64 }}>
          <div style={{ fontWeight: 900, fontSize: 11, letterSpacing: '0.3em', textTransform: 'uppercase', color: med.theme.accent, opacity: 0.75 }}>
            Guided Meditations · {MEDITATIONS.length} tracks
          </div>
          <h2 style={{ marginTop: 16, fontSize: mob ? 32 : 52, fontWeight: 700, letterSpacing: '-0.03em', lineHeight: 1.05, color: '#fff', maxWidth: 560 }}>
            Not generic mindfulness.<br/>
            <span style={{ color: 'rgba(255,255,255,0.38)' }}>Built for the sober day.</span>
          </h2>
        </div>

        {/* Body: orb left, track list right */}
        <div style={{
          display: 'grid',
          gridTemplateColumns: mob ? '1fr' : '1fr 360px',
          gap: mob ? 48 : 64,
          alignItems: 'center',
        }}>

          {/* Left: orb + phrase */}
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 32 }}>
            <div style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden' }}>
              <div style={{ transform: mob ? 'scale(0.72)' : 'scale(1)', transformOrigin: 'center' }}>
                <BreathingOrb med={med} size={420} />
              </div>
            </div>
            <PhraseCycler med={med} />
            {/* Selected track label */}
            <div style={{ textAlign: 'center' }}>
              <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '0.25em', textTransform: 'uppercase', color: med.theme.accent, opacity: 0.7, marginBottom: 4 }}>{med.eyebrow}</div>
              <div style={{ fontSize: 20, fontWeight: 700, color: '#fff' }}>{med.title}</div>
              <div style={{ fontSize: 13, color: 'rgba(255,255,255,0.4)', marginTop: 4 }}>{med.desc}</div>
            </div>
          </div>

          {/* Right: track list */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '0.25em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.3)', marginBottom: 10, paddingLeft: 4 }}>
              Select a track
            </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 ? `${m.theme.orb}cc` : 'rgba(255,255,255,0.04)',
                  borderLeft: `3px solid ${active ? m.theme.accent : 'transparent'}`,
                  borderRadius: 14, padding: '14px 16px 14px 14px',
                  display: 'flex', alignItems: 'center', gap: 14,
                  transition: 'all 300ms ease',
                  boxShadow: active ? `0 4px 24px ${m.theme.glow}30` : 'none',
                }}>
                  {/* Dot */}
                  <div style={{
                    width: 9, height: 9, borderRadius: '50%', flexShrink: 0,
                    background: m.theme.accent,
                    opacity: active ? 1 : 0.35,
                    transform: active ? 'scale(1.3)' : 'scale(1)',
                    transition: 'all 300ms',
                  }}/>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 9, fontWeight: 900, letterSpacing: '0.2em', textTransform: 'uppercase', color: active ? m.theme.accent : 'rgba(255,255,255,0.35)', marginBottom: 3 }}>{m.eyebrow}</div>
                    <div style={{ fontSize: 15, fontWeight: 700, color: active ? '#fff' : 'rgba(255,255,255,0.65)', letterSpacing: '-0.01em' }}>{m.title}</div>
                  </div>
                  <div style={{ fontSize: 11, fontWeight: 700, color: 'rgba(255,255,255,0.35)', fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>{m.duration}</div>
                </button>
              );
            })}
          </div>
        </div>

        <p style={{ textAlign: 'center', marginTop: 60, fontSize: 13, color: 'rgba(255,255,255,0.25)', fontWeight: 500 }}>
          Available inside the app · new tracks added regularly
        </p>
      </div>
    </section>
  );
}

window.LandingMeditations = Meditations;
