// Shared atoms — Mark, Wordmark, GridBackdrop, helpers
// Loaded after React/Babel.

const Mark = ({ size = 24, color }) => (
  <svg width={size} height={size} viewBox="0 0 32 32" fill="none" style={{ color: color || 'currentColor', flex: 'none' }}>
    <circle cx="16" cy="16" r="13" stroke="currentColor" strokeWidth="2.25" fill="none" />
    <rect x="8"  y="18" width="3" height="6"  rx="0.5" fill="currentColor" />
    <rect x="13" y="14" width="3" height="10" rx="0.5" fill="currentColor" />
    <rect x="18" y="11" width="3" height="13" rx="0.5" fill="currentColor" />
    <path d="M22.5 12 L25 8 L24 11 L26 9.5" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none" />
  </svg>
);

const Wordmark = ({ size = 22, prefix = false }) => (
  <span style={{
    display: 'inline-flex', alignItems: 'center', gap: 8,
    fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: size,
    letterSpacing: '-0.025em', color: 'var(--fg-0)',
  }}>
    <Mark size={size + 4} />
    {prefix && <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--fg-3)', fontWeight: 400 }}>//</span>}
    <span>tokenmaxxer</span>
  </span>
);

// Subliminal terminal grid — used at most once per page
const GridBackdrop = ({ alpha = 0.5, size = 60 }) => (
  <div aria-hidden="true" style={{
    position: 'absolute', inset: 0, pointerEvents: 'none',
    backgroundImage: `linear-gradient(to right, var(--bg-2) 1px, transparent 1px),
                      linear-gradient(to bottom, var(--bg-2) 1px, transparent 1px)`,
    backgroundSize: `${size}px ${size}px`,
    opacity: alpha,
    maskImage: 'radial-gradient(ellipse at center, black 30%, transparent 80%)',
    WebkitMaskImage: 'radial-gradient(ellipse at center, black 30%, transparent 80%)',
  }} />
);

// // tagline — the brand's signature double-slash overline
const SlashTag = ({ children, color }) => (
  <span style={{
    fontFamily: 'var(--font-mono)', fontSize: 13, color: color || 'var(--fg-3)',
    letterSpacing: 0,
  }}>
    <span style={{ color: 'var(--accent)' }}>//</span> {children}
  </span>
);

// Receipt-tape dashed rule
const Rule = ({ vertical = false, color, style }) => (
  <div aria-hidden="true" style={
    vertical
      ? { width: 0, alignSelf: 'stretch', borderLeft: `1px dashed ${color || 'var(--fg-4)'}`, ...style }
      : { width: '100%', height: 0, borderTop: `1px dashed ${color || 'var(--fg-4)'}`, ...style }
  } />
);

// useInterval (no-flicker setInterval hook)
function useInterval(cb, ms) {
  const ref = React.useRef(cb);
  React.useEffect(() => { ref.current = cb; }, [cb]);
  React.useEffect(() => {
    if (ms == null) return;
    const id = setInterval(() => ref.current(), ms);
    return () => clearInterval(id);
  }, [ms]);
}

// Animated tabular number — counts toward target
function TickNum({ value, decimals = 1, suffix = '', duration = 600, prefix = '' }) {
  const [shown, setShown] = React.useState(value);
  const fromRef = React.useRef(value);
  const toRef = React.useRef(value);
  const startRef = React.useRef(0);
  const rafRef = React.useRef(0);

  React.useEffect(() => {
    fromRef.current = shown;
    toRef.current = value;
    startRef.current = performance.now();
    cancelAnimationFrame(rafRef.current);
    const tick = (t) => {
      const p = Math.min(1, (t - startRef.current) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      const v = fromRef.current + (toRef.current - fromRef.current) * eased;
      setShown(v);
      if (p < 1) rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
    // eslint-disable-next-line
  }, [value]);

  const txt = decimals === 0 ? Math.round(shown).toLocaleString() : shown.toFixed(decimals);
  return <span className="t-num">{prefix}{txt}{suffix}</span>;
}

function useMediaQuery(query) {
  const get = () => typeof window !== 'undefined' && window.matchMedia
    ? window.matchMedia(query).matches
    : false;
  const [matches, setMatches] = React.useState(get);
  React.useEffect(() => {
    const mql = window.matchMedia(query);
    const onChange = () => setMatches(mql.matches);
    onChange();
    mql.addEventListener ? mql.addEventListener('change', onChange) : mql.addListener(onChange);
    return () => {
      mql.removeEventListener ? mql.removeEventListener('change', onChange) : mql.removeListener(onChange);
    };
  }, [query]);
  return matches;
}

Object.assign(window, { Mark, Wordmark, GridBackdrop, SlashTag, Rule, useInterval, TickNum, useMediaQuery });
