/* =====================================================
   jenblat.com — Omar Jenblat personal site
   Built with React via CDN + in-browser Babel
   ===================================================== */

const { useState, useEffect, useRef, useMemo } = React;

// Detect if we're being served at /jenblat (preview) vs / (production apex).
const BASE = (() => {
  const p = window.location.pathname;
  return p.startsWith('/jenblat') ? '/jenblat' : '';
})();
const asset = (name) => `${BASE}/${name}`;
// Media (video/headshot) goes through /media/ route which bypasses the upstream cache.
const media = (name) => `${BASE}/media/${name}`;
const apiUrl = (name) => `${BASE}/api/${name}`;

// ──────────────────────────────────────────────────────────
// Hooks
// ──────────────────────────────────────────────────────────
function useScrollProgress() {
  const [p, setP] = useState(0);
  useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = h.scrollHeight - h.clientHeight;
      setP(max > 0 ? (h.scrollTop || window.scrollY) / max : 0);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return p;
}

function useInView(threshold = 0.15) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setSeen(true);
            obs.disconnect();
          }
        });
      },
      { threshold, rootMargin: '0px 0px -10% 0px' }
    );
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, [threshold]);
  return [ref, seen];
}

function useTypewriter(words, { typeSpeed = 80, deleteSpeed = 40, pause = 1700 } = {}) {
  const [text, setText] = useState('');
  const [wi, setWi] = useState(0);
  const [deleting, setDeleting] = useState(false);

  useEffect(() => {
    const word = words[wi % words.length];
    let t;
    if (!deleting && text === word) {
      t = setTimeout(() => setDeleting(true), pause);
    } else if (deleting && text === '') {
      setDeleting(false);
      setWi((i) => i + 1);
    } else {
      t = setTimeout(
        () => {
          setText((cur) =>
            deleting ? word.substring(0, cur.length - 1) : word.substring(0, cur.length + 1)
          );
        },
        deleting ? deleteSpeed : typeSpeed
      );
    }
    return () => clearTimeout(t);
  }, [text, deleting, wi, words, typeSpeed, deleteSpeed, pause]);

  return text;
}

function useCounter(target, { duration = 2000, start = false } = {}) {
  const [v, setV] = useState(0);
  useEffect(() => {
    if (!start) return;
    const startT = performance.now();
    let raf;
    const tick = (now) => {
      const t = Math.min(1, (now - startT) / duration);
      const eased = 1 - Math.pow(1 - t, 3);
      setV(target * eased);
      if (t < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [target, duration, start]);
  return v;
}

// ──────────────────────────────────────────────────────────
// Custom cursor
// ──────────────────────────────────────────────────────────
function Cursor() {
  const dotRef = useRef(null);
  const ringRef = useRef(null);
  const pos = useRef({ x: -100, y: -100 });
  const target = useRef({ x: -100, y: -100 });

  useEffect(() => {
    if (window.matchMedia('(max-width: 768px)').matches) return;
    const onMove = (e) => {
      target.current = { x: e.clientX, y: e.clientY };
      if (dotRef.current) {
        dotRef.current.style.transform = `translate(${e.clientX}px, ${e.clientY}px) translate(-50%, -50%)`;
      }
    };
    const onOver = (e) => {
      const t = e.target;
      const interactive = t.closest('a, button, input, textarea, .venture-card, .nav-link');
      if (dotRef.current) dotRef.current.classList.toggle('is-hover', !!interactive);
      if (ringRef.current) ringRef.current.classList.toggle('is-hover', !!interactive);
    };
    let raf;
    const animate = () => {
      pos.current.x += (target.current.x - pos.current.x) * 0.15;
      pos.current.y += (target.current.y - pos.current.y) * 0.15;
      if (ringRef.current) {
        ringRef.current.style.transform = `translate(${pos.current.x}px, ${pos.current.y}px) translate(-50%, -50%)`;
      }
      raf = requestAnimationFrame(animate);
    };
    raf = requestAnimationFrame(animate);
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseover', onOver);
    return () => {
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseover', onOver);
      cancelAnimationFrame(raf);
    };
  }, []);

  return (
    <>
      <div ref={dotRef} className="cursor-dot" />
      <div ref={ringRef} className="cursor-ring" />
    </>
  );
}

// ──────────────────────────────────────────────────────────
// Nav
// ──────────────────────────────────────────────────────────
function Nav() {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 60);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const go = (id) => (e) => {
    e.preventDefault();
    const el = document.getElementById(id);
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  return (
    <nav className={`nav ${scrolled ? 'is-scrolled' : ''}`}>
      <a href="#top" onClick={go('top')} className="nav-logo">
        <LogoMark />
      </a>
      <div className="nav-links">
        <a href="#about" onClick={go('about')} className="nav-link">About</a>
        <a href="#ventures" onClick={go('ventures')} className="nav-link">Ventures</a>
        <a href="#numbers" onClick={go('numbers')} className="nav-link">Impact</a>
        <a href="#contact" onClick={go('contact')} className="nav-link">Contact</a>
      </div>
    </nav>
  );
}

function LogoMark() {
  const [hasImg, setHasImg] = useState(true);
  return hasImg ? (
    <img
      src={asset('logo.png')}
      alt="Jenblat"
      onError={() => setHasImg(false)}
    />
  ) : (
    <span>
      <span className="accent">J</span>enblat
    </span>
  );
}

// ──────────────────────────────────────────────────────────
// Hero
// ──────────────────────────────────────────────────────────
function Hero() {
  const videoRef = useRef(null);
  const [videoOk, setVideoOk] = useState(true);
  const subtitle = useTypewriter(
    ['Serial Entrepreneur', 'Angel Investor', 'Founder', 'Bunny Dad', 'Coffee Addict'],
    { typeSpeed: 75, deleteSpeed: 35, pause: 1600 }
  );

  useEffect(() => {
    const onScroll = () => {
      if (!videoRef.current) return;
      const y = window.scrollY;
      if (y < window.innerHeight) {
        videoRef.current.style.transform = `translateY(${y * 0.25}px) scale(${1 + y * 0.0002})`;
      }
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // Kick the video into playing on mount — autoplay policy is satisfied because
  // it's muted+playsinline, but some browsers need an explicit .play() after
  // React mounts the element.
  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    const tryPlay = () => v.play().catch(() => {});
    tryPlay();
    const onCan = () => tryPlay();
    v.addEventListener('canplay', onCan);
    return () => v.removeEventListener('canplay', onCan);
  }, []);

  const goContact = (e) => {
    e.preventDefault();
    const el = document.getElementById('contact');
    if (el) el.scrollIntoView({ behavior: 'smooth' });
  };

  return (
    <section id="top" className="hero">
      {videoOk ? (
        <video
          ref={videoRef}
          className="hero-video"
          src={media('hero.mp4')}
          autoPlay
          muted
          loop
          playsInline
          preload="auto"
          onError={() => setVideoOk(false)}
        />
      ) : (
        <div className="hero-fallback" />
      )}
      <div className="hero-overlay" />
      <div className="hero-content">
        <div className="hero-eyebrow">OMAR JENBLAT · PROVIDENCE, RI</div>
        <h1 className="hero-name">Omar Jenblat</h1>
        <div className="hero-rule" />
        <div className="hero-sub">
          <span>{subtitle}</span>
          <span className="cursor-blink" />
        </div>
        <a href="#contact" onClick={goContact} className="btn-primary">
          <span>Let's Connect</span>
          <span className="arrow">→</span>
        </a>
      </div>
      <div className="hero-scroll-hint">Scroll</div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// About
// ──────────────────────────────────────────────────────────
function About() {
  const [ref, seen] = useInView();
  const [src, setSrc] = useState('omar-light.jpg');
  const tryNext = () => {
    if (src === 'omar-light.jpg') setSrc('omar-light.png');
    else if (src === 'omar-light.png') setSrc('omar-light.webp');
    else if (src === 'omar-light.webp') setSrc('omar-dark.jpg');
    else if (src === 'omar-dark.jpg') setSrc('omar-dark.png');
    else setSrc('');
  };

  return (
    <section id="about" className={`section about reveal ${seen ? 'is-visible' : ''}`} ref={ref}>
      <div className="about-photo">
        {src ? (
          <img
            src={media(src)}
            alt="Omar Jenblat"
            onError={tryNext}
            loading="lazy"
          />
        ) : (
          <div style={{
            position: 'absolute', inset: 0,
            background: 'linear-gradient(135deg, #161616, #0A0A0A)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: 'rgba(201,168,76,0.4)', fontFamily: 'var(--serif)',
            fontSize: '5rem', letterSpacing: '0.05em'
          }}>OJ</div>
        )}
        <div className="about-photo-frame" />
      </div>
      <div className="about-text">
        <div className="section-eyebrow">About</div>
        <h2 className="section-title">A simple man with <em>two decades</em> of building.</h2>
        <div className="section-rule" />
        <p>
          I'm a simple man who loves watching businesses grow and drinking unhealthy
          sums of coffee.
        </p>
        <p>
          I help companies of all sizes see real growth through digital technology
          — and I've been doing it for nearly two decades.
        </p>
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// Ventures
// ──────────────────────────────────────────────────────────
const VENTURES = [
  { name: 'BusySeed',     desc: 'Award-winning digital marketing agency.',           href: 'https://busyseed.com' },
  { name: 'Rankxa',       desc: 'GEO/AEO optimization for the AI search era.',       href: 'https://rankxa.com' },
  { name: 'LeadChaser',   desc: 'AI-powered lead generation tool.',                   href: 'https://leadchaser.ai' },
  { name: 'Growth Squads',desc: 'Scalable growth teams for modern businesses.',       href: 'https://growth-squads.com' },
  { name: 'Zeed Agency',  desc: 'Performance-driven digital advertising.',            href: 'https://zeedagency.com' },
];

function VentureCard({ v, i }) {
  const ref = useRef(null);
  const onMove = (e) => {
    const card = ref.current;
    if (!card) return;
    const r = card.getBoundingClientRect();
    const x = e.clientX - r.left;
    const y = e.clientY - r.top;
    const cx = r.width / 2;
    const cy = r.height / 2;
    const rx = ((y - cy) / cy) * -6;
    const ry = ((x - cx) / cx) * 6;
    card.style.transform = `perspective(900px) rotateX(${rx}deg) rotateY(${ry}deg) translateZ(0)`;
    card.style.setProperty('--mx', x + 'px');
    card.style.setProperty('--my', y + 'px');
  };
  const onLeave = () => {
    if (ref.current) ref.current.style.transform = 'perspective(900px) rotateX(0) rotateY(0)';
  };
  return (
    <a
      ref={ref}
      href={v.href}
      target="_blank"
      rel="noopener noreferrer"
      className="venture-card"
      onMouseMove={onMove}
      onMouseLeave={onLeave}
    >
      <div>
        <div className="venture-num">0{i + 1}</div>
        <h3 className="venture-name">{v.name}</h3>
        <p className="venture-desc">{v.desc}</p>
      </div>
      <div className="venture-arrow">↗</div>
    </a>
  );
}

function Ventures() {
  const [ref, seen] = useInView();
  return (
    <section id="ventures" className={`section reveal ${seen ? 'is-visible' : ''}`} ref={ref}>
      <div className="section-eyebrow">Ventures</div>
      <h2 className="section-title">Building <em>across</em> the stack.</h2>
      <div className="section-rule" />
      <div className="ventures-grid">
        {VENTURES.map((v, i) => <VentureCard v={v} i={i} key={v.name} />)}
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// Numbers
// ──────────────────────────────────────────────────────────
function NumberBlock({ value, suffix, prefix = '', label, start }) {
  const v = useCounter(value, { start, duration: 2200 });
  const display = value >= 100 ? Math.floor(v) : v.toFixed(0);
  return (
    <div className="number-block">
      <span className="number-value">{prefix}{display.toLocaleString()}{suffix}</span>
      <div className="number-label">{label}</div>
    </div>
  );
}

function Numbers() {
  const [ref, seen] = useInView(0.3);
  return (
    <section id="numbers" className="numbers" ref={ref}>
      <div className={`numbers-inner reveal ${seen ? 'is-visible' : ''}`}>
        <div className="section-eyebrow" style={{ textAlign: 'center' }}>By the Numbers</div>
        <h2 className="section-title" style={{ textAlign: 'center' }}>
          Real impact, <em>measured</em>.
        </h2>
        <div className="numbers-grid">
          <NumberBlock value={6}   suffix="+" label="Ventures Founded"      start={seen} />
          <NumberBlock value={700} suffix="+" label="Businesses Worked With" start={seen} />
          <NumberBlock value={18}  suffix="+" label="Years in the Industry" start={seen} />
          <NumberBlock value={540} suffix="M+" prefix="$" label="Generated for Clients" start={seen} />
        </div>
      </div>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// Contact
// ──────────────────────────────────────────────────────────
function Contact() {
  const [ref, seen] = useInView();
  const [form, setForm] = useState({ name: '', email: '', message: '' });
  const [status, setStatus] = useState({ state: 'idle', msg: '' });

  const onChange = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));

  const onSubmit = async (e) => {
    e.preventDefault();
    if (!form.name || !form.email || !form.message) {
      setStatus({ state: 'error', msg: 'Please fill in all fields.' });
      return;
    }
    setStatus({ state: 'loading', msg: 'Sending…' });
    try {
      const r = await fetch(apiUrl('contact'), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(form),
      });
      const data = await r.json();
      if (r.ok && data.ok) {
        setStatus({ state: 'success', msg: "Got it. I'll be in touch soon." });
        setForm({ name: '', email: '', message: '' });
      } else {
        setStatus({ state: 'error', msg: data.error || 'Something went wrong. Please try again.' });
      }
    } catch (err) {
      setStatus({ state: 'error', msg: 'Network error. Please try again.' });
    }
  };

  return (
    <section id="contact" className={`section contact reveal ${seen ? 'is-visible' : ''}`} ref={ref}>
      <div className="contact-text">
        <div className="section-eyebrow">Contact</div>
        <h2 className="section-title">Let's Build <em>Something</em>.</h2>
        <div className="section-rule" />
        <p>
          Whether you're looking to grow your business, explore a partnership,
          or just want to talk — I'm always open to a conversation.
        </p>
      </div>
      <form className="contact-form" onSubmit={onSubmit} noValidate>
        <div className="field">
          <label>Name</label>
          <input type="text" value={form.name} onChange={onChange('name')} required autoComplete="name" />
        </div>
        <div className="field">
          <label>Email</label>
          <input type="email" value={form.email} onChange={onChange('email')} required autoComplete="email" />
        </div>
        <div className="field">
          <label>Message</label>
          <textarea value={form.message} onChange={onChange('message')} required rows={4} />
        </div>
        <button type="submit" className="btn-primary" disabled={status.state === 'loading'}>
          <span>{status.state === 'loading' ? 'Sending…' : 'Send Message'}</span>
          <span className="arrow">→</span>
        </button>
        {status.state === 'success' && <div className="form-status success">{status.msg}</div>}
        {status.state === 'error' && <div className="form-status error">{status.msg}</div>}
      </form>
    </section>
  );
}

// ──────────────────────────────────────────────────────────
// Footer
// ──────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer className="footer">
      <div className="footer-meta">© {new Date().getFullYear()} Omar Jenblat · Providence, Rhode Island</div>
      <div className="footer-links">
        <a href="https://www.linkedin.com/in/omarjenblat/" target="_blank" rel="noopener noreferrer">LinkedIn</a>
        <a href="mailto:omar@jenblat.com">omar@jenblat.com</a>
      </div>
    </footer>
  );
}

// ──────────────────────────────────────────────────────────
// App shell
// ──────────────────────────────────────────────────────────
function App() {
  const p = useScrollProgress();
  return (
    <>
      <Cursor />
      <div className="scroll-progress" style={{ width: (p * 100) + '%' }} />
      <Nav />
      <Hero />
      <About />
      <Ventures />
      <Numbers />
      <Contact />
      <Footer />
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
