/* global React, AuroraMark */
// Aurora PRIMITIVES + design tokens — the shared building blocks used by the
// canonical screens (aurora-unified-screens.jsx) in BOTH the Unified router and
// the Combined canvas. No screens live here anymore; this is just the kit.

const { useState, useRef, useEffect } = React;

const C_BG     = 'linear-gradient(180deg, #1a1f3a 0%, #0d0f1f 100%)';
const C_FIRE   = 'linear-gradient(180deg, #1a1f3a 0%, #4a3147 42%, #c25d75 100%)';
// Warm morning — driven by a CSS var so the colorway can be tuned globally.
const C_MORN   = 'var(--morn)';
const C_CORAL  = '#ff7a59';
const C_INDIGO = '#6b7be0';
const C_GREEN  = '#5fdba7';
const C_GOLD   = '#f5c46b';
const C_TEXT   = '#e8e6f0';
const C_DIM    = 'rgba(232,230,240,0.55)';
const C_MUTED  = 'rgba(232,230,240,0.3)';
const C_CARD   = 'rgba(255,255,255,0.05)';

// Dark glass — for Plan & Memory (V5 layout)
const CGlass = ({ children, style }) => (
  <div style={{
    background: 'rgba(255,255,255,0.06)',
    backdropFilter: 'blur(24px)', WebkitBackdropFilter: 'blur(24px)',
    borderRadius: 22, border: '1px solid rgba(255,255,255,0.12)',
    boxShadow: '0 8px 32px rgba(8,10,24,0.35)', ...style,
  }}>{children}</div>
);

// day-summary helper (shared)
const DAY_LETTERS = ['M','T','W','T','F','S','S'];
const daySummary = (days = []) => {
  const n = days.filter(Boolean).length;
  if (n === 0) return 'Once';
  if (n === 7) return 'Every day';
  if (days[0]&&days[1]&&days[2]&&days[3]&&days[4]&&!days[5]&&!days[6]) return 'Weekdays';
  if (!days[0]&&!days[1]&&!days[2]&&!days[3]&&!days[4]&&days[5]&&days[6]) return 'Weekends';
  return days.map((d,i) => d ? DAY_LETTERS[i] : null).filter(Boolean).join(' ');
};

// ─── 24h alarm dial — DRAGGABLE. The selected alarm shows a bell grip you drag to
//     set its time (snapped to 5 min); other enabled alarms show as faint dots on the
//     24h ring. Center shows the selected alarm's time + which days it repeats.
//     Controlled: alarms = [{h,m,enabled,days}]; onChange(selectedIndex, {h,m}).
const CDial = ({ size = 206, alarms = [], selectedIndex = 0, onChange }) => {
  const svgRef = useRef(null);
  const [drag, setDrag] = useState(false);
  const cx = size/2, cy = size/2;
  const rOuter = size * 0.47, rInner = size * 0.35;
  const rMid = (rOuter + rInner) / 2;
  const band = rOuter - rInner;
  const polar = (r, deg) => { const rad = deg*Math.PI/180; return [cx + r*Math.cos(rad), cy + r*Math.sin(rad)]; };
  const toDeg = (t) => ((t.h + t.m/60) / 24) * 360 - 90;
  const sel = alarms[selectedIndex] || { h: 6, m: 0, days: [] };
  const [sx, sy] = polar(rMid, toDeg(sel));
  const timeLabel = `${String(sel.h).padStart(2,'0')}:${String(sel.m).padStart(2,'0')}`;

  useEffect(() => {
    if (!drag) return;
    const onMove = (e) => {
      if (e.cancelable) e.preventDefault();
      const pt = e.touches ? e.touches[0] : e;
      const rect = svgRef.current.getBoundingClientRect();
      const ccx = rect.left + rect.width/2, ccy = rect.top + rect.height/2;
      const deg = Math.atan2(pt.clientY - ccy, pt.clientX - ccx) * 180/Math.PI;
      let h = ((deg + 90)/360) * 24; h = (h % 24 + 24) % 24;
      let mins = Math.round(h*60/5)*5 % 1440;     // snap to 5 min
      onChange && onChange(selectedIndex, { h: Math.floor(mins/60)%24, m: mins%60 });
    };
    const onUp = () => setDrag(false);
    window.addEventListener('pointermove', onMove);
    window.addEventListener('pointerup', onUp);
    window.addEventListener('touchmove', onMove, { passive: false });
    window.addEventListener('touchend', onUp);
    return () => {
      window.removeEventListener('pointermove', onMove);
      window.removeEventListener('pointerup', onUp);
      window.removeEventListener('touchmove', onMove);
      window.removeEventListener('touchend', onUp);
    };
  }, [drag, onChange, selectedIndex]);

  const hr = band * 0.78; // handle radius
  const grab = (e) => { e.preventDefault(); e.stopPropagation(); setDrag(true); };

  return (
    <svg ref={svgRef} width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ touchAction: 'none', userSelect: 'none', overflow: 'visible' }}>
      <defs>
        <linearGradient id="carc" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor={C_INDIGO}/>
          <stop offset="100%" stopColor={C_CORAL}/>
        </linearGradient>
      </defs>
      {/* track */}
      <circle cx={cx} cy={cy} r={rMid} fill="none" stroke="rgba(255,255,255,0.07)" strokeWidth={band}/>
      {/* tick marks */}
      {Array.from({length: 96}).map((_, i) => {
        const deg = (i/96)*360 - 90;
        const r1 = rInner - 5, r2 = i % 4 === 0 ? r1 - 8 : r1 - 5;
        const [px1,py1] = polar(r1, deg), [px2,py2] = polar(r2, deg);
        return <line key={i} x1={px1} y1={py1} x2={px2} y2={py2} stroke="rgba(255,255,255,0.18)" strokeWidth="1"/>;
      })}
      {[0,6,12,18].map(h => { const [x,y] = polar(rInner-22, (h/24)*360-90);
        return <text key={h} x={x} y={y} textAnchor="middle" dominantBaseline="central" fontFamily="Inter Tight" fontSize="11" fontWeight="500" fill="rgba(232,230,240,0.45)">{h}</text>; })}
      {/* faint dots for other enabled alarms */}
      {alarms.map((a, i) => {
        if (i === selectedIndex || !a.enabled) return null;
        const [dx, dy] = polar(rMid, toDeg(a));
        return <circle key={i} cx={dx} cy={dy} r={band*0.26} fill={C_CORAL} opacity="0.45"/>;
      })}
      {/* draggable bell grip for the selected alarm */}
      <g style={{ cursor: drag ? 'grabbing' : 'grab', touchAction: 'none' }} onPointerDown={grab} onTouchStart={grab}>
        <circle cx={sx} cy={sy} r={hr + 10} fill="transparent"/>
        <circle cx={sx} cy={sy} r={hr} fill="url(#carc)"
          style={{ filter: 'drop-shadow(0 2px 5px rgba(0,0,0,0.4))', transform: drag ? 'scale(1.1)' : 'scale(1)', transformBox: 'fill-box', transformOrigin: 'center', transition: 'transform 0.12s' }}/>
        <g transform={`translate(${sx}, ${sy})`}>
          <path d="M6 0 a4.2 4.2 0 0 0 -4.2 4.2 v3.4 l-1.4 2 h11.2 l-1.4 -2 v-3.4 A4.2 4.2 0 0 0 6 0z M4 11.5 a2 2 0 0 0 4 0z" fill="#fff" transform="translate(-6,-5.5)"/>
        </g>
      </g>
    </svg>
  );
};

// ─── Segmented control ───
function CSeg({ options, value, onChange }) {
  return (
    <div style={{ display: 'flex', gap: 4, background: 'rgba(255,255,255,0.05)', borderRadius: 12, padding: 4, border: '1px solid rgba(255,255,255,0.06)' }}>
      {options.map(o => {
        const on = o === value;
        return (
          <button key={o} onClick={() => onChange(o)} style={{
            flex: 1, padding: '9px 0', borderRadius: 9, border: 'none', cursor: 'pointer',
            fontFamily: 'inherit', fontSize: 13, fontWeight: 600,
            background: on ? C_CORAL : 'transparent', color: on ? '#fff' : C_DIM,
            transition: 'background 0.15s',
          }}>{o}</button>
        );
      })}
    </div>
  );
}

// ─── Aurora orb (shared by both firing screens) ───
//   speaking → beams: ripple rings + glow + a pulsing scale.
//   settled  → a single calm breathing loop. The only motion is that one transition.
function COrb({ size = 80, speaking, settledLabel = 'AURORA · LISTENING', settledDot = C_GREEN, label = true }) {
  const ringSize = size * 1.03;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      <div style={{ position: 'relative', width: size * 1.5, height: size * 1.3, display: 'grid', placeItems: 'center' }}>
        {speaking && [0, 1, 2].map(i => (
          <div key={i} style={{ position: 'absolute', width: ringSize, height: ringSize, borderRadius: '50%', border: `1.5px solid ${C_CORAL}`, animation: `ripple 1.9s ease-out ${i * 0.6}s infinite` }}/>
        ))}
        <div style={{
          width: size, height: size, borderRadius: '50%',
          background: `radial-gradient(circle at 35% 35%, ${C_CORAL}cc 0%, ${C_CORAL}55 50%, transparent 75%)`,
          display: 'grid', placeItems: 'center',
          boxShadow: speaking ? `0 0 ${Math.round(size * 0.33)}px ${C_CORAL}99` : 'none',
          transition: 'box-shadow 0.5s',
          animation: speaking ? 'beam 1.3s ease-in-out infinite' : 'breathe 3.4s ease-in-out infinite',
        }}>
          <AuroraMark size={Math.round(size * 0.5)} tone="ink"/>
        </div>
      </div>
      {label && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 8 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: speaking ? C_CORAL : settledDot, boxShadow: `0 0 6px ${speaking ? C_CORAL : settledDot}`, transition: 'background 0.4s' }}/>
          <span style={{ fontSize: 9, letterSpacing: '0.14em', opacity: 0.85, whiteSpace: 'nowrap' }}>{speaking ? 'AURORA · SPEAKING' : settledLabel}</span>
        </div>
      )}
    </div>
  );
}

// ─── Hold-to-confirm button ───
function CHoldButton({ label, holdingLabel, doneLabel, duration = 1400, primary, small, icon, onDone }) {
  const [progress, setProgress] = useState(0);
  const [state, setState] = useState('idle'); // idle | holding | done
  const rafRef = useRef(null);
  const startRef = useRef(0);

  const frame = () => {
    const p = Math.min(1, (performance.now() - startRef.current) / duration);
    setProgress(p);
    if (p < 1) rafRef.current = requestAnimationFrame(frame);
    else { setState('done'); if (onDone) onDone(); }
  };
  const begin = (e) => {
    e.preventDefault();
    if (state === 'done') return;
    setState('holding');
    startRef.current = performance.now();
    rafRef.current = requestAnimationFrame(frame);
  };
  const end = () => {
    if (state === 'done') return;
    cancelAnimationFrame(rafRef.current);
    setState('idle'); setProgress(0);
  };

  const done = state === 'done';
  const text = done ? doneLabel : state === 'holding' ? holdingLabel : label;
  const fill = primary ? C_CORAL : 'rgba(255,255,255,0.28)';
  const baseBg = primary ? 'rgba(255,255,255,0.12)' : 'transparent';

  return (
    <div
      onMouseDown={begin} onMouseUp={end} onMouseLeave={end}
      onTouchStart={begin} onTouchEnd={end}
      style={{
        position: 'relative', overflow: 'hidden', userSelect: 'none', cursor: 'pointer',
        height: small ? 42 : primary ? 60 : 50, borderRadius: 999,
        background: done ? C_CORAL : baseBg,
        border: primary ? 'none' : `1px solid rgba(255,255,255,${small ? 0.16 : 0.25})`,
        display: 'grid', placeItems: 'center', opacity: small && !done ? 0.85 : 1,
        transition: 'background 0.2s',
      }}
    >
      <div style={{
        position: 'absolute', left: 0, top: 0, bottom: 0,
        width: `${progress * 100}%`, background: fill,
        transition: state === 'idle' ? 'width 0.25s ease' : 'none',
      }}/>
      <span style={{
        position: 'relative', zIndex: 1,
        fontSize: small ? 12 : primary ? 16 : 14, fontWeight: 600, color: '#fff',
        fontFamily: 'inherit', letterSpacing: '0.01em',
        display: 'flex', alignItems: 'center', gap: 8, whiteSpace: 'nowrap',
      }}>
        {!done && icon}
        {done && <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/></svg>}
        {text}
      </span>
    </div>
  );
}

Object.assign(window, {
  CDial, COrb, CHoldButton, CSeg, CGlass,
  AURORA_TOKENS: { C_BG, C_FIRE, C_MORN, C_CORAL, C_INDIGO, C_GREEN, C_GOLD, C_TEXT, C_DIM, C_MUTED, C_CARD },
});
