// Pyrovolt — Utilities: reveal-on-scroll, count-up, useInView

function useInView(ref, options = {}) {
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setInView(true); obs.unobserve(el); }
    }, { threshold: 0.15, rootMargin: '0px 0px -80px 0px', ...options });
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return inView;
}

function Reveal({ children, stagger = false, split = false, as: Tag = 'div', style, className = '', ...rest }) {
  const ref = React.useRef(null);
  const inView = useInView(ref);
  const cls = `${split ? 'split' : (stagger ? 'reveal-stagger' : 'reveal')} ${inView ? 'in' : ''} ${className}`;
  return <Tag ref={ref} className={cls} style={style} {...rest}>{children}</Tag>;
}

// Split a text into line-wrapped <span> elements for line reveal
function SplitText({ lines, className = '', style }) {
  const ref = React.useRef(null);
  const inView = useInView(ref);
  return (
    <span ref={ref} className={`split ${inView ? 'in' : ''} ${className}`} style={style}>
      {lines.map((l, i) => (
        <span key={i} className="line"><span>{l}</span></span>
      ))}
    </span>
  );
}

// Count-up number
function CountUp({ to, from = 0, duration = 1400, decimals = 0, suffix = '', prefix = '' }) {
  const ref = React.useRef(null);
  const inView = useInView(ref);
  const [v, setV] = React.useState(from);
  React.useEffect(() => {
    if (!inView) return;
    let raf, start;
    const anim = (t) => {
      if (!start) start = t;
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setV(from + (to - from) * eased);
      if (p < 1) raf = requestAnimationFrame(anim);
    };
    raf = requestAnimationFrame(anim);
    return () => cancelAnimationFrame(raf);
  }, [inView, to, from, duration]);
  return <span ref={ref} className="num-counter">{prefix}{v.toFixed(decimals)}{suffix}</span>;
}

// Parallax (translateY based on scroll offset relative to viewport)
function useParallax(speed = 0.3) {
  const ref = React.useRef(null);
  const [offset, setOffset] = React.useState(0);
  React.useEffect(() => {
    const onScroll = () => {
      if (!ref.current) return;
      const rect = ref.current.getBoundingClientRect();
      const viewH = window.innerHeight;
      const center = rect.top + rect.height/2 - viewH/2;
      setOffset(center * speed * -0.1);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, [speed]);
  return [ref, offset];
}

// Blueprint visual replacing the IMAGEN placeholder. Style varies by tag.
function BlueprintTile({ tag, height = 180, dark = false }) {
  const fg = dark ? 'rgba(244,242,237,0.7)' : 'rgba(14,14,14,0.7)';
  const fgDim = dark ? 'rgba(244,242,237,0.18)' : 'rgba(14,14,14,0.18)';
  const fgGrid = dark ? 'rgba(244,242,237,0.06)' : 'rgba(14,14,14,0.06)';
  const bg = dark ? 'var(--dark-bg-soft)' : 'var(--bg-soft)';
  const t = (tag || '').toLowerCase();
  let body;
  if (t.startsWith('proy')) {
    // Site / map layout
    body = (
      <>
        {/* roads */}
        <line x1="0" y1="60%" x2="100%" y2="60%" stroke={fg} strokeWidth="1" opacity="0.35"/>
        <line x1="35%" y1="0" x2="35%" y2="100%" stroke={fg} strokeWidth="1" opacity="0.35"/>
        {/* plot */}
        <rect x="42%" y="12%" width="48%" height="38%" fill="none" stroke={fg} strokeWidth="1" strokeDasharray="3,3"/>
        {/* chargers icons */}
        {[0,1,2,3].map(i => (
          <g key={i}>
            <rect x={`${50 + i*9}%`} y="22%" width="14" height="22" rx="2" fill={fg} opacity="0.7"/>
            <circle cx={`${50 + i*9 + 1.4}%`} cy="60%" r="3" fill={fg} opacity="0.6"/>
          </g>
        ))}
        {/* compass */}
        <text x="6%" y="20%" fontFamily="var(--font-mono)" fontSize="10" fill={fg} opacity="0.5">N</text>
        <text x="6%" y="92%" fontFamily="var(--font-mono)" fontSize="10" fill={fg} opacity="0.5">PROYECTO</text>
      </>
    );
  } else if (t.startsWith('prod')) {
    // Product wireframe — DC charger silhouette
    body = (
      <>
        <rect x="38%" y="15%" width="24%" height="70%" rx="6" fill="none" stroke={fg} strokeWidth="1.2"/>
        <rect x="42%" y="22%" width="16%" height="14%" fill="none" stroke={fg} strokeWidth="0.8" opacity="0.5"/>
        <line x1="42%" y1="42%" x2="58%" y2="42%" stroke={fg} strokeWidth="0.5" opacity="0.4"/>
        <line x1="42%" y1="48%" x2="58%" y2="48%" stroke={fg} strokeWidth="0.5" opacity="0.4"/>
        <line x1="42%" y1="54%" x2="58%" y2="54%" stroke={fg} strokeWidth="0.5" opacity="0.4"/>
        <circle cx="46%" cy="74%" r="6" fill="none" stroke={fg} strokeWidth="0.8"/>
        <circle cx="54%" cy="74%" r="6" fill="none" stroke={fg} strokeWidth="0.8"/>
        {/* dimension lines */}
        <line x1="32%" y1="15%" x2="32%" y2="85%" stroke={fg} strokeWidth="0.5" opacity="0.4"/>
        <text x="6%" y="92%" fontFamily="var(--font-mono)" fontSize="10" fill={fg} opacity="0.5">PRODUCTO</text>
      </>
    );
  } else {
    // Network / org pattern
    body = (
      <>
        {/* central */}
        <circle cx="50%" cy="50%" r="14" fill="none" stroke={fg} strokeWidth="1.2"/>
        <circle cx="50%" cy="50%" r="3" fill={fg}/>
        {/* satellites */}
        {[
          ['25%', '30%'], ['75%', '30%'], ['20%', '70%'], ['80%', '70%'], ['50%', '15%'], ['50%', '85%'],
        ].map(([x, y], i) => (
          <g key={i}>
            <line x1="50%" y1="50%" x2={x} y2={y} stroke={fg} strokeWidth="0.6" opacity="0.4"/>
            <circle cx={x} cy={y} r="6" fill={bg} stroke={fg} strokeWidth="0.8"/>
            <circle cx={x} cy={y} r="2" fill={fg} opacity="0.7"/>
          </g>
        ))}
        <text x="6%" y="92%" fontFamily="var(--font-mono)" fontSize="10" fill={fg} opacity="0.5">EMPRESA</text>
      </>
    );
  }
  return (
    <div style={{ position: 'relative', height, overflow: 'hidden', borderRadius: 16, background: bg, border: `1px solid ${dark ? 'var(--dark-line)' : 'var(--line)'}` }}>
      {/* grid background */}
      <svg viewBox="0 0 200 120" preserveAspectRatio="none" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
        <defs>
          <pattern id={`grid-${tag}-${dark ? 'd' : 'l'}`} width="10" height="10" patternUnits="userSpaceOnUse">
            <path d="M 10 0 L 0 0 0 10" fill="none" stroke={fgGrid} strokeWidth="0.3"/>
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill={`url(#grid-${tag}-${dark ? 'd' : 'l'})`}/>
      </svg>
      <svg viewBox="0 0 100 100" preserveAspectRatio="none" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
        {body}
      </svg>
    </div>
  );
}

Object.assign(window, { useInView, Reveal, SplitText, CountUp, useParallax, BlueprintTile });
