/* eslint-disable */
// Shared helpers: theme, motion utils, icons, magnetic, tilt, reveal, orbs, grid
const { useState, useEffect, useRef, useLayoutEffect, useCallback, useMemo } = React;

/* ===============  THEME  =============== */
function useTheme() {
  const [theme, setTheme] = useState(() => {
    try { return localStorage.getItem('seo.theme') || 'dark'; } catch { return 'dark'; }
  });
  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    try { localStorage.setItem('seo.theme', theme); } catch {}
  }, [theme]);
  return [theme, setTheme];
}

function ThemeToggle({ theme, setTheme }) {
  const on = theme === 'dark';
  return (
    <button
      className="btn btn-ghost btn-sm theme-toggle"
      onClick={() => setTheme(on ? 'light' : 'dark')}
      aria-label="toggle theme"
      style={{ padding: 8, width: 36, height: 36, borderRadius: 999 }}
    >
      <span style={{ display:'grid', placeItems:'center', width:18, height:18, position:'relative' }}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
             style={{ position:'absolute', transition:'opacity .3s, transform .4s', opacity: on?1:0, transform: on?'rotate(0) scale(1)':'rotate(90deg) scale(0.6)'}}>
          <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
        </svg>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
             style={{ position:'absolute', transition:'opacity .3s, transform .4s', opacity: on?0:1, transform: on?'rotate(-90deg) scale(0.6)':'rotate(0) scale(1)'}}>
          <circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
        </svg>
      </span>
    </button>
  );
}

/* ===============  ICONS (hand-tuned Lucide-style)  =============== */
const Icon = ({ name, size=16, stroke=2, ...p }) => {
  const s = { width:size, height:size, stroke:'currentColor', fill:'none', strokeWidth:stroke, strokeLinecap:'round', strokeLinejoin:'round', ...p };
  const paths = {
    search:       <><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></>,
    trending:     <><path d="M3 17l6-6 4 4 8-8"/><path d="M21 7h-5v5"/></>,
    layers:       <><path d="m12 2 9 5-9 5-9-5 9-5z"/><path d="m3 12 9 5 9-5"/><path d="m3 17 9 5 9-5"/></>,
    sparkle:      <><path d="M12 3v18M3 12h18M6 6l12 12M18 6 6 18"/></>,
    bolt:         <><path d="M13 2 3 14h7l-1 8 10-12h-7l1-8z"/></>,
    target:       <><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></>,
    chart:        <><path d="M3 3v18h18"/><path d="M7 14l4-4 4 4 6-6"/></>,
    grid:         <><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></>,
    user:         <><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></>,
    settings:     <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33h0a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51h0a1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82v0a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></>,
    folder:       <><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z"/></>,
    list:         <><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></>,
    zap:          <><path d="M13 2 3 14h7l-1 8 10-12h-7l1-8z"/></>,
    globe:        <><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></>,
    key:          <><circle cx="7" cy="15" r="4"/><path d="m10.5 11.5 10-10M17 5l3 3"/></>,
    calendar:     <><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 9h18M8 3v4M16 3v4"/></>,
    wallet:       <><path d="M3 7v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2H5a2 2 0 0 1 0-4h12"/><circle cx="17" cy="14" r="1.5"/></>,
    users:        <><circle cx="9" cy="8" r="4"/><path d="M2 21a7 7 0 0 1 14 0"/><path d="M16 3.13a4 4 0 0 1 0 7.75M22 21a7 7 0 0 0-5-6.71"/></>,
    plus:         <><path d="M12 5v14M5 12h14"/></>,
    check:        <><path d="M4 12l5 5L20 6"/></>,
    arrow:        <><path d="M5 12h14M13 6l6 6-6 6"/></>,
    chevron:      <><path d="m9 6 6 6-6 6"/></>,
    chevronDown:  <><path d="m6 9 6 6 6-6"/></>,
    close:        <><path d="M6 6l12 12M18 6 6 18"/></>,
    play:         <><path d="M6 4l14 8-14 8V4z"/></>,
    menu:         <><path d="M3 6h18M3 12h18M3 18h18"/></>,
    clock:        <><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></>,
    bell:         <><path d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13 21a2 2 0 0 1-2 0"/></>,
    eye:          <><path d="M2 12s3.5-8 10-8 10 8 10 8-3.5 8-10 8S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></>,
    link:         <><path d="M10 14a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1"/><path d="M14 10a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1"/></>,
    upload:       <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/></>,
    download:     <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></>,
    filter:       <><path d="M3 5h18M6 12h12M10 19h4"/></>,
    copy:         <><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></>,
    external:     <><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><path d="M15 3h6v6M10 14 21 3"/></>,
    robot:        <><rect x="3" y="8" width="18" height="12" rx="2"/><circle cx="9" cy="14" r="1"/><circle cx="15" cy="14" r="1"/><path d="M12 8V4M10 4h4"/></>,
    flame:        <><path d="M12 2s5 5 5 10a5 5 0 0 1-10 0c0-2 1-3 1-3s-1-2 1-4 3-3 3-3z"/></>,
    ai:           <><path d="M12 3v4M5 7l2.5 2.5M19 7l-2.5 2.5M12 17v4M5 17l2.5-2.5M19 17l-2.5-2.5"/><circle cx="12" cy="12" r="4"/></>,
    book:         <><path d="M4 3h10a4 4 0 0 1 4 4v14H8a4 4 0 0 1-4-4V3z"/><path d="M4 17a4 4 0 0 1 4-4h10"/></>,
    tool:         <><path d="M14.7 6.3a4 4 0 1 0 5 5L21 13l-7 7-9-9 7-7 1.7 1.3z"/></>,
    dashboard:    <><path d="M3 13h8V3H3zM13 21h8V11h-8zM3 21h8v-6H3zM13 9h8V3h-8z"/></>,
    star:         <><path d="m12 2 3 7 7 .5-5.5 5 2 7-6.5-4-6.5 4 2-7L2 9.5 9 9l3-7z"/></>,
    shield:       <><path d="M12 2 4 6v6c0 5 3.5 9 8 10 4.5-1 8-5 8-10V6l-8-4z"/></>,
    paw:          <><circle cx="6" cy="10" r="2"/><circle cx="18" cy="10" r="2"/><circle cx="9" cy="5" r="2"/><circle cx="15" cy="5" r="2"/><path d="M8 15a4 4 0 0 1 8 0c0 2-1 5-4 5s-4-3-4-5z"/></>,
    logo:         <><path d="M4 14c6 0 6-8 16-8"/><path d="M4 18c8 0 8-10 16-10"/><circle cx="6" cy="14" r="2" fill="currentColor"/></>,
    code:         <><path d="m8 6-6 6 6 6M16 6l6 6-6 6M14 4l-4 16"/></>,
    alert:        <><path d="M12 2 1 22h22L12 2z"/><path d="M12 10v5M12 18h.01"/></>,
    monitor:      <><rect x="2" y="4" width="20" height="13" rx="2"/><path d="M8 21h8M12 17v4"/></>,
    phone:        <><rect x="6" y="2" width="12" height="20" rx="2"/><path d="M11 18h2"/></>,
    x:            <><path d="M6 6l12 12M18 6 6 18"/></>,
  };
  return <svg viewBox="0 0 24 24" style={{flex:'none'}} {...s}>{paths[name] || null}</svg>;
};

/* ===============  MOTION: magnetic, tilt, reveal, typewriter, counter =============== */
function useMagnetic(strength = 24) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    let raf;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const x = e.clientX - (r.left + r.width/2);
      const y = e.clientY - (r.top + r.height/2);
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        el.style.transform = `translate(${x/strength}px, ${y/strength}px)`;
      });
    };
    const onLeave = () => { el.style.transform = ''; };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => { el.removeEventListener('mousemove', onMove); el.removeEventListener('mouseleave', onLeave); cancelAnimationFrame(raf); };
  }, [strength]);
  return ref;
}

function useTilt(max = 10) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const px = (e.clientX - r.left) / r.width - 0.5;
      const py = (e.clientY - r.top) / r.height - 0.5;
      el.style.transform = `perspective(800px) rotateX(${-py*max}deg) rotateY(${px*max}deg) translateZ(0)`;
      el.style.setProperty('--mx', `${(e.clientX - r.left)}px`);
      el.style.setProperty('--my', `${(e.clientY - r.top)}px`);
    };
    const onLeave = () => { el.style.transform = ''; };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => { el.removeEventListener('mousemove', onMove); el.removeEventListener('mouseleave', onLeave); };
  }, [max]);
  return ref;
}

function useReveal() {
  useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.15 });
    document.querySelectorAll('[data-reveal]').forEach(el => io.observe(el));
    return () => io.disconnect();
  });
}

function Typewriter({ phrases, speed = 50, hold = 1500 }) {
  const [text, setText] = useState('');
  const [i, setI] = useState(0);
  const [dir, setDir] = useState(1); // 1 typing, -1 deleting
  useEffect(() => {
    const target = phrases[i % phrases.length];
    let t;
    if (dir === 1) {
      if (text.length < target.length) t = setTimeout(() => setText(target.slice(0, text.length+1)), speed);
      else t = setTimeout(() => setDir(-1), hold);
    } else {
      if (text.length > 0) t = setTimeout(() => setText(target.slice(0, text.length-1)), speed/2);
      else { setDir(1); setI(i+1); }
    }
    return () => clearTimeout(t);
  }, [text, dir, i, phrases, speed, hold]);
  return <span>{text}<span className="tw-caret">│</span></span>;
}

function Counter({ to, duration=1400, suffix='', fmt }) {
  const [n, setN] = useState(0);
  const ref = useRef(null);
  const started = useRef(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting && !started.current) {
        started.current = true;
        const t0 = performance.now();
        const tick = (now) => {
          const p = Math.min(1, (now - t0) / duration);
          const eased = 1 - Math.pow(1-p, 3);
          setN(to * eased);
          if (p < 1) requestAnimationFrame(tick);
        };
        requestAnimationFrame(tick);
      }
    }, { threshold: 0.4 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  const v = fmt ? fmt(n) : Math.round(n).toLocaleString('ru-RU');
  return <span ref={ref}>{v}{suffix}</span>;
}

/* ===============  BACKGROUND LAYERS  =============== */
function Orbs({ variant='hero' }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const x = (e.clientX - r.left - r.width/2) / r.width;
      const y = (e.clientY - r.top - r.height/2) / r.height;
      el.style.setProperty('--px', x);
      el.style.setProperty('--py', y);
    };
    window.addEventListener('mousemove', onMove);
    return () => window.removeEventListener('mousemove', onMove);
  }, []);
  const sets = {
    hero: [
      { color:'var(--g-tertiary)', size:520, top:'-10%', left:'-8%', opacity:0.55, speed:40 },
      { color:'var(--g-primary)',  size:620, top:'30%',  left:'55%', opacity:0.45, speed:-55 },
      { color:'var(--g-deep)',     size:440, top:'60%',  left:'15%', opacity:0.5,  speed:30 },
      { color:'var(--g-secondary)',size:380, top:'5%',   left:'70%', opacity:0.5,  speed:-35 },
    ],
    sub: [
      { color:'var(--g-primary)',  size:420, top:'10%',  left:'70%', opacity:0.25, speed:30 },
      { color:'var(--g-tertiary)', size:360, top:'60%',  left:'-5%', opacity:0.25, speed:-30 },
    ]
  };
  return (
    <div ref={ref} className="orbs-wrap" style={{ position:'absolute', inset:0, zIndex:0, overflow:'hidden', pointerEvents:'none' }}>
      {sets[variant].map((o, idx) => (
        <div key={idx} className="orb" style={{
          width:o.size, height:o.size,
          top:o.top, left:o.left,
          background: `radial-gradient(circle, ${o.color}, transparent 65%)`,
          opacity:o.opacity,
          transform:`translate(calc(var(--px, 0) * ${o.speed}px), calc(var(--py, 0) * ${o.speed}px))`,
          transition:'transform .6s var(--ease)',
          animation:`orbFloat ${14+idx*2}s ease-in-out infinite alternate`,
        }}/>
      ))}
    </div>
  );
}

function ReactiveGrid() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      el.style.setProperty('--mx', `${e.clientX - r.left}px`);
      el.style.setProperty('--my', `${e.clientY - r.top}px`);
    };
    window.addEventListener('mousemove', onMove);
    return () => window.removeEventListener('mousemove', onMove);
  }, []);
  return (
    <div ref={ref} className="reactive-grid" style={{
      position:'absolute', inset:0, zIndex:0, pointerEvents:'none',
      backgroundImage: `
        radial-gradient(circle 280px at var(--mx, 50%) var(--my, 50%), var(--grid-line-hot), transparent 70%),
        linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
        linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px)
      `,
      backgroundSize: '100% 100%, 56px 56px, 56px 56px',
      maskImage: 'radial-gradient(ellipse at center, black 40%, transparent 80%)',
      WebkitMaskImage: 'radial-gradient(ellipse at center, black 40%, transparent 80%)',
    }}/>
  );
}

/* ===============  MAGNETIC BUTTON WRAPPER  =============== */
function Magnetic({ children, strength=24, className='', ...rest }) {
  const ref = useMagnetic(strength);
  return <span ref={ref} className={`magnetic ${className}`} {...rest} style={{display:'inline-flex', transition:'transform .35s var(--ease)'}}>{children}</span>;
}

/* expose */
Object.assign(window, {
  useTheme, ThemeToggle, Icon,
  useMagnetic, useTilt, useReveal, Typewriter, Counter,
  Orbs, ReactiveGrid, Magnetic,
});
