// sixtyone.jsx — 61-Point Relaxation (Himalayan tradition / Swami Rama).
// Attention travels through 61 fixed points in sequence; rest at each and let it relax.
// Coordinates are in the standing BodyFigure viewBox: 300 × 660.

const SIX_HUE = '#7CC4FF'; // calm blue — the traditional "blue star" at each point
const SIX_CHIME = [261.63, 293.66, 329.63, 392.00, 440.00]; // C-pentatonic — a gentle, resolving cue
const SIX_INTRO = 'This is the sixty-one point relaxation, from the Himalayan tradition of Swami Rama. Your attention will travel through sixty-one points across the body, resting a breath at each. It calms the nervous system, deepens awareness of the body, and settles the mind for stillness. Lie down, let the breath be easy, and simply follow.';

// [x, y, label]. Sequence: brow → throat → right arm out & back → throat →
// left arm out & back → throat → chest/heart → navel → right leg → navel →
// left leg → navel → heart → throat → brow. Exactly 61 points.
const SIX_POINTS = [
  [150, 48, 'eyebrow center'],            // 1
  [150, 114, 'hollow of the throat'],     // 2
  // right arm out (viewer-right) — shoulder→elbow→wrist→fingertips
  [208, 160, 'right shoulder'],           // 3
  [240, 250, 'right elbow'],              // 4
  [252, 340, 'right wrist'],              // 5
  [270, 357, 'right thumb'],              // 6
  [264, 376, 'right index finger'],       // 7
  [256, 383, 'right middle finger'],      // 8
  [248, 382, 'right ring finger'],        // 9
  [242, 376, 'right little finger'],      // 10
  [252, 340, 'right wrist'],              // 11
  [240, 250, 'right elbow'],              // 12
  [208, 160, 'right shoulder'],           // 13
  [150, 114, 'hollow of the throat'],     // 14
  // left arm out (viewer-left)
  [92, 160, 'left shoulder'],             // 15
  [60, 250, 'left elbow'],                // 16
  [48, 340, 'left wrist'],                // 17
  [18, 357, 'left thumb'],                // 18
  [24, 376, 'left index finger'],         // 19
  [32, 383, 'left middle finger'],        // 20
  [40, 382, 'left ring finger'],          // 21
  [46, 376, 'left little finger'],        // 22
  [48, 340, 'left wrist'],                // 23
  [60, 250, 'left elbow'],                // 24
  [92, 160, 'left shoulder'],             // 25
  [150, 114, 'hollow of the throat'],     // 26
  // chest / heart
  [150, 172, 'center of the heart'],      // 27
  [184, 160, 'right side of the chest'],  // 28
  [150, 172, 'center of the heart'],      // 29
  [116, 160, 'left side of the chest'],   // 30
  [150, 172, 'center of the heart'],      // 31
  [150, 236, 'solar plexus'],             // 32
  [150, 270, 'navel center'],             // 33
  // right leg down & back
  [180, 336, 'right side of the pelvis'], // 34
  [186, 486, 'right knee'],               // 35
  [192, 584, 'right ankle'],              // 36
  [206, 614, 'right big toe'],            // 37
  [199, 618, 'right second toe'],         // 38
  [193, 620, 'right middle toe'],         // 39
  [187, 620, 'right fourth toe'],         // 40
  [181, 617, 'right little toe'],         // 41
  [192, 584, 'right ankle'],              // 42
  [186, 486, 'right knee'],               // 43
  [180, 336, 'right side of the pelvis'], // 44
  [150, 270, 'navel center'],             // 45
  // left leg down & back
  [120, 336, 'left side of the pelvis'],  // 46
  [114, 486, 'left knee'],                // 47
  [108, 584, 'left ankle'],               // 48
  [94, 614, 'left big toe'],              // 49
  [101, 618, 'left second toe'],          // 50
  [107, 620, 'left middle toe'],          // 51
  [113, 620, 'left fourth toe'],          // 52
  [119, 617, 'left little toe'],          // 53
  [108, 584, 'left ankle'],               // 54
  [114, 486, 'left knee'],                // 55
  [120, 336, 'left side of the pelvis'],  // 56
  // return up the center
  [150, 340, 'center of the pelvis'],     // 57
  [150, 270, 'navel center'],             // 58
  [150, 172, 'center of the heart'],      // 59
  [150, 114, 'hollow of the throat'],     // 60
  [150, 48,  'eyebrow center'],           // 61
];

function SixtyOneScreen({ vp, audio, onExit }) {
  const C = MT_COLORS;
  const voice = useVoice();
  const PACES = [{ s: 2.5, t: 'Gentle', sub: '~2½ min' }, { s: 4, t: 'Slow', sub: '~4 min' }, { s: 6, t: 'Deep', sub: '~6 min' }];
  const [stage, setStage] = React.useState('intro'); // intro | live | done
  const [pace, setPace] = React.useState(4);
  const [voiceOn, setVoiceOn] = React.useState(true);
  const [idx, setIdx] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const [warming, setWarming] = React.useState(false);   // intro voice playing before points begin
  const [chimeOn, setChimeOn] = React.useState(true);
  const chimeRef = React.useRef(true);
  React.useEffect(() => { chimeRef.current = chimeOn; }, [chimeOn]);

  const idxRef = React.useRef(0);
  const accRef = React.useRef(0);
  const lastRef = React.useRef(0);
  const pausedRef = React.useRef(false);
  React.useEffect(() => { pausedRef.current = paused; }, [paused]);
  const land = vp.landscape;
  const total = SIX_POINTS.length;

  function speakPoint(n) {
    if (!voiceOn || !voice.supported) return;
    const label = SIX_POINTS[n][2];
    voice.speak('Relax the ' + label + '.');
  }

  // advance through points on an interval, paced — an optional spoken
  // intro plays first (what it is + why), with soft ambient underneath
  React.useEffect(() => {
    if (stage !== 'live') return;
    audio.bell(528);
    if (audio.fade) audio.fade(0.16, 4);   // soothing background drone for the whole practice
    idxRef.current = 0; accRef.current = 0; lastRef.current = performance.now();
    setIdx(0);
    const useIntro = voiceOn && voice.supported;
    let started = !useIntro;
    if (useIntro) { setWarming(true); voice.speak(SIX_INTRO); } else { speakPoint(0); }
    const introMs = useIntro ? 31000 : 0;   // full ~27s intro, then a few seconds of silence before point 1
    const t0 = performance.now();
    const id = setInterval(() => {
      const now = performance.now();
      const dt = Math.min(500, now - lastRef.current); lastRef.current = now;
      if (pausedRef.current) { return; }
      if (!started) {
        if (now - t0 >= introMs) { started = true; setWarming(false); audio.bell(432); speakPoint(0); }
        return;
      }
      accRef.current += dt;
      if (accRef.current >= pace * 1000) {
        accRef.current = 0;
        const next = idxRef.current + 1;
        if (next >= total) {
          clearInterval(id);
          if (audio.fade) audio.fade(0, 2.5);
          audio.bell(396);
          setStage('done');
          return;
        }
        idxRef.current = next;
        setIdx(next);
        if (chimeRef.current && audio.chime) audio.chime(SIX_CHIME[next % SIX_CHIME.length], 0.045);
        speakPoint(next);
      }
    }, 60);
    return () => { clearInterval(id); if (audio.fade) audio.fade(0, 2); voice.cancel && voice.cancel(); };
    // eslint-disable-next-line
  }, [stage, pace]);

  React.useEffect(() => () => { voice.cancel && voice.cancel(); }, []); // eslint-disable-line

  // ── intro ──
  if (stage === 'intro') {
    return (
      <div style={{ position: 'fixed', inset: 0, background: `radial-gradient(120% 80% at 50% 0%, #0a1a2e 0%, ${C.bg} 60%)`, color: C.ink, overflow: 'auto' }}>
        <ParticleField count={42} />
        <SixTop onExit={onExit} label="Close" />
        <div style={{ maxWidth: 560, margin: '0 auto', padding: '74px 24px 40px', position: 'relative', display: 'flex', flexDirection: land ? 'row' : 'column', gap: land ? 40 : 0, alignItems: 'center' }}>
          <div style={{ height: land ? 'min(72vh,540px)' : 'min(38vh,320px)', aspectRatio: '300/660', flexShrink: 0 }}>
            <BodyFigure interactive={false} pose="standing" breathing dim tint={SIX_HUE}
              naam={null} markers={[]} />
          </div>
          <div>
            <MTEyebrow color={SIX_HUE}>Himalayan tradition · Swami Rama</MTEyebrow>
            <h1 style={{ font: '300 30px/1.18 var(--serif)', margin: '12px 0 12px' }}>61-Point Relaxation</h1>
            <p style={{ fontSize: 15.5, lineHeight: 1.6, color: C.inkDim, margin: '0 0 14px', textWrap: 'pretty' }}>
              Attention travels through 61 points across the body, in a fixed path — brow, throat, out each arm to the fingertips, the chest and heart, down each leg to the toes, and back.
            </p>
            <p style={{ fontSize: 15.5, lineHeight: 1.6, color: C.inkDim, margin: '0 0 22px', textWrap: 'pretty' }}>
              Rest at each point for a breath. Feel a cool point of light there, and let it soften. Lie down or sit — and simply follow.
            </p>

            <MTEyebrow>Pace</MTEyebrow>
            <div style={{ display: 'flex', gap: 8, margin: '12px 0 20px' }}>
              {PACES.map(p => {
                const on = pace === p.s;
                return (
                  <button key={p.s} onClick={() => setPace(p.s)} style={{
                    flex: 1, appearance: 'none', cursor: 'pointer', font: 'inherit', padding: '12px 0', borderRadius: 14,
                    border: `1px solid ${on ? SIX_HUE : C.inkGhost}`, background: on ? hexA(SIX_HUE, 0.1) : 'rgba(255,255,255,0.02)',
                    color: on ? C.ink : C.inkDim, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
                  }}>
                    <span style={{ fontSize: 14.5, fontWeight: 600 }}>{p.t}</span>
                    <span style={{ fontSize: 10.5, color: C.inkFaint, fontFamily: 'var(--mono)' }}>{p.sub}</span>
                  </button>
                );
              })}
            </div>

            {voice.supported && (
              <button onClick={() => setVoiceOn(v => !v)} style={{
                appearance: 'none', cursor: 'pointer', font: 'inherit', display: 'flex', alignItems: 'center', gap: 9, marginBottom: 22,
                padding: '11px 15px', borderRadius: 12, width: '100%',
                border: `1px solid ${voiceOn ? SIX_HUE : C.inkGhost}`, background: voiceOn ? hexA(SIX_HUE, 0.08) : 'rgba(255,255,255,0.02)', color: C.ink }}>
                <MTIcon name="quotes" size={17} color={voiceOn ? SIX_HUE : C.inkFaint} />
                <span style={{ flex: 1, textAlign: 'left', fontSize: 14.5 }}>Spoken guidance at each point</span>
                <span style={{ width: 40, height: 24, borderRadius: 999, position: 'relative', background: voiceOn ? SIX_HUE : 'rgba(255,255,255,0.12)' }}>
                  <span style={{ position: 'absolute', top: 3, left: voiceOn ? 19 : 3, width: 18, height: 18, borderRadius: 999, background: '#fff', transition: 'left .2s' }} />
                </span>
              </button>
            )}

            <button onClick={() => setChimeOn(v => !v)} style={{
              appearance: 'none', cursor: 'pointer', font: 'inherit', display: 'flex', alignItems: 'center', gap: 9, marginBottom: 22,
              padding: '11px 15px', borderRadius: 12, width: '100%',
              border: `1px solid ${chimeOn ? SIX_HUE : C.inkGhost}`, background: chimeOn ? hexA(SIX_HUE, 0.08) : 'rgba(255,255,255,0.02)', color: C.ink }}>
              <MTIcon name="sound" size={17} color={chimeOn ? SIX_HUE : C.inkFaint} />
              <span style={{ flex: 1, textAlign: 'left', fontSize: 14.5 }}>Soft chime at each point</span>
              <span style={{ width: 40, height: 24, borderRadius: 999, position: 'relative', background: chimeOn ? SIX_HUE : 'rgba(255,255,255,0.12)' }}>
                <span style={{ position: 'absolute', top: 3, left: chimeOn ? 19 : 3, width: 18, height: 18, borderRadius: 999, background: '#fff', transition: 'left .2s' }} />
              </span>
            </button>

            <MTButton size="lg" full onClick={() => setStage('live')} style={{ background: `linear-gradient(180deg, ${SIX_HUE}, #3E86C8)` }}>
              <MTIcon name="play" size={20} color="#04121f" /> Begin
            </MTButton>
          </div>
        </div>
      </div>
    );
  }

  // ── done ──
  if (stage === 'done') {
    return (
      <div style={{ position: 'fixed', inset: 0, background: `radial-gradient(120% 80% at 50% 0%, #0a1a2e 0%, ${C.bg} 60%)`, color: C.ink, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 26 }}>
        <ParticleField count={36} />
        <div style={{ maxWidth: 420, textAlign: 'center', position: 'relative' }}>
          <MTEyebrow color={SIX_HUE}>Complete</MTEyebrow>
          <h1 style={{ font: '300 30px/1.2 var(--serif)', margin: '12px 0 16px' }}>The whole body, at rest</h1>
          <p style={{ font: 'italic 300 18px/1.5 var(--serif)', color: C.inkDim, marginBottom: 26, textWrap: 'pretty' }}>
            Every point met, every point softened. Rest here a moment in the stillness before you rise.
          </p>
          <MTButton size="lg" full onClick={() => setStage('intro')} style={{ background: `linear-gradient(180deg, ${SIX_HUE}, #3E86C8)`, marginBottom: 12 }}>Again</MTButton>
          <button onClick={onExit} style={{ appearance: 'none', background: 'none', border: 'none', color: C.inkFaint, cursor: 'pointer', fontSize: 15, fontFamily: 'var(--sans)' }}>Return</button>
        </div>
      </div>
    );
  }

  // ── live ──
  const p = SIX_POINTS[idx];
  // trailing points (the path already traveled, faint)
  const trail = [];
  for (let k = Math.max(0, idx - 7); k < idx; k++) trail.push({ x: SIX_POINTS[k][0], y: SIX_POINTS[k][1], k });

  const figureBox = (
    <div style={{ position: 'relative', height: land ? 'min(82vh,640px)' : 'min(58vh,500px)', aspectRatio: '300/660' }}>
      <BodyFigure interactive={false} pose="standing" breathing={!paused} dim tint={SIX_HUE} markers={[]} />
      <svg viewBox="0 0 300 660" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', overflow: 'visible', pointerEvents: 'none' }}>
        {/* faint trail */}
        {trail.map(t => (
          <circle key={t.k} cx={t.x} cy={t.y} r="3" fill={hexA(SIX_HUE, 0.28)} />
        ))}
        {/* connecting line from previous to current */}
        {idx > 0 && (
          <line x1={SIX_POINTS[idx - 1][0]} y1={SIX_POINTS[idx - 1][1]} x2={p[0]} y2={p[1]}
            stroke={hexA(SIX_HUE, 0.4)} strokeWidth="1" strokeDasharray="2 3" />
        )}
        {/* current point — the blue star */}
        <circle cx={p[0]} cy={p[1]} r="22" fill={hexA(SIX_HUE, 0.18)} style={{ transformOrigin: `${p[0]}px ${p[1]}px`, animation: paused ? 'none' : 'mtGlowPulse 2.6s ease-in-out infinite' }} />
        <circle cx={p[0]} cy={p[1]} r="7" fill="#EAF7FF" style={{ filter: `drop-shadow(0 0 8px ${SIX_HUE})` }} />
        <circle cx={p[0]} cy={p[1]} r="12" fill="none" stroke={hexA(SIX_HUE, 0.7)} strokeWidth="1.2" />
      </svg>
    </div>
  );

  const sideContent = warming ? (
    <div style={{ textAlign: land ? 'left' : 'center' }}>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 13, color: SIX_HUE, letterSpacing: 1 }}>SETTLING IN</div>
      <div style={{ font: 'italic 300 22px/1.4 var(--serif)', color: C.inkDim, margin: '8px 0 0', textWrap: 'pretty' }}>
        Lie down, let the breath be easy, and simply follow.
      </div>
    </div>
  ) : (
    <div style={{ textAlign: land ? 'left' : 'center' }}>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 13, color: SIX_HUE, letterSpacing: 1 }}>POINT {idx + 1} / {total}</div>
      <div key={idx} style={{ font: '300 26px/1.3 var(--serif)', color: C.ink, margin: '8px 0 0', textWrap: 'pretty', animation: 'mtRise .5s ease-out' }}>
        Relax the <span style={{ color: SIX_HUE }}>{p[2]}</span>.
      </div>
    </div>
  );

  return (
    <div style={{ position: 'fixed', inset: 0, background: `radial-gradient(120% 80% at 50% 6%, #09192c 0%, ${C.bg} 60%)`, color: C.ink, overflow: 'hidden' }}>
      <ParticleField count={46} />
      <SixTop onExit={onExit} label="End"
        center={<div style={{ fontFamily: 'var(--mono)', fontSize: 12, letterSpacing: 1, color: C.inkDim }}>61-POINT RELAXATION</div>}
        right={voice.supported ? (
          <button onClick={() => { const v = !voiceOn; setVoiceOn(v); if (!v) voice.cancel(); }} title="Voice"
            style={{ appearance: 'none', cursor: 'pointer', background: voiceOn ? hexA(SIX_HUE, 0.14) : 'rgba(255,255,255,0.05)', border: `1px solid ${voiceOn ? hexA(SIX_HUE, 0.5) : C.inkGhost}`, borderRadius: 999, width: 38, height: 38, display: 'grid', placeItems: 'center', color: voiceOn ? SIX_HUE : C.inkFaint }}>
            <MTIcon name="quotes" size={17} />
          </button>
        ) : null} />

      {/* progress hairline */}
      <div style={{ position: 'absolute', top: 'calc(env(safe-area-inset-top, 0px) + 66px)', left: '50%', transform: 'translateX(-50%)', width: 'min(100% - 40px, 600px)', height: 2, background: C.inkGhost, borderRadius: 2, zIndex: 10 }}>
        <div style={{ width: `${((idx + 1) / total) * 100}%`, height: '100%', background: SIX_HUE, borderRadius: 2, boxShadow: `0 0 8px ${SIX_HUE}`, transition: 'width .4s ease' }} />
      </div>

      {land ? (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center' }}>
          <div style={{ flex: '1 1 46%', display: 'grid', placeItems: 'center', minWidth: 0 }}>{figureBox}</div>
          <div style={{ flex: '1 1 54%', padding: '0 6vw', maxWidth: 620 }}>{sideContent}</div>
        </div>
      ) : (
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', paddingTop: 84 }}>
          <div style={{ flex: 1, display: 'grid', placeItems: 'center', minHeight: 0, width: '100%' }}>{figureBox}</div>
          <div style={{ width: '100%', maxWidth: 540, padding: '0 24px 26px' }}>{sideContent}</div>
        </div>
      )}

      {/* pause / resume */}
      <div style={{ position: 'absolute', bottom: 30, left: 0, right: 0, display: 'flex', justifyContent: 'center', zIndex: 10 }}>
        <button onClick={() => setPaused(x => !x)} style={{ appearance: 'none', cursor: 'pointer', width: 60, height: 60, borderRadius: 999, background: 'rgba(255,255,255,0.06)', border: `1px solid ${C.inkGhost}`, display: 'grid', placeItems: 'center', backdropFilter: 'blur(8px)', color: C.ink }}>
          <MTIcon name={paused ? 'play' : 'pause'} size={24} color={C.ink} />
        </button>
      </div>
    </div>
  );
}

function SixTop({ onExit, label, center, right }) {
  const C = MT_COLORS;
  return (
    <div style={{ position: 'absolute', top: 26, left: 20, right: 20, display: 'flex', alignItems: 'center', justifyContent: 'space-between', zIndex: 20 }}>
      <button onClick={onExit} style={{ appearance: 'none', cursor: 'pointer', background: 'rgba(255,255,255,0.05)', border: `1px solid ${C.inkGhost}`, borderRadius: 999, padding: '8px 16px', color: C.inkDim, fontSize: 13, fontFamily: 'var(--mono)' }}>{label}</button>
      {center || <span />}
      {right || <span style={{ width: 60 }} />}
    </div>
  );
}

Object.assign(window, { SixtyOneScreen, SIX_POINTS, SIX_INTRO });
