// ─────────────────────────────────────────────────────────────
// Threshold Rings view — alternate Folk view, toggle from header.
//
// Concentric rings centred in the canvas (matches the Threshold mark):
//   nucleus = you (amber)
//   ring 1  = Close
//   ring 2  = Friends
//   ring 3  = Acquaintances
// Avatars are placed on their ring at a deterministic angle per handle
// so the layout is stable across renders. Tap to open ConnectSheet.
// ─────────────────────────────────────────────────────────────

const RING_DEFS = [
  { stage: 'close',        r: 60  },
  { stage: 'friend',       r: 118 },
  { stage: 'acquaintance', r: 172 },
];

// Deterministic angle for each handle — keeps layout consistent across
// re-renders without requiring a layout solver.
function angleFor(handle, idx, total) {
  // Distribute evenly around the ring with a per-stage rotation offset
  // so close/friend/acquaintance don't all line up on the same axis.
  const offsetByLen = ((handle.length * 47) % 360) * 0.005; // tiny jitter
  return (idx / total) * Math.PI * 2 - Math.PI / 2 + offsetByLen;
}

function Rings({ folk, proposals, onTapUser }) {
  const W = 390;
  const cx = W / 2;
  const cy = 230;

  // Breath: 4.2s, same as the login Threshold mark. Each ring's stagger
  // makes the rings undulate outward like a sigh.
  const BREATH = 4.2;
  const SCALE_MIN = 0.972;
  const SCALE_MAX = 1.028;

  return (
    <div style={{ position: 'relative', height: 520, overflow: 'hidden' }}>
      {/* The rings — drawn in SVG so strokes stay crisp at any DPI */}
      <svg width={W} height={520} style={{ position: 'absolute', top: 0, left: 0,
                                            pointerEvents: 'none' }}>
        {RING_DEFS.map((r, i) => {
          // Stagger each ring by a fraction of the breath cycle so they
          // ripple outward from the nucleus.
          const begin = `${i * 0.25}s`;
          const rMin = (r.r * SCALE_MIN).toFixed(2);
          const rMax = (r.r * SCALE_MAX).toFixed(2);
          const baseOpacity = [0.58, 0.42, 0.28][i];
          return (
            <circle key={r.stage} cx={cx} cy={cy} r={r.r}
              stroke={['#4F8E51', '#5E8048', '#445239'][i]}
              strokeOpacity={baseOpacity}
              strokeWidth="0.7" fill="none">
              <animate attributeName="r"
                values={`${rMin};${rMax};${rMin}`}
                dur={`${BREATH}s`} begin={begin}
                calcMode="spline"
                keySplines="0.42 0 0.58 1; 0.42 0 0.58 1"
                repeatCount="indefinite"/>
              <animate attributeName="stroke-opacity"
                values={`${(baseOpacity * 0.7).toFixed(3)};${baseOpacity};${(baseOpacity * 0.7).toFixed(3)}`}
                dur={`${BREATH}s`} begin={begin}
                calcMode="spline"
                keySplines="0.42 0 0.58 1; 0.42 0 0.58 1"
                repeatCount="indefinite"/>
            </circle>
          );
        })}

        {/* Subtle radial halo on the close ring — breathes brightest at peak */}
        <circle cx={cx} cy={cy} r="60" stroke="#D4960C" strokeOpacity="0.10"
                strokeWidth="6" fill="none">
          <animate attributeName="stroke-opacity"
            values="0.06;0.14;0.06"
            dur={`${BREATH}s`} begin="0s"
            calcMode="spline"
            keySplines="0.42 0 0.58 1; 0.42 0 0.58 1"
            repeatCount="indefinite"/>
          <animate attributeName="r"
            values={`${(60 * SCALE_MIN).toFixed(2)};${(60 * SCALE_MAX).toFixed(2)};${(60 * SCALE_MIN).toFixed(2)}`}
            dur={`${BREATH}s`} begin="0s"
            calcMode="spline"
            keySplines="0.42 0 0.58 1; 0.42 0 0.58 1"
            repeatCount="indefinite"/>
        </circle>

        {/* Ring labels */}
        {RING_DEFS.map((r, i) => (
          <text key={r.stage + 'lbl'}
            x={cx + r.r + 8} y={cy + 4}
            fill={['#76AB78', '#8A9678', '#586552'][i]}
            style={{ font: '500 9.5px var(--font-sans)',
                     letterSpacing: '0.12em', textTransform: 'uppercase' }}>
            {STAGE_META[r.stage].label.toUpperCase()} · {folk.filter(f => f.stage === r.stage).length}
          </text>
        ))}

        {/* Nucleus — you. Outer ring breathes with the close ring; the
            amber centre pulses brighter at peak. */}
        <circle cx={cx} cy={cy} r="16" fill="#1B3A1D" stroke="#2C5F2E" strokeWidth="1">
          <animate attributeName="r"
            values="15.4;16.6;15.4"
            dur={`${BREATH}s`} begin="0s"
            calcMode="spline"
            keySplines="0.42 0 0.58 1; 0.42 0 0.58 1"
            repeatCount="indefinite"/>
        </circle>
        <circle cx={cx} cy={cy} r="4.5" fill="#D4960C">
          <animate attributeName="r"
            values="4.0;5.2;4.0"
            dur={`${BREATH}s`} begin="0s"
            calcMode="spline"
            keySplines="0.42 0 0.58 1; 0.42 0 0.58 1"
            repeatCount="indefinite"/>
          <animate attributeName="opacity"
            values="0.82;1;0.82"
            dur={`${BREATH}s`} begin="0s"
            calcMode="spline"
            keySplines="0.42 0 0.58 1; 0.42 0 0.58 1"
            repeatCount="indefinite"/>
        </circle>
      </svg>

      {/* You label */}
      <div style={{
        position: 'absolute', left: cx, top: cy + 24, transform: 'translateX(-50%)',
        font: 'italic 500 12px var(--font-serif)', color: '#F4DCA0',
        pointerEvents: 'none',
      }}>you</div>

      {/* Avatars positioned over the rings */}
      {RING_DEFS.map(ring => {
        const folks = folk.filter(f => f.stage === ring.stage);
        return folks.map((u, idx) => {
          const angle = angleFor(u.handle, idx, folks.length);
          const x = cx + Math.cos(angle) * ring.r;
          const y = cy + Math.sin(angle) * ring.r;
          const size = ring.stage === 'close' ? 36 : ring.stage === 'friend' ? 32 : 28;
          const proposed = proposals[u.handle];
          return (
            <button key={u.handle}
              onClick={() => onTapUser(u.handle)}
              style={{
                position: 'absolute',
                left: x - size / 2, top: y - size / 2,
                width: size, height: size,
                padding: 0, background: 'transparent', border: 'none', cursor: 'pointer',
              }}>
              <FolkAvatar user={u} size={size} online={u.online}/>
              {proposed && (
                <span style={{
                  position: 'absolute', right: -4, top: -4,
                  width: 14, height: 14, borderRadius: '50%',
                  background: '#D4960C', color: '#0B1306',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  boxShadow: '0 0 0 2px #0B1306',
                }}>
                  <PIcons.ArrowUpRight size={9} color="#0B1306"/>
                </span>
              )}
              <span style={{
                position: 'absolute',
                top: size + 3, left: '50%', transform: 'translateX(-50%)',
                font: '500 10px var(--font-mono)', color: '#C9D2BB',
                background: 'rgba(11,19,6,0.85)', padding: '1px 5px',
                borderRadius: 4, whiteSpace: 'nowrap',
                border: '0.5px solid #1F2B16',
              }}>
                {u.handle}
              </span>
            </button>
          );
        });
      })}

      {/* Bottom hint */}
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 14,
        textAlign: 'center',
        font: 'italic 400 12px var(--font-serif)', color: '#8A9678',
      }}>
        tap anyone to open · the closer they orbit, the deeper you've gone
      </div>
    </div>
  );
}


window.Rings = Rings;
