// Shared SVG icons & small primitives
const { useEffect: useEffectP, useRef: useRefP, useState: useStateP } = React;

function Icon({ name, size = 24, stroke = 1.25 }) {
  const props = {
    width: size, height: size, viewBox: '0 0 24 24',
    fill: 'none', stroke: 'currentColor',
    strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round'
  };
  const paths = {
    globe: <g><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18"/></g>,
    layers: <g><path d="M12 3L2 8l10 5 10-5-10-5z"/><path d="M2 13l10 5 10-5M2 18l10 5 10-5"/></g>,
    satellite: <g><path d="M12 2v4M2 12h4M22 12h-4M12 22v-4"/><circle cx="12" cy="12" r="4"/><path d="M7 7l2 2M15 15l2 2M17 7l-2 2M9 15l-2 2"/></g>,
    brain: <g><path d="M9 3a3 3 0 0 0-3 3v2a3 3 0 0 0-2 2.83V14a3 3 0 0 0 3 3v1a3 3 0 0 0 5 0V6a3 3 0 0 0-3-3Z"/><path d="M15 3a3 3 0 0 1 3 3v2a3 3 0 0 1 2 2.83V14a3 3 0 0 1-3 3v1a3 3 0 0 1-5 0"/></g>,
    leaf: <g><path d="M11 20A7 7 0 0 1 4 13c0-7 9-9 17-9-1 9-3 16-10 16Z"/><path d="M4 21c4-6 8-10 13-13"/></g>,
    route: <g><circle cx="5" cy="5" r="2"/><circle cx="19" cy="19" r="2"/><path d="M5 7v5a4 4 0 0 0 4 4h6a4 4 0 0 1 4 4v-2"/></g>,
    chart: <g><path d="M3 3v18h18"/><path d="M7 14l3-3 3 3 5-5"/></g>,
    arrow: <g><path d="M5 12h14M13 5l7 7-7 7"/></g>,
    plus: <g><path d="M12 5v14M5 12h14"/></g>,
    shield: <g><path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3Z"/></g>,
    scan: <g><path d="M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2M8 12h8"/></g>,
    pulse: <g><path d="M3 12h3l3-8 4 16 3-8h5"/></g>,
    map: <g><path d="M9 4l-6 2v14l6-2 6 2 6-2V4l-6 2-6-2Z"/><path d="M9 4v16M15 6v16"/></g>,
    building: <g><path d="M4 21V7l8-4 8 4v14"/><path d="M9 9h.01M9 13h.01M9 17h.01M15 9h.01M15 13h.01M15 17h.01"/></g>,
    tractor: <g><circle cx="7" cy="17" r="3"/><circle cx="18" cy="18" r="2"/><path d="M4 17V9h6l3 5h5"/></g>,
    city: <g><path d="M3 21V10l5-3 5 3M13 21V14l4-2 4 2v7"/><path d="M3 21h18"/></g>,
    alert: <g><path d="M12 3l10 18H2L12 3z"/><path d="M12 10v5M12 18h.01"/></g>,
    wind: <g><path d="M3 9h12a3 3 0 1 0-3-3M3 15h15a3 3 0 1 1-3 3M3 12h10"/></g>,
    bolt: <g><path d="M13 2L4 14h7l-1 8 9-12h-7l1-8z"/></g>,
    compass: <g><circle cx="12" cy="12" r="9"/><path d="M15.5 8.5l-2 5-5 2 2-5 5-2z"/></g>,
    eye: <g><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></g>,
  };
  return <svg {...props}>{paths[name]}</svg>;
}

function Reveal({ children, delay = 0 }) {
  const ref = useRefP(null);
  const [visible, setVisible] = useStateP(false);
  useEffectP(() => {
    if (!ref.current) return;
    // If already in view on mount, reveal immediately (w/ optional delay)
    const rect = ref.current.getBoundingClientRect();
    const vh = window.innerHeight || document.documentElement.clientHeight;
    if (rect.top < vh - 40) {
      const t = setTimeout(() => setVisible(true), delay);
      return () => clearTimeout(t);
    }
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setVisible(true); io.disconnect(); }
    }, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [delay]);
  return (
    <div ref={ref} className={"reveal" + (visible ? " visible" : "")} style={{ transitionDelay: delay + 'ms' }}>
      {children}
    </div>
  );
}

function Sparkline({ values, color = '#58d6ff', height = 22 }) {
  const max = Math.max(...values);
  return (
    <div className="panel-sparkline" style={{ height }}>
      {values.map((v, i) => (
        <span key={i} style={{ height: (v / max * 100) + '%', background: color }} />
      ))}
    </div>
  );
}

// Animated counter that counts up on reveal
function Counter({ value, suffix = '', duration = 1400, decimals = 0 }) {
  const ref = useRefP(null);
  const [display, setDisplay] = useStateP(0);
  useEffectP(() => {
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        const start = performance.now();
        const tick = (t) => {
          const p = Math.min(1, (t - start) / duration);
          const eased = 1 - Math.pow(1 - p, 3);
          setDisplay(eased * value);
          if (p < 1) requestAnimationFrame(tick);
        };
        requestAnimationFrame(tick);
        io.disconnect();
      }
    }, { threshold: 0.3 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, [value]);
  return <span ref={ref}>{display.toFixed(decimals)}{suffix}</span>;
}

window.Icon = Icon;
window.Reveal = Reveal;
window.Sparkline = Sparkline;
window.Counter = Counter;
