// kataleya-ui.jsx
// Ouroboros Protocol — visual primitives
// Faithful to native app tokens: Null Black, Courier Prime, phase accents.

// ── Phase theme ──────────────────────────────────────────────────────────
const PHASE_THEME = {
  dawn:       { accent: '#00d4aa', rgb: '0,212,170',  displayName: 'morning',     ouro: 'renewal', speed: 14000 },
  day:        { accent: '#00ecc4', rgb: '0,236,196',  displayName: 'afternoon',   ouro: 'choice',  speed: 10000 },
  goldenHour: { accent: '#ff6b35', rgb: '255,107,53', displayName: 'evening',     ouro: 'desire',  speed: 8000  },
  night:      { accent: '#8a5fe0', rgb: '138,95,224', displayName: 'night',       ouro: 'void',    speed: 22000 },
};

const BASE = {
  bg: '#050508',
  surface: '#0d0d14',
  surfaceHi: '#14141f',
  text: '#e8e6f0',
  textMuted: '#8a8a9e',
  border: '#1c1c28',
  scar: '#8a8a9e',
};

const rgba = (rgb, a) => `rgba(${rgb}, ${a})`;

// ── Ouroboros Ring ─────────────────────────────────────────────────────
// Never-closing, segment ticks, head diamond, tail dot, scar marks.
function OuroborosRing({ size = 260, phase = 'night', cycleCount = 0, transmutationScars = 0, gapFraction = 0.14, breathing = true, showHeadTail = true }) {
  const theme = PHASE_THEME[phase];
  const color = theme.accent;
  const R = size / 2;
  const strokeW = Math.max(1.2, size * 0.005);
  const radius = R - strokeW - 3;
  const circ = 2 * Math.PI * radius;
  const arcLength = circ * (1 - gapFraction);

  const tailAngleDeg = -90;
  const headAngleDeg = -90 + (1 - gapFraction) * 360;
  const toXY = (deg) => {
    const rad = (deg * Math.PI) / 180;
    return { x: R + radius * Math.cos(rad), y: R + radius * Math.sin(rad) };
  };
  const tail = toXY(tailAngleDeg);
  const head = toXY(headAngleDeg);

  const headR = Math.max(strokeW * 2.4, radius * 0.034);
  const tailR = Math.max(strokeW * 1.4, radius * 0.016);

  const diamond = `M ${head.x} ${head.y - headR} L ${head.x + headR * 0.65} ${head.y} L ${head.x} ${head.y + headR * 0.5} L ${head.x - headR * 0.65} ${head.y} Z`;

  // Growth scars — one per 3 days, max 12
  const growth = Math.min(Math.floor(cycleCount / 3), 12);
  const growthArcs = Array.from({ length: growth }, (_, i) => {
    const deg = (i / 12) * 360;
    const a = toXY(deg);
    const b = toXY(deg + (0.14 * 180) / Math.PI);
    return { a, b, key: `g${i}` };
  });

  // Transmutation scars — max 8, offset 22.5°
  const trans = Math.min(transmutationScars, 8);
  const transArcs = Array.from({ length: trans }, (_, i) => {
    const deg = (i / 8) * 360 + 22.5;
    const a = toXY(deg);
    const b = toXY(deg + (0.18 * 180) / Math.PI);
    return { a, b, key: `t${i}` };
  });

  // Segment ticks via dasharray
  const tickCount = 32;
  const tickGap = circ / tickCount;

  return (
    <div style={{
      width: size, height: size, position: 'relative',
      animation: breathing ? 'ouroBreathe 4.8s ease-in-out infinite' : 'none',
    }}>
      {/* Outer glow */}
      <div style={{
        position: 'absolute',
        inset: `${-size * 0.09}px`,
        borderRadius: '50%',
        background: color,
        opacity: 0.06,
        filter: `blur(${size * 0.03}px)`,
        animation: breathing ? 'ouroGlow 4.8s ease-in-out infinite' : 'none',
      }} />
      <div style={{
        width: size, height: size,
        animation: `ouroSpin ${theme.speed}ms linear infinite`,
      }}>
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
          {/* Base ring */}
          <circle
            cx={R} cy={R} r={radius}
            fill="none" stroke={color} strokeWidth={strokeW}
            strokeOpacity={0.35}
            strokeDasharray={`${arcLength} ${circ - arcLength}`}
            strokeLinecap="butt"
            transform={`rotate(-90 ${R} ${R})`}
          />
          {/* Segment ticks */}
          <circle
            cx={R} cy={R} r={radius}
            fill="none" stroke={color} strokeWidth={strokeW * 2}
            strokeOpacity={0.18}
            strokeDasharray={`1.5 ${tickGap}`}
            strokeLinecap="butt"
            transform={`rotate(-90 ${R} ${R})`}
          />
          {showHeadTail && (
            <>
              {/* Tail */}
              <circle cx={tail.x} cy={tail.y} r={tailR} fill={color} opacity={0.38} />
              {/* Head diamond */}
              <path d={diamond} fill={color} opacity={0.75}
                stroke={color} strokeWidth={strokeW * 0.8} strokeLinejoin="round" />
              <circle cx={head.x} cy={head.y} r={headR * 0.25} fill={color} opacity={0.95} />
            </>
          )}
          {/* Growth scars */}
          {growthArcs.map(g => (
            <path key={g.key}
              d={`M ${g.a.x} ${g.a.y} A ${radius} ${radius} 0 0 1 ${g.b.x} ${g.b.y}`}
              fill="none" stroke={BASE.scar} strokeWidth={strokeW + 0.5}
              strokeLinecap="round" opacity={0.7} />
          ))}
          {/* Transmutation scars */}
          {transArcs.map(t => (
            <path key={t.key}
              d={`M ${t.a.x} ${t.a.y} A ${radius} ${radius} 0 0 1 ${t.b.x} ${t.b.y}`}
              fill="none" stroke={color} strokeWidth={strokeW + 1.2}
              strokeLinecap="round" opacity={0.55} />
          ))}
        </svg>
      </div>
    </div>
  );
}

// ── Sphere Orb ─────────────────────────────────────────────────────────
// 3D volume, layered radial gradients. Responds to pressed state.
function SphereOrb({ size = 150, phase = 'night', pressed = false, bpm = 60 }) {
  const theme = PHASE_THEME[phase];
  const breathMs = Math.round(60000 / bpm) * 2; // two beats per breath
  return (
    <div style={{
      width: size, height: size, position: 'relative',
      transform: pressed ? 'scale(0.97)' : 'scale(1)',
      transition: 'transform 300ms cubic-bezier(.4,0,.2,1)',
    }}>
      {/* outer halo */}
      <div style={{
        position: 'absolute', inset: `${-size * 0.18}px`,
        borderRadius: '50%',
        background: `radial-gradient(circle at 50% 50%, ${rgba(theme.rgb, 0.22)} 0%, ${rgba(theme.rgb, 0.08)} 35%, transparent 65%)`,
        filter: `blur(${size * 0.04}px)`,
        animation: `orbPulse ${breathMs}ms ease-in-out infinite`,
      }} />
      {/* core sphere — dark base */}
      <div style={{
        position: 'absolute', inset: 0,
        borderRadius: '50%',
        background: `
          radial-gradient(circle at 35% 30%, ${rgba(theme.rgb, 0.55)} 0%, ${rgba(theme.rgb, 0.15)} 25%, rgba(5,5,8,0.95) 65%, rgba(5,5,8,1) 100%),
          radial-gradient(circle at 50% 50%, ${rgba(theme.rgb, 0.18)} 0%, transparent 55%)
        `,
        boxShadow: `
          inset 0 0 ${size * 0.1}px ${rgba(theme.rgb, 0.25)},
          inset -${size * 0.02}px -${size * 0.04}px ${size * 0.08}px rgba(0,0,0,0.6),
          0 0 ${size * 0.2}px ${rgba(theme.rgb, 0.35)}
        `,
      }} />
      {/* specular highlight */}
      <div style={{
        position: 'absolute',
        top: '18%', left: '25%',
        width: '32%', height: '22%',
        borderRadius: '50%',
        background: `radial-gradient(ellipse at 50% 50%, ${rgba(theme.rgb, 0.45)} 0%, transparent 70%)`,
        filter: 'blur(6px)',
        opacity: 0.8,
      }} />
      {/* inner glyph ..: :.. */}
      <div style={{
        position: 'absolute', inset: 0,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: '"Courier Prime", ui-monospace, monospace',
        fontSize: size * 0.13,
        color: rgba(theme.rgb, 0.5),
        letterSpacing: size * 0.01,
        textShadow: `0 0 ${size * 0.06}px ${rgba(theme.rgb, 0.6)}`,
        animation: `glyphPulse ${breathMs * 1.3}ms ease-in-out infinite`,
      }}>..: :..</div>
    </div>
  );
}

// ── Butterfly — the real asset ─────────────────────────────────────────
// butterfly-dna-t.gif: monarch body, DNA helix wings, transparent bg.
// Phase accent applied via CSS filter — hue-rotate off the sepia baseline.
function ButterflyDNA({ size = 88, phase = 'night', inverse = false }) {
  // sepia baseline hue ≈ 30°. rotate to each phase's accent hue.
  // dawn/day cyan ≈ 170°, goldenHour amber ≈ 15°, night violet ≈ 270°.
  const hueByPhase = { dawn: 140, day: 140, goldenHour: -15, night: 240 };
  const filter = `hue-rotate(${hueByPhase[phase]}deg) saturate(0.75) brightness(1.05)`;
  return (
    <div style={{
      width: size, height: size, position: 'relative',
      animation: `butterfly${inverse ? 'Inv' : ''} 3.6s ease-in-out infinite`,
    }}>
      <img
        src="assets/butterfly-dna-t.gif"
        alt=""
        style={{
          width: '100%', height: '100%', objectFit: 'contain',
          filter,
          opacity: 0.88,
          mixBlendMode: 'screen',
        }}
      />
    </div>
  );
}

// ── Typewriter Text ─────────────────────────────────────────────────────
function Typewriter({ text, speed = 45, jitter = 28, startDelay = 0, onComplete, style, key: k }) {
  const [out, setOut] = React.useState('');
  React.useEffect(() => {
    setOut('');
    let i = 0;
    let cancelled = false;
    const step = () => {
      if (cancelled) return;
      if (i <= text.length) {
        setOut(text.slice(0, i));
        const ch = text[i - 1];
        let extra = 0;
        if (ch === '.' || ch === '?' || ch === '!') extra = 140;
        else if (ch === ',' || ch === ';') extra = 80;
        const delay = speed + (Math.random() - 0.5) * jitter + extra;
        i++;
        if (i <= text.length + 1) setTimeout(step, delay);
        else onComplete && onComplete();
      }
    };
    const t = setTimeout(step, startDelay);
    return () => { cancelled = true; clearTimeout(t); };
  }, [text]);
  return <span style={style}>{out}<span style={{ opacity: 0.35 }}>{out.length < text.length ? '▍' : ''}</span></span>;
}

// ── Atmosphere ──────────────────────────────────────────────────────────
// Phase-aware ambient background — gentle vignette, tiny noise dots.
function Atmosphere({ phase = 'night' }) {
  const theme = PHASE_THEME[phase];
  return (
    <div style={{ position: 'absolute', inset: 0, overflow: 'hidden', pointerEvents: 'none' }}>
      {/* phase vignette */}
      <div style={{
        position: 'absolute', inset: 0,
        background: `radial-gradient(ellipse at 50% 45%, ${rgba(theme.rgb, 0.08)} 0%, transparent 55%)`,
      }} />
      {/* top-edge phase bleed (golden hour warms the top) */}
      {phase === 'goldenHour' && (
        <div style={{
          position: 'absolute', top: 0, left: 0, right: 0, height: '45%',
          background: `linear-gradient(180deg, ${rgba(theme.rgb, 0.09)} 0%, transparent 100%)`,
        }} />
      )}
      {/* night void — subtle bottom hush */}
      {phase === 'night' && (
        <div style={{
          position: 'absolute', bottom: 0, left: 0, right: 0, height: '40%',
          background: `linear-gradient(0deg, ${rgba(theme.rgb, 0.06)} 0%, transparent 100%)`,
        }} />
      )}
      {/* noise grain */}
      <div style={{
        position: 'absolute', inset: 0,
        backgroundImage: 'radial-gradient(rgba(232,230,240,0.02) 1px, transparent 1px)',
        backgroundSize: '3px 3px',
        opacity: 0.6,
      }} />
    </div>
  );
}

// ── HUD corner brackets ─────────────────────────────────────────────────
function HudCorners({ phase = 'night', opacity = 0.38, inset = 18 }) {
  const theme = PHASE_THEME[phase];
  const c = rgba(theme.rgb, opacity);
  const sz = 16;
  const base = { position: 'absolute', width: sz, height: sz };
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
      <div style={{ ...base, top: inset, left: inset,    borderTop: `1px solid ${c}`, borderLeft:  `1px solid ${c}` }} />
      <div style={{ ...base, top: inset, right: inset,   borderTop: `1px solid ${c}`, borderRight: `1px solid ${c}` }} />
      <div style={{ ...base, bottom: inset, left: inset, borderBottom: `1px solid ${c}`, borderLeft:  `1px solid ${c}` }} />
      <div style={{ ...base, bottom: inset, right: inset,borderBottom: `1px solid ${c}`, borderRight: `1px solid ${c}` }} />
    </div>
  );
}

// ── Mercury divider ─────────────────────────────────────────────────────
function MercuryLine({ phase = 'night', width = 40 }) {
  const theme = PHASE_THEME[phase];
  return (
    <div style={{
      marginTop: 8,
      width, height: 1,
      background: `linear-gradient(90deg, transparent 0%, ${rgba(theme.rgb, 0.5)} 50%, transparent 100%)`,
    }} />
  );
}

Object.assign(window, {
  PHASE_THEME, BASE, rgba,
  OuroborosRing, SphereOrb, ButterflyDNA,
  Typewriter, Atmosphere, HudCorners, MercuryLine,
});
