// sphere.jsx — Progress-ring system: the new visual identity of Eme.
// The luminous ring replaces every orb/sphere. A fixed top anchor never moves;
// a single neon line grows clockwise from it, emitting a soft atmospheric halo.
const { useMemo: useMemoR } = React;

// ── ProgressRing ──────────────────────────────────────────
// progress 0..1. The drawn arc always begins at the fixed 12 o'clock anchor and
// extends clockwise; only the moving end advances. `running` enables the smooth,
// continuous (per-second → 1s linear) fill so progression never visibly steps.
// GlassSphere — the luminous Liquid Glass orb inside the timer ring: a dark
// translucent body, a bright magenta/cyan rim, an iridescent edge ring, a specular
// sheen, and flowing liquid light. Waves are faint at rest and luminous while running.
function GlassSphere({ size = 280, running = false, colors = ['#C24DFF', '#29C5FF'], anim = 1 }) {
  const gid = React.useMemo(() => 'ls' + Math.random().toString(36).slice(2, 7), []);
  // A seamless, tiling wave path: two identical periods (width 0..200, period 100)
  // so a -50% horizontal translate loops perfectly. `a` = baseline, `amp` = height.
  const wave = (a, amp) =>
    `M0,${a} C12.5,${(a - amp).toFixed(2)} 37.5,${(a - amp).toFixed(2)} 50,${a} ` +
    `C62.5,${(a + amp).toFixed(2)} 87.5,${(a + amp).toFixed(2)} 100,${a} ` +
    `C112.5,${(a - amp).toFixed(2)} 137.5,${(a - amp).toFixed(2)} 150,${a} ` +
    `C162.5,${(a + amp).toFixed(2)} 187.5,${(a + amp).toFixed(2)} 200,${a} L200,101 L0,101 Z`;
  return (
    <div className="ls-orb" style={{ width: size, height: size, '--wl': colors[0], '--wr': colors[1], '--anim': anim }} aria-hidden="true">
      <div className="ls-glow" />
      <div className="ls-body">
        <svg className={'ls-waves' + (running ? ' is-on' : '')} viewBox="0 0 100 100" preserveAspectRatio="none">
          <defs>
            <clipPath id={`c-${gid}`}><circle cx="50" cy="50" r="50" /></clipPath>
            <linearGradient id={`w-${gid}`} x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="#ffffff" stopOpacity="0" />
              <stop offset="12%" stopColor="#ffffff" stopOpacity=".55" />
              <stop offset="34%" stopColor={colors[0]} stopOpacity=".9" />
              <stop offset="72%" stopColor={colors[1]} stopOpacity=".5" />
              <stop offset="100%" stopColor={colors[1]} stopOpacity=".18" />
            </linearGradient>
            <filter id={`b-${gid}`} x="-20%" y="-20%" width="140%" height="140%"><feGaussianBlur stdDeviation="0.5" /></filter>
          </defs>
          <g clipPath={`url(#c-${gid})`} filter={`url(#b-${gid})`}>
            <g className="lsw lsw1"><path d={wave(60, 4.2)} fill={`url(#w-${gid})`} opacity="0.45" /></g>
            <g className="lsw lsw2"><path d={wave(64, 5.4)} fill={`url(#w-${gid})`} opacity="0.6" /></g>
            <g className="lsw lsw3"><path d={wave(68, 6.6)} fill={`url(#w-${gid})`} opacity="0.92" /></g>
          </g>
        </svg>
      </div>
      <div className="orb-rim" />
      <div className="orb-ringline" />
      <div className="ls-sheen" />
    </div>
  );
}

function ProgressRing({ progress = 0, size = 290, colors = ['#B57BFF', '#56D8FF'], running = false, rate = 0, complete = false, anim = 1, topGlow = false, topSphere = false, noAura = false, glass = false, glassColors = null, trackColor = 'rgba(255,255,255,.045)', trackWidth = 0.6, glow = false, endMinutes = null, children }) {
  const target = Math.max(0, Math.min(1, progress));
  // Frame-continuous fill: while running, a rAF loop advances the drawn value at
  // a constant velocity (`rate` = progress/sec, synced to remaining time) so the
  // ring extends fluidly every frame — never in per-second steps. The authoritative
  // discrete `progress` re-anchors the value on each tick so it can never drift.
  const [shown, setShown] = React.useState(target);
  const shownRef = React.useRef(target);
  React.useEffect(() => { shownRef.current = target; setShown(target); }, [target]);
  React.useEffect(() => {
    if (!running || rate <= 0) return;
    let raf, prev = performance.now();
    const loop = (now) => {
      const dt = (now - prev) / 1000; prev = now;
      const next = Math.min(1, shownRef.current + rate * dt);
      shownRef.current = next; setShown(next);
      if (next < 1) raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [running, rate, target]);
  const p = running ? Math.max(0, Math.min(1, shown)) : target;
  const R = 41, C = 2 * Math.PI * R, cx = 50, cy = 50;
  const dash = C * (1 - p);
  const gid = useMemoR(() => 'r' + Math.random().toString(36).slice(2, 8), []);
  const c0 = colors[0], c1 = colors[1] || colors[0];
  const showEnd = p > 0.0015;
  // rAF supplies continuous values while running, so no CSS easing is layered on top.
  const trans = running ? 'none' : 'stroke-dashoffset .45s ease';
  const rotTrans = running ? 'none' : 'transform .45s ease';

  return (
    <div className={'ring-stage' + (complete ? ' ring-complete' : '')}
         style={{ width: size, height: size, position: 'relative', '--anim': anim }}>
      {/* atmospheric halo — tight + luminous, hugs the trace (not a fog cloud) */}
      {!noAura && <div className="ring-aura" style={{ opacity: 0.04 + p * 0.1,
        background: `radial-gradient(closest-side, ${c0}33, ${c1}0f 54%, transparent 70%)` }} />}
      {/* completion: a single soft pulse spreading outward */}
      {complete && <div className="ring-pulse" style={{ borderColor: c0 }} />}

      {/* Liquid Glass orb — sits just inside the ring track, behind the timer */}
      {glass && <GlassSphere size={size * 0.84} running={running} colors={glassColors || colors} anim={anim} />}

      <svg viewBox="0 0 100 100" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', overflow: 'visible' }}>
        <defs>
          {/* violet → blue, following the clockwise growth: violet at the 12 o'clock
             origin / right side, flowing into blue across the arc. Axis reversed from
             the prior vertical gradient so the flow direction is clearly inverted. */}
          <linearGradient id={`g-${gid}`} x1="1" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={c0} />
            <stop offset="42%" stopColor={c0} />
            <stop offset="58%" stopColor={c1} />
            <stop offset="100%" stopColor={c1} />
          </linearGradient>
          {/* edgeless luminous point for the moving tip — bright core fading to nothing */}
          <radialGradient id={`tipg-${gid}`} cx="50%" cy="50%" r="50%">
            <stop offset="0%" stopColor="#ffffff" stopOpacity="1" />
            <stop offset="30%" stopColor="#ffffff" stopOpacity="0.9" />
            <stop offset="62%" stopColor={c1} stopOpacity="0.55" />
            <stop offset="100%" stopColor={c1} stopOpacity="0" />
          </radialGradient>
          <filter id={`bloom-${gid}`} x="-80%" y="-80%" width="260%" height="260%">
            <feGaussianBlur stdDeviation="0.55" />
          </filter>
          <filter id={`soft-${gid}`} x="-70%" y="-70%" width="240%" height="240%">
            <feGaussianBlur stdDeviation="0.4" />
          </filter>
          <filter id={`tip-${gid}`} x="-220%" y="-220%" width="540%" height="540%">
            <feGaussianBlur stdDeviation="0.8" />
          </filter>
          <filter id={`vglow-${gid}`} x="-120%" y="-120%" width="340%" height="340%">
            <feGaussianBlur stdDeviation="2.4" />
          </filter>
        </defs>

        {/* violet bloom radiating from the ring stroke (minimal-neon look) */}
        {glow && (
          <g>
            <circle cx={cx} cy={cy} r={R} fill="none" stroke={c0} strokeWidth="2.6" opacity="0.55" filter={`url(#vglow-${gid})`} />
            <circle cx={cx} cy={cy} r={R} fill="none" stroke={c0} strokeWidth="1.1" opacity="0.5" filter={`url(#bloom-${gid})`} />
          </g>
        )}

        {/* inactive track — the elegant circle outline */}
        <circle cx={cx} cy={cy} r={R} fill="none" stroke={trackColor} strokeWidth={trackWidth} />

        {/* subtle halo — faint + secondary, so the line itself stays the focus */}
        <circle cx={cx} cy={cy} r={R} fill="none" stroke={`url(#g-${gid})`} strokeWidth="2.1" strokeLinecap="butt"
          strokeDasharray={C} strokeDashoffset={dash} transform={`rotate(-90 ${cx} ${cy})`}
          filter={`url(#bloom-${gid})`} opacity={p > 0 ? 0.32 : 0} style={{ transition: trans }} />

        {/* vivid gradient line */}
        <circle cx={cx} cy={cy} r={R} fill="none" stroke={`url(#g-${gid})`} strokeWidth="1.25" strokeLinecap="butt"
          strokeDasharray={C} strokeDashoffset={dash} transform={`rotate(-90 ${cx} ${cy})`}
          filter={`url(#soft-${gid})`} style={{ transition: trans }} />

        {/* crisp bright core — the thin, luminous line that ends in a clean flat edge */}
        <circle cx={cx} cy={cy} r={R} fill="none" stroke="#fff" strokeWidth="0.7" strokeLinecap="butt"
          strokeDasharray={C} strokeDashoffset={dash} transform={`rotate(-90 ${cx} ${cy})`}
          opacity={p > 0 ? 1 : 0} style={{ transition: trans }} />

        {/* top circle at 12 o'clock — a glowing point during the session;
            once the session ends the glow is replaced by the minutes completed */}
        {(topGlow || endMinutes != null) && (
          endMinutes != null ? (
            <g>
              <circle cx={cx} cy={cy - R} r="8.6" fill={c0} opacity="0.3" filter={`url(#bloom-${gid})`} />
              <circle cx={cx} cy={cy - R} r="7.2" fill="#0a0913" stroke={c0} strokeWidth="0.9" />
              <text x={cx} y={cy - R} textAnchor="middle" dominantBaseline="central"
                fontSize="5.3" fontWeight="600" fill="#ffffff"
                style={{ fontFamily: "'Sora', system-ui, sans-serif" }}>{endMinutes}</text>
            </g>
          ) : (
            <g>
              {/* a softer, smaller violet glow around a pure-white core */}
              <circle cx={cx} cy={cy - R} r="5.1" fill={c0} opacity="0.38" filter={`url(#vglow-${gid})`} />
              <circle cx={cx} cy={cy - R} r="3.2" fill="#ffffff" opacity="0.22" filter={`url(#tip-${gid})`} />
              <circle cx={cx} cy={cy - R} r="2.1" fill="#ffffff" />
            </g>
          )
        )}

        {/* clean white origin-sphere (emblem only) — the point the ring grows from; no purple halo */}
        {topSphere && (
          <g>
            <circle cx={cx} cy={cy - R} r="4.2" fill="#ffffff" opacity="0.09" filter={`url(#bloom-${gid})`} />
            <circle cx={cx} cy={cy - R} r="2.7" fill="#ffffff" opacity="0.18" filter={`url(#tip-${gid})`} />
            <circle cx={cx} cy={cy - R} r="2.0" fill="#ffffff" />
          </g>
        )}
      </svg>

      {children != null && <div className="ring-center">{children}</div>}
    </div>
  );
}

// ── LevelRing ─────────────────────────────────────────────
// A fully-lit decorative ring used wherever an emblem is needed (splash, onboarding,
// level-up, share, premium). Breathes gently and can hold a centred glyph.
function LevelRing({ size = 180, colors = ['#B57BFF', '#56D8FF'], breathe = true, complete = false, topSphere = false, noAura = false, children }) {
  return (
    <div className={breathe ? 'ring-breathe' : ''} style={{ width: size, height: size, position: 'relative' }}>
      <ProgressRing progress={1} size={size} colors={colors} complete={complete} topSphere={topSphere} noAura={noAura}>{children}</ProgressRing>
    </div>
  );
}

window.ProgressRing = ProgressRing;
window.LevelRing = LevelRing;
window.GlassSphere = GlassSphere;

  