// Reusable visual primitives for the Tron-y aesthetic
const { useEffect, useRef, useState, useMemo, useLayoutEffect } = React;

// Animated grid floor / scanline background
function NeonGrid({ intensity = 1, hue = '#00f0ff' }) {
  return (
    <div className="neon-grid" style={{ '--grid-hue': hue, opacity: 0.55 * intensity }}>
      <div className="neon-grid__floor"></div>
      <div className="neon-grid__scan"></div>
      <div className="neon-grid__vignette"></div>
    </div>
  );
}

// Glowing label chip
function Chip({ children, color = '#00f0ff', size = 'sm', filled = false, style }) {
  const cls = `chip chip--${size}${filled ? ' chip--filled' : ''}`;
  return (
    <span className={cls} style={{ '--chip-color': color, ...(style || {}) }}>
      {children}
    </span>
  );
}

// Stat readout (mono number, label below)
function Stat({ label, value, color = '#00f0ff', size = 'md' }) {
  return (
    <div className={`stat stat--${size}`} style={{ '--stat-color': color }}>
      <div className="stat__value">{value}</div>
      <div className="stat__label">{label}</div>
    </div>
  );
}

// Animated number ticker
function NumberTick({ value, duration = 800, format = (v) => v }) {
  const [shown, setShown] = useState(value);
  const startRef = useRef(null);
  const fromRef = useRef(value);
  useEffect(() => {
    fromRef.current = shown;
    startRef.current = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - startRef.current) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setShown(Math.round(fromRef.current + (value - fromRef.current) * eased));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [value]);
  return <span>{format(shown)}</span>;
}

// "Fighter card" — tool as a trading card / bracket fighter
function FighterCard({ tool, size = 'md', glow = true, onClick, isWinner, isLoser, rank, voted, votePct }) {
  const cls = [
    'fighter',
    `fighter--${size}`,
    glow ? 'fighter--glow' : '',
    isWinner ? 'fighter--winner' : '',
    isLoser ? 'fighter--loser' : '',
    onClick ? 'fighter--clickable' : '',
    voted ? 'fighter--voted' : '',
  ].filter(Boolean).join(' ');
  return (
    <div className={cls} style={{ '--tool-color': tool.color }} onClick={onClick}>
      <div className="fighter__frame">
        <div className="fighter__top">
          <span className="fighter__cat">{tool.cat.toUpperCase()}</span>
          <span className="fighter__elo">ELO {tool.elo}</span>
        </div>
        <div className="fighter__sigil" aria-hidden>
          <div className="fighter__sigil-glyph">{tool.emoji}</div>
          <div className="fighter__sigil-rings">
            <div></div><div></div><div></div>
          </div>
        </div>
        <div className="fighter__name">{tool.name}</div>
        <div className="fighter__tag">{tool.tag}</div>
        <div className="fighter__stats">
          <div className="fighter__stat">
            <span className="lbl">PRICE</span>
            <span className="val">{tool.price}</span>
          </div>
          <div className="fighter__stat">
            <span className="lbl">HEAT</span>
            <span className="val">
              <span className="heatbar" style={{ '--heat': `${tool.hot}%` }}></span>
            </span>
          </div>
        </div>
        <div className="fighter__flags">
          {tool.free && <Chip color="#c6ff3d" size="xs">FREE TIER</Chip>}
          {tool.oss && <Chip color="#a78bff" size="xs">OPEN SRC</Chip>}
          {tool.local && <Chip color="#00f0ff" size="xs">LOCAL</Chip>}
        </div>
        {rank != null && (
          <div className="fighter__rank">#{rank}</div>
        )}
        {votePct != null && (
          <div className="fighter__votebar" style={{ '--pct': `${votePct}%` }}>
            <div className="fighter__votebar-fill"></div>
            <span className="fighter__votebar-label">{votePct}% picked</span>
          </div>
        )}
      </div>
    </div>
  );
}

// VS divider used between fighters
function VSDivider({ vertical = false, label = 'VS' }) {
  return (
    <div className={`vs ${vertical ? 'vs--vert' : ''}`}>
      <div className="vs__bar"></div>
      <div className="vs__label">{label}</div>
      <div className="vs__bar"></div>
    </div>
  );
}

// Glitch text — letters jitter on mount
function GlitchText({ children, className = '', as = 'span' }) {
  const Tag = as;
  return (
    <Tag className={`glitch ${className}`} data-text={children}>
      {children}
    </Tag>
  );
}

// Animated typewriter for landing
function Typewriter({ items, className }) {
  const [idx, setIdx] = useState(0);
  const [shown, setShown] = useState('');
  const [phase, setPhase] = useState('typing'); // typing | hold | erasing
  useEffect(() => {
    const word = items[idx];
    let t;
    if (phase === 'typing') {
      if (shown.length < word.length) {
        t = setTimeout(() => setShown(word.slice(0, shown.length + 1)), 55);
      } else {
        t = setTimeout(() => setPhase('hold'), 1200);
      }
    } else if (phase === 'hold') {
      t = setTimeout(() => setPhase('erasing'), 900);
    } else if (phase === 'erasing') {
      if (shown.length > 0) {
        t = setTimeout(() => setShown(shown.slice(0, -1)), 25);
      } else {
        setIdx((idx + 1) % items.length);
        setPhase('typing');
      }
    }
    return () => clearTimeout(t);
  }, [shown, phase, idx, items]);
  return <span className={className}>{shown}<span className="caret">▋</span></span>;
}

window.NeonGrid = NeonGrid;
window.Chip = Chip;
window.Stat = Stat;
window.NumberTick = NumberTick;
window.FighterCard = FighterCard;
window.VSDivider = VSDivider;
window.GlitchText = GlitchText;
window.Typewriter = Typewriter;
