/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

// ====== ICONS ======
const Icon = {
  Python: () => (
    <svg viewBox="0 0 32 32" width="32" height="32">
      <defs>
        <linearGradient id="py-b" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0" stopColor="#00E676"/><stop offset="1" stopColor="#00D4FF"/>
        </linearGradient>
        <linearGradient id="py-y" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0" stopColor="#00FF88"/><stop offset="1" stopColor="#BF00FF"/>
        </linearGradient>
      </defs>
      <path fill="url(#py-b)" d="M15.9 2c-3 0-5.6.5-5.6 2.6v2.6h5.7v.7H8.2C6 7.9 4.1 9.4 4.1 12.5s1.6 4.7 3.8 4.7h2v-3c0-2.2 1.9-4 4-4h5.8c1.9 0 3.4-1.5 3.4-3.4V4.6C23.1 2.8 21.5 2 19.5 2 18 2 16.9 2 15.9 2zm-3 1.7c.6 0 1.1.5 1.1 1.1s-.5 1.1-1.1 1.1-1.1-.5-1.1-1.1.5-1.1 1.1-1.1z"/>
      <path fill="url(#py-y)" d="M23.7 8v2.8c0 2.3-1.9 4.1-4 4.1h-5.8c-1.9 0-3.4 1.6-3.4 3.4v6.4c0 1.8 1.6 2.9 3.4 3.4 2.2.6 4.2.7 6.3 0 1.7-.5 3.4-1.5 3.4-3.4V22h-5.7v-.7h8.5c1.7 0 2.6-1.2 3.4-3.4.8-2.2.8-4.4 0-6.7-.6-2.2-1.7-3.4-3.4-3.4h-2.7zm-3.2 14.9c.6 0 1.1.5 1.1 1.1s-.5 1.1-1.1 1.1-1.1-.5-1.1-1.1.5-1.1 1.1-1.1z"/>
    </svg>
  ),
  Django: () => (
    <svg viewBox="0 0 24 24" width="32" height="32" aria-label="Django">
      <path
        fill="#00FF88"
        d="M11.146 0h3.924v18.166c-2.013.382-3.491.535-5.096.535-4.791 0-7.288-2.166-7.288-6.32 0-4.002 2.65-6.6 6.753-6.6.637 0 1.121.05 1.707.203zm0 9.143a3.894 3.894 0 0 0-1.325-.204c-1.988 0-3.134 1.223-3.134 3.365 0 2.09 1.096 3.236 3.109 3.236.433 0 .79-.025 1.35-.102V9.143zM23.621 6.612v9.068c0 3.121-.229 4.62-.917 5.91-.637 1.224-1.477 1.988-3.211 2.854l-3.643-1.733c1.733-.815 2.575-1.529 3.109-2.625.561-1.121.739-2.421.739-5.834V6.612h3.923zM19.698.255h3.923v4.026h-3.923z"
      />
    </svg>
  ),
  JS: () => (
    <svg viewBox="0 0 32 32" width="32" height="32">
      <rect x="3" y="3" width="26" height="26" rx="4" fill="none" stroke="#00FF88" strokeWidth="1.5"/>
      <text x="16" y="23" textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontWeight="900" fontSize="13" fill="#00FF88">JS</text>
    </svg>
  ),
  Flutter: () => (
    <svg viewBox="0 0 32 32" width="32" height="32" fill="none" stroke="#00D4FF" strokeWidth="2" strokeLinejoin="round">
      <path d="M20 4 L8 16 L14 22 L26 10 Z"/>
      <path d="M14 22 L20 28 L26 22 L20 16 Z" fill="rgba(0,212,255,0.2)"/>
    </svg>
  ),
  Android: () => (
    <svg viewBox="0 0 32 32" width="32" height="32" fill="none" stroke="#00FF88" strokeWidth="1.8" strokeLinecap="round">
      <path d="M8 12c0-4 4-7 8-7s8 3 8 7" />
      <line x1="11" y1="8" x2="9" y2="5"/>
      <line x1="21" y1="8" x2="23" y2="5"/>
      <rect x="8" y="12" width="16" height="12" rx="2" fill="rgba(0,255,136,0.06)"/>
      <circle cx="12" cy="10" r="0.8" fill="#00FF88"/>
      <circle cx="20" cy="10" r="0.8" fill="#00FF88"/>
      <rect x="5" y="14" width="2" height="8" rx="1"/>
      <rect x="25" y="14" width="2" height="8" rx="1"/>
      <rect x="11" y="24" width="2" height="5" rx="1"/>
      <rect x="19" y="24" width="2" height="5" rx="1"/>
    </svg>
  ),
  Algo: () => (
    <svg viewBox="0 0 32 32" width="32" height="32" fill="none" stroke="#BF00FF" strokeWidth="1.8" strokeLinejoin="round">
      <circle cx="6" cy="8" r="2.5"/>
      <circle cx="26" cy="8" r="2.5"/>
      <circle cx="6" cy="24" r="2.5"/>
      <circle cx="26" cy="24" r="2.5"/>
      <circle cx="16" cy="16" r="3" fill="rgba(191,0,255,0.2)"/>
      <line x1="8.5" y1="8" x2="13" y2="14"/>
      <line x1="23.5" y1="8" x2="19" y2="14"/>
      <line x1="8.5" y1="24" x2="13" y2="18"/>
      <line x1="23.5" y1="24" x2="19" y2="18"/>
    </svg>
  ),
  Grad: () => (
    <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 3 L2 8 L12 13 L22 8 Z"/>
      <path d="M6 10v5c0 2 3 4 6 4s6-2 6-4v-5"/>
      <line x1="22" y1="8" x2="22" y2="14"/>
    </svg>
  ),
  Clock: () => (
    <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
      <circle cx="12" cy="12" r="9"/>
      <polyline points="12 7 12 12 16 14"/>
    </svg>
  ),
  Moon: () => (
    <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M20 14.5A8 8 0 1 1 9.5 4a7 7 0 0 0 10.5 10.5z"/>
    </svg>
  ),
  Arrow: () => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/>
    </svg>
  ),
  Menu: () => (
    <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
      <line x1="3" y1="7" x2="21" y2="7"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="17" x2="21" y2="17"/>
    </svg>
  ),
  Close: () => (
    <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
      <line x1="5" y1="5" x2="19" y2="19"/><line x1="19" y1="5" x2="5" y2="19"/>
    </svg>
  ),
  Pin: () => (
    <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.8">
      <path d="M12 21s-7-7-7-13a7 7 0 0114 0c0 6-7 13-7 13z"/>
      <circle cx="12" cy="8" r="2.5" fill="currentColor"/>
    </svg>
  ),
};

window.Icon = Icon;

// ====== REVEAL ======
function Reveal({ children, stagger = false, className = '', as: As = 'div', ...rest }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (entries) => entries.forEach(e => {
        if (e.isIntersecting) { el.classList.add('in'); io.disconnect(); }
      }),
      { threshold: 0.15 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return <As ref={ref} className={`${stagger ? 'reveal-stagger' : 'reveal'} ${className}`} {...rest}>{children}</As>;
}
window.Reveal = Reveal;

// ====== PARTICLES ======
function Particles({ count = 24 }) {
  const [items] = useState(() => {
    const syms = ['</>', '{}', '[]', '0x', '#', '//', '=>', '&&', '||', '::', '()', '<>'];
    return Array.from({ length: count }, (_, i) => ({
      id: i,
      sym: syms[Math.floor(Math.random() * syms.length)],
      left: Math.random() * 100,
      delay: Math.random() * 20,
      dur: 15 + Math.random() * 20,
      size: 10 + Math.random() * 10,
      color: ['', 'cyan', 'magenta'][Math.floor(Math.random() * 3)],
      top: 100 + Math.random() * 50,
    }));
  });
  return (
    <div className="particles">
      {items.map(p => (
        <span key={p.id} className={`particle ${p.color}`} style={{
          left: p.left + '%',
          top: p.top + '%',
          animationDuration: p.dur + 's',
          animationDelay: -p.delay + 's',
          fontSize: p.size + 'px',
        }}>{p.sym}</span>
      ))}
    </div>
  );
}
window.Particles = Particles;

// ====== TYPING ======
function Typing({ text, speed = 45 }) {
  const [out, setOut] = useState('');
  useEffect(() => {
    let i = 0;
    setOut('');
    const t = setInterval(() => {
      i++;
      setOut(text.slice(0, i));
      if (i >= text.length) clearInterval(t);
    }, speed);
    return () => clearInterval(t);
  }, [text, speed]);
  return <span>{out}</span>;
}
window.Typing = Typing;

// ====== MATRIX RAIN ======
function MatrixRain() {
  const CHARSET = '01{}[]</>#0xABCDEFabcdefKODAIFROADS+*=!?&';
  const COLS = 18;
  const LINES = 30;
  // hidden easter egg phrase — drops rarely, in a random column
  const SECRET = 'ACHEI O BRINDE';

  const randCh = () => CHARSET[Math.floor(Math.random() * CHARSET.length)];
  const randomColumnText = () => {
    let s = '';
    for (let j = 0; j < LINES; j++) s += randCh() + '\n';
    return s;
  };

  const [cols, setCols] = useState(() =>
    Array.from({ length: COLS }, (_, i) => ({
      id: i,
      left: (i / COLS) * 100,
      delay: Math.random() * 5,
      dur: 6 + Math.random() * 6,
      text: randomColumnText(),
      opacity: 0.2 + Math.random() * 0.5,
    }))
  );

  // Easter egg cycle — every 60-120s embed SECRET into a random column,
  // then restore the column to random chars after one animation cycle.
  useEffect(() => {
    let cancelled = false;
    let timer;

    const inject = () => {
      if (cancelled) return;
      const target = Math.floor(Math.random() * COLS);
      // letters of SECRET as a vertical sequence, padded by random chars
      const cleanLetters = SECRET.split('').map(ch => (ch === ' ' ? '·' : ch));
      const padTop = 5 + Math.floor(Math.random() * (LINES - cleanLetters.length - 6));
      let liveDur = 0;
      setCols(prev => prev.map((c, idx) => {
        if (idx !== target) return c;
        const lines = [];
        for (let j = 0; j < LINES; j++) {
          const k = j - padTop;
          lines.push(k >= 0 && k < cleanLetters.length ? cleanLetters[k] : randCh());
        }
        liveDur = c.dur;
        return { ...c, text: lines.join('\n') };
      }));
      // After one full fall, scramble the column back to noise
      setTimeout(() => {
        if (cancelled) return;
        setCols(prev => prev.map((c, idx) =>
          idx === target ? { ...c, text: randomColumnText() } : c
        ));
      }, (liveDur + 1) * 1000);
      // schedule next injection (60-120s)
      timer = setTimeout(inject, 60000 + Math.random() * 60000);
    };

    // first injection: 45-90s after mount (so it isn't visible immediately)
    timer = setTimeout(inject, 45000 + Math.random() * 45000);
    return () => { cancelled = true; clearTimeout(timer); };
  }, []);

  return (
    <div className="matrix-rain">
      {cols.map(c => (
        <div key={c.id} className="matrix-col" style={{
          left: c.left + '%',
          animationDuration: c.dur + 's',
          animationDelay: -c.delay + 's',
          opacity: c.opacity,
        }}>{c.text}</div>
      ))}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(180deg, rgba(5,10,14,0.8), transparent 30%, transparent 70%, rgba(5,10,14,0.8))',
        pointerEvents: 'none',
      }}/>
    </div>
  );
}
window.MatrixRain = MatrixRain;

Object.assign(window, { Icon, Reveal, Particles, Typing, MatrixRain });
