/* AUREN — shared UI kit (Babel JSX). Exports to window. */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ---------------- Icons (stroke, currentColor) ---------------- */
const PATHS = {
  mesh: '<circle cx="12" cy="5" r="2"/><circle cx="5" cy="16" r="2"/><circle cx="19" cy="16" r="2"/><circle cx="12" cy="12" r="2"/><path d="M12 7v3M10.3 13.3 6.5 15M13.7 13.3l3.8 1.7M7 16h10"/>',
  gpu: '<rect x="3" y="6" width="18" height="12" rx="1.5"/><rect x="6" y="9" width="6" height="6" rx="1"/><path d="M15 9h3M15 12h3M15 15h3M7 6V4M11 6V4M16 18v2"/>',
  route: '<circle cx="6" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="M6 8.5V14a3 3 0 0 0 3 3h6.5M8.5 6H14a3 3 0 0 1 3 3v6"/>',
  scale: '<path d="M3 17V7M3 7l4-2M21 7v10M21 17l-4 2M8 12h8M14 9l3 3-3 3M10 15l-3-3 3-3"/>',
  settle: '<rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 10h18M7 15h4"/><circle cx="16.5" cy="15" r="1.2"/>',
  sync: '<path d="M4 12a8 8 0 0 1 13.7-5.6L20 8M20 4v4h-4M20 12a8 8 0 0 1-13.7 5.6L4 16M4 20v-4h4"/>',
  dashboard: '<rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="11" width="7" height="10" rx="1"/><rect x="3" y="15" width="7" height="6" rx="1"/>',
  nodes: '<rect x="3" y="4" width="18" height="6" rx="1.5"/><rect x="3" y="14" width="18" height="6" rx="1.5"/><path d="M7 7h.01M7 17h.01"/>',
  workloads: '<path d="M4 6h16M4 12h16M4 18h10"/><circle cx="18" cy="18" r="2.5"/>',
  staking: '<path d="M12 3 4 7v6c0 4 3.5 7 8 8 4.5-1 8-4 8-8V7l-8-4Z"/><path d="m9 12 2 2 4-4"/>',
  wallet: '<rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18M16 14h2"/><path d="M17 6V4.5a1.5 1.5 0 0 0-2-1.4L5 6"/>',
  explorer: '<circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c2.5 2.5 3.8 5.8 3.8 9s-1.3 6.5-3.8 9c-2.5-2.5-3.8-5.8-3.8-9S9.5 5.5 12 3Z"/>',
  governance: '<path d="M12 3v18M5 8l7-4 7 4M5 8v8l7 4 7-4V8M9 11v4M15 11v4"/>',
  settings: '<circle cx="12" cy="12" r="3"/><path d="M19.4 13.5a1.7 1.7 0 0 0 .3 1.9l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-2.9 1.2V20a2 2 0 0 1-4 0v-.2a1.7 1.7 0 0 0-2.9-1.2l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0-1.2-2.9H3a2 2 0 0 1 0-4h.2a1.7 1.7 0 0 0 1.2-2.9l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 2.9-1.2V3a2 2 0 0 1 4 0v.2a1.7 1.7 0 0 0 2.9 1.2l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.9Z"/>',
  logout: '<path d="M15 4h3a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-3M10 17l-5-5 5-5M5 12h11"/>',
  arrow: '<path d="M5 12h14M13 6l6 6-6 6"/>',
  bolt: '<path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/>',
  check: '<path d="M5 12l4 4L19 7"/>',
  cube: '<path d="M12 2 3 7v10l9 5 9-5V7l-9-5Z"/><path d="M3 7l9 5 9-5M12 12v10"/>',
  shield: '<path d="M12 3 5 6v5c0 4 3 7.5 7 9 4-1.5 7-5 7-9V6l-7-3Z"/>',
  globe: '<circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/>',
  plus: '<path d="M12 5v14M5 12h14"/>',
  trend: '<path d="M3 17l6-6 4 4 8-8M21 7h-5M21 7v5"/>',
  chip: '<rect x="6" y="6" width="12" height="12" rx="1"/><path d="M9 3v3M15 3v3M9 18v3M15 18v3M3 9h3M3 15h3M18 9h3M18 15h3"/>',
  x: '<path d="M6 6l12 12M18 6 6 18"/>',
  menu: '<path d="M4 6h16M4 12h16M4 18h16"/>',
  xlogo: '<path fill="currentColor" stroke="none" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>',
};
function Icon({ name, size = 20, stroke = 1.6, className = '', style = {} }) {
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
    stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
    className={className} style={style} dangerouslySetInnerHTML={{ __html: PATHS[name] || '' }} />;
}

/* ---------------- Button ---------------- */
function Button({ children, variant = 'primary', size = 'md', icon, iconRight, onClick, type, full, className = '', style = {} }) {
  const base = {
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 9,
    fontFamily: 'var(--font-body)', fontWeight: 600, cursor: 'pointer',
    borderRadius: 'var(--r-sm)', border: '1px solid transparent', whiteSpace: 'nowrap',
    transition: 'all .25s var(--ease)', letterSpacing: '.01em',
    width: full ? '100%' : 'auto', position: 'relative', overflow: 'hidden',
  };
  const sizes = {
    sm: { padding: '7px 14px', fontSize: 13 },
    md: { padding: '11px 22px', fontSize: 14.5 },
    lg: { padding: '15px 30px', fontSize: 16 },
  };
  const variants = {
    primary: { background: 'var(--grad-cyan)', color: '#021018', boxShadow: 'var(--glow-cyan-sm)' },
    ghost: { background: 'rgba(255,255,255,0.03)', color: 'var(--text-1)', border: '1px solid var(--line-2)' },
    outline: { background: 'transparent', color: 'var(--cyan)', border: '1px solid var(--line-cyan)' },
    subtle: { background: 'var(--surface-2)', color: 'var(--text-1)', border: '1px solid var(--line)' },
    danger: { background: 'rgba(255,92,122,0.1)', color: 'var(--red)', border: '1px solid rgba(255,92,122,0.3)' },
  };
  return (
    <button type={type || 'button'} onClick={onClick} className={'au-btn ' + className}
      style={{ ...base, ...sizes[size], ...variants[variant], ...style }}>
      {icon && <Icon name={icon} size={size === 'sm' ? 15 : 17} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === 'sm' ? 15 : 17} />}
    </button>
  );
}

/* ---------------- Panel / Card ---------------- */
function Panel({ children, className = '', style = {}, glow = false, hover = false, ...rest }) {
  return (
    <div className={'au-panel ' + (hover ? 'au-panel-hover ' : '') + className}
      style={{
        background: 'var(--grad-panel)', border: '1px solid var(--line)',
        borderRadius: 'var(--r-lg)', position: 'relative',
        boxShadow: glow ? 'var(--glow-soft)' : 'none', ...style,
      }} {...rest}>
      {children}
    </div>
  );
}

/* ---------------- Badge / Pill ---------------- */
function Badge({ children, color = 'cyan', dot = false, style = {} }) {
  const map = {
    cyan: ['rgba(24,224,255,0.12)', 'var(--cyan)', 'rgba(24,224,255,0.3)'],
    green: ['rgba(61,245,166,0.12)', 'var(--green)', 'rgba(61,245,166,0.3)'],
    amber: ['rgba(255,197,66,0.12)', 'var(--amber)', 'rgba(255,197,66,0.3)'],
    red: ['rgba(255,92,122,0.12)', 'var(--red)', 'rgba(255,92,122,0.3)'],
    violet: ['rgba(156,123,255,0.12)', 'var(--violet)', 'rgba(156,123,255,0.3)'],
    gray: ['rgba(154,169,184,0.1)', 'var(--text-2)', 'rgba(154,169,184,0.25)'],
  };
  const [bg, fg, bd] = map[color] || map.cyan;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6, padding: '3px 10px',
      fontSize: 11.5, fontWeight: 600, fontFamily: 'var(--font-mono)', letterSpacing: '.04em',
      background: bg, color: fg, border: '1px solid ' + bd, borderRadius: 100,
      textTransform: 'uppercase', ...style,
    }}>
      {dot && <span style={{ width: 6, height: 6, borderRadius: 6, background: fg, boxShadow: '0 0 8px ' + fg }} />}
      {children}
    </span>
  );
}

/* ---------------- Animated counter ---------------- */
function useCountUp(target, dur = 1400, dec = 0) {
  const [v, setV] = useState(0);
  useEffect(() => {
    let raf, start, done = false;
    function step(t) {
      if (!start) start = t;
      const p = Math.min((t - start) / dur, 1);
      const e = 1 - Math.pow(1 - p, 3);
      setV(target * e);
      if (p < 1) raf = requestAnimationFrame(step); else done = true;
    }
    raf = requestAnimationFrame(step);
    // Guarantee final value even if RAF is throttled (hidden/inactive iframe).
    const guard = setTimeout(() => { if (!done) setV(target); }, dur + 250);
    return () => { cancelAnimationFrame(raf); clearTimeout(guard); };
  }, [target]);
  return dec === 0 ? Math.round(v) : +v.toFixed(dec);
}

/* ---------------- Sparkline (SVG) ---------------- */
function Sparkline({ data, w = 120, h = 36, color = 'var(--cyan)', fill = true, strokeW = 1.8 }) {
  const { d, area, last } = useMemo(() => {
    const min = Math.min(...data), max = Math.max(...data);
    const rng = max - min || 1;
    const pts = data.map((v, i) => [(i / (data.length - 1)) * w, h - ((v - min) / rng) * (h - 4) - 2]);
    const d = pts.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
    const area = d + ` L${w} ${h} L0 ${h} Z`;
    return { d, area, last: pts[pts.length - 1] };
  }, [data, w, h]);
  const id = useMemo(() => 'sp' + Math.random().toString(36).slice(2, 7), []);
  return (
    <svg width={w} height={h} style={{ overflow: 'visible', display: 'block' }}>
      <defs>
        <linearGradient id={id} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor={color} stopOpacity="0.28" />
          <stop offset="1" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      {fill && <path d={area} fill={`url(#${id})`} />}
      <path d={d} fill="none" stroke={color} strokeWidth={strokeW} strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={last[0]} cy={last[1]} r="2.5" fill={color} style={{ filter: 'drop-shadow(0 0 4px ' + color + ')' }} />
    </svg>
  );
}

/* ---------------- Progress bar ---------------- */
function Progress({ value, color = 'var(--cyan)', h = 6, glow = true }) {
  return (
    <div style={{ width: '100%', height: h, background: 'rgba(255,255,255,0.06)', borderRadius: 100, overflow: 'hidden' }}>
      <div style={{
        width: Math.min(100, value) + '%', height: '100%', borderRadius: 100,
        background: color === 'var(--cyan)' ? 'var(--grad-cyan)' : color,
        boxShadow: glow ? '0 0 10px ' + color : 'none', transition: 'width .8s var(--ease)',
      }} />
    </div>
  );
}

/* ---------------- Stat tile ---------------- */
function Stat({ label, value, suffix, prefix, sub, icon, spark, sparkColor, dec = 0, accent }) {
  const num = useCountUp(typeof value === 'number' ? value : 0, 1400, dec);
  const display = typeof value === 'number'
    ? (prefix || '') + num.toLocaleString('en-US', { minimumFractionDigits: dec, maximumFractionDigits: dec }) + (suffix || '')
    : value;
  return (
    <Panel hover style={{ padding: '18px 20px', display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <span style={{ fontSize: 12.5, color: 'var(--text-2)', fontWeight: 500, letterSpacing: '.02em' }}>{label}</span>
        {icon && <span style={{ color: accent || 'var(--cyan)', opacity: 0.8 }}><Icon name={icon} size={17} /></span>}
      </div>
      <div className="font-display" style={{ fontSize: 27, fontWeight: 700, color: 'var(--text-0)', lineHeight: 1, letterSpacing: '-.01em' }}>{display}</div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: 18 }}>
        {sub && <span style={{ fontSize: 12, color: sub.color || 'var(--text-2)', fontFamily: 'var(--font-mono)', fontWeight: 500 }}>{sub.text}</span>}
        {spark && <Sparkline data={spark} w={80} h={24} color={sparkColor || 'var(--cyan)'} strokeW={1.5} />}
      </div>
    </Panel>
  );
}

/* ---------------- Section heading ---------------- */
function SectionHead({ eyebrow, title, sub, center, light }) {
  return (
    <div style={{ textAlign: center ? 'center' : 'left', maxWidth: center ? 720 : 'none', margin: center ? '0 auto' : 0 }}>
      {eyebrow && <div className="eyebrow" style={{ marginBottom: 14 }}>{eyebrow}</div>}
      <h2 className="font-display" style={{
        fontSize: 'clamp(26px, 4vw, 42px)', fontWeight: 700, lineHeight: 1.08,
        letterSpacing: '-.01em', color: 'var(--text-0)', marginBottom: sub ? 16 : 0,
      }}>{title}</h2>
      {sub && <p style={{ fontSize: 'clamp(15px,1.6vw,17.5px)', color: 'var(--text-2)', lineHeight: 1.6, maxWidth: 640, margin: center ? '0 auto' : 0, textWrap: 'pretty' }}>{sub}</p>}
    </div>
  );
}

/* ---------------- Reveal on scroll ---------------- */
function Reveal({ children, delay = 0, y = 26, as = 'div', style = {}, ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    // Fallback: if IO never fires (e.g. offscreen/hidden iframe), reveal anyway.
    const fb = setTimeout(() => setShown(true), 600);
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setShown(true); clearTimeout(fb); io.disconnect(); }
    }, { threshold: 0.08 });
    io.observe(el);
    return () => { io.disconnect(); clearTimeout(fb); };
  }, []);
  const Tag = as;
  return (
    <Tag ref={ref} style={{
      opacity: shown ? 1 : 0,
      transform: shown ? 'translateY(0)' : `translateY(${y}px)`,
      transition: `opacity .7s var(--ease) ${delay}ms, transform .7s var(--ease) ${delay}ms`,
      ...style,
    }} {...rest}>{children}</Tag>
  );
}

/* ---------------- Three.js mount hook ---------------- */
function useThreeScene(factory, deps = []) {
  const ref = useRef(null);
  useEffect(() => {
    if (!ref.current || !window.AURENThree) return;
    const ctl = factory(ref.current);
    return () => ctl && ctl.destroy && ctl.destroy();
  }, deps);
  return ref;
}

Object.assign(window, {
  Icon, Button, Panel, Badge, Sparkline, Progress, Stat, SectionHead,
  Reveal, useCountUp, useThreeScene,
  React, useState, useEffect, useRef, useMemo, useCallback,
});
