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

/* ──────────────────────────────────────────
   Cursor (dot + ring, hover zoom + labels)
   ────────────────────────────────────────── */
function Cursor() {
  const dot = useRef(null);
  const ring = useRef(null);
  const lbl = useRef(null);
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    let rx = 0, ry = 0, x = 0, y = 0;
    const onMove = (e) => {
      x = e.clientX; y = e.clientY;
      if (!visible) setVisible(true);
      if (dot.current) dot.current.style.transform = `translate(${x}px, ${y}px) translate(-50%,-50%)`;
    };
    let raf;
    const loop = () => {
      rx += (x - rx) * 0.18; ry += (y - ry) * 0.18;
      if (ring.current) ring.current.style.transform = `translate(${rx}px, ${ry}px) translate(-50%,-50%)`;
      if (lbl.current)  lbl.current.style.transform  = `translate(${rx}px, ${ry - 48}px) translate(-50%,-50%)`;
      raf = requestAnimationFrame(loop);
    };
    loop();

    const handleOver = (e) => {
      const t = e.target;
      if (!t || !t.closest) return;
      const interactive = t.closest("a, button, .lab-tile, .p-card, .discipline-card, .contact-method, input, textarea, [data-hover]");
      if (interactive) {
        dot.current?.classList.add("hover");
        ring.current?.classList.add("hover");
        const label = interactive.getAttribute("data-hover");
        if (label && lbl.current) { lbl.current.textContent = label; lbl.current.classList.add("show"); }
      }
      // Zoom-on-hover for text/images
      const zoomable = t.closest("p, h1, h2, h3, h4, h5, .p-title, .h1, .h2, .h3, .thesis-statement, .contact-statement, .footer .big, .journal-entry .title, img, video, .cover, .thumb, .lab-tile, .discipline-card");
      if (zoomable && !zoomable.classList.contains("zoom-lock")) {
        zoomable.classList.add("zoomable");
        if (zoomable.matches("img, video, .cover, .thumb")) zoomable.classList.add("center-origin");
        zoomable.classList.add("zoomable-hover");
      }
    };
    const handleOut = (e) => {
      const t = e.target;
      if (!t || !t.closest) return;
      const interactive = t.closest("a, button, .lab-tile, .p-card, .discipline-card, .contact-method, input, textarea, [data-hover]");
      if (interactive) {
        dot.current?.classList.remove("hover");
        ring.current?.classList.remove("hover");
        if (lbl.current) lbl.current.classList.remove("show");
      }
      const zoomable = t.closest(".zoomable-hover");
      if (zoomable) zoomable.classList.remove("zoomable-hover");
    };

    window.addEventListener("mousemove", onMove);
    document.addEventListener("mouseover", handleOver);
    document.addEventListener("mouseout", handleOut);
    return () => {
      window.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseover", handleOver);
      document.removeEventListener("mouseout", handleOut);
      cancelAnimationFrame(raf);
    };
  }, [visible]);

  return (
    <React.Fragment>
      <div ref={dot} className="cursor-dot" style={{opacity: visible ? 1 : 0}} />
      <div ref={ring} className="cursor-ring" style={{opacity: visible ? 1 : 0}} />
      <div ref={lbl} className="cursor-text" />
    </React.Fragment>
  );
}

/* ──────────────────────────────────────────
   Nav
   ────────────────────────────────────────── */
function Nav({ availability = "Currently exploring" }) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 80);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <nav className={`nav ${scrolled ? "scrolled" : ""}`}>
      <div className="nav-inner">
        <a href="#top" className="logo zoom-lock" data-hover="Home">
          <span className="bk">[</span>RM<span className="bk">]</span>
        </a>
        <span className="wip-banner" aria-label="Work in progress">
          <span className="wip-dot" />
          Live draft · still being built
        </span>
        <div className="nav-links">
          <a href="#work">Work</a>
          <a href="#about">About</a>
          <a href="#journal">Journal</a>
          <a href="#cv">CV</a>
        </div>
        <div className="nav-right">
          <span className="availability">
            <span className="dot" />
            <span className="avl-text">{availability}</span>
          </span>
          <a href="#contact" className="btn btn-accent" data-hover="Say hi">Contact →</a>
        </div>
      </div>
    </nav>
  );
}

/* ──────────────────────────────────────────
   Reveal-on-scroll wrapper
   ────────────────────────────────────────── */
function Reveal({ children, delay = 0, className = "", as = "div" }) {
  const ref = useRef(null);
  const [inView, setInView] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setInView(true); obs.disconnect(); }
    }, { threshold: 0.12 });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);
  const Tag = as;
  const delayCls = delay ? `d${delay}` : "";
  return (
    <Tag ref={ref} className={`reveal ${inView ? "in" : ""} ${delayCls} ${className}`}>
      {children}
    </Tag>
  );
}

/* ──────────────────────────────────────────
   Project cover placeholder — procedural SVG per discipline
   ────────────────────────────────────────── */
function ProjectCover({ project }) {
  const d = window.DISCIPLINES[project.discipline];
  const accent = d.accent;
  if (project.cover === "careconnect") {
    return (
      <svg className="cover-svg" viewBox="0 0 800 500" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
        <defs>
          <linearGradient id="cc-bg" x1="0" y1="0" x2="1" y2="1">
            <stop offset="0%" stopColor="#14141C"/><stop offset="100%" stopColor="#0A0A0F"/>
          </linearGradient>
        </defs>
        <rect width="800" height="500" fill="url(#cc-bg)"/>
        {[...Array(24)].map((_,i)=>(
          <circle key={i} cx={60 + (i%6)*130} cy={80 + Math.floor(i/6)*110} r={24 + (i%3)*8}
            fill="none" stroke={accent} strokeOpacity={0.18 + (i%4)*0.1} strokeWidth="1"/>
        ))}
        <g transform="translate(400,250)">
          <circle r="110" fill="none" stroke={accent} strokeOpacity="0.8"/>
          <circle r="70"  fill="none" stroke={accent} strokeOpacity="0.5"/>
          <circle r="30"  fill={accent} fillOpacity="0.9"/>
        </g>
        <text x="40" y="470" fontFamily="JetBrains Mono, monospace" fontSize="11" fill="#8A8A94" letterSpacing="2">// HEALTH • CALD • WCAG 2.1</text>
      </svg>
    );
  }
  if (project.cover === "success-ladder") {
    return (
      <svg className="cover-svg" viewBox="0 0 800 500" preserveAspectRatio="xMidYMid slice">
        <rect width="800" height="500" fill="#14141C"/>
        {[...Array(7)].map((_,i)=>{
          const y = 460 - i*55;
          const w = 140 + i*60;
          return <g key={i}>
            <rect x={80} y={y} width={w} height="36" fill="none" stroke={accent} strokeOpacity={0.3 + i*0.1} strokeWidth="1"/>
            <rect x={80} y={y} width={w * (0.2 + i*0.12)} height="36" fill={accent} fillOpacity={0.15 + i*0.08}/>
            <text x={92} y={y+23} fontFamily="JetBrains Mono, monospace" fontSize="10" fill="#E8E8F0" letterSpacing="1.5">RUNG {String(i+1).padStart(2,'0')}</text>
          </g>
        })}
        <text x="80" y="40" fontFamily="Fraunces, serif" fontSize="20" fill="#E8E8F0" fontWeight="400">Module 4 — Self-narration</text>
        <text x="80" y="62" fontFamily="JetBrains Mono, monospace" fontSize="10" fill="#8A8A94" letterSpacing="1.5">// PROGRESS AS ARTIFACT, NOT METRIC</text>
      </svg>
    );
  }
  if (project.cover === "yasumo") {
    return (
      <svg className="cover-svg" viewBox="0 0 800 500" preserveAspectRatio="xMidYMid slice">
        <rect width="800" height="500" fill="#14141C"/>
        <g transform="translate(400,260)">
          <rect x="-110" y="-90" width="220" height="180" rx="18" fill="none" stroke={accent} strokeOpacity="0.5"/>
          <rect x="-96" y="-76" width="192" height="130" fill="#0A0A0F" stroke={accent} strokeOpacity="0.3"/>
          {/* pixel pet */}
          {[[0,0],[1,0],[2,0],[-1,0],[-2,0],[0,-1],[1,-1],[-1,-1],[2,-2],[-2,-2],[3,1],[-3,1],[0,2],[1,2],[-1,2]].map(([x,y],i)=>
            <rect key={i} x={x*10 - 4} y={y*10 - 4} width="10" height="10" fill={accent} fillOpacity="0.85"/>
          )}
          <circle cx="-18" cy="-12" r="3" fill="#0A0A0F"/>
          <circle cx="18" cy="-12" r="3" fill="#0A0A0F"/>
          <text x="0" y="74" textAnchor="middle" fontFamily="JetBrains Mono, monospace" fontSize="10" fill="#8A8A94" letterSpacing="2">MOOD: CONTENT</text>
        </g>
        <text x="40" y="40" fontFamily="JetBrains Mono, monospace" fontSize="11" fill="#8A8A94" letterSpacing="2">// YASUMO.APP</text>
      </svg>
    );
  }
  if (project.cover === "vivid") {
    return (
      <svg className="cover-svg" viewBox="0 0 800 500" preserveAspectRatio="xMidYMid slice">
        <rect width="800" height="500" fill="#14141C"/>
        {/* map */}
        <g opacity="0.6">
          {[...Array(12)].map((_,i)=>(
            <line key={`h${i}`} x1="0" x2="560" y1={i*42} y2={i*42} stroke={accent} strokeOpacity="0.1"/>
          ))}
          {[...Array(14)].map((_,i)=>(
            <line key={`v${i}`} y1="0" y2="500" x1={i*42} x2={i*42} stroke={accent} strokeOpacity="0.1"/>
          ))}
        </g>
        <path d="M 40 380 Q 180 200 340 260 T 520 120" stroke={accent} strokeWidth="2" fill="none" strokeDasharray="4 4"/>
        {[[80,360],[220,240],[340,260],[420,180],[520,120]].map(([x,y],i)=>(
          <g key={i}>
            <circle cx={x} cy={y} r="12" fill="none" stroke={accent}/>
            <circle cx={x} cy={y} r="4" fill={accent}/>
          </g>
        ))}
        {/* chat panel */}
        <rect x="600" y="40" width="180" height="420" fill="#0A0A0F" stroke={accent} strokeOpacity="0.35"/>
        <rect x="616" y="64" width="120" height="22" fill={accent} fillOpacity="0.2"/>
        <rect x="616" y="96" width="140" height="22" fill={accent} fillOpacity="0.1"/>
        <rect x="616" y="128" width="96" height="22" fill={accent} fillOpacity="0.2"/>
        <text x="616" y="54" fontFamily="JetBrains Mono, monospace" fontSize="9" fill="#8A8A94" letterSpacing="1.5">VIVID · ONLINE</text>
      </svg>
    );
  }
  // chromatin / in-progress
  return (
    <svg className="cover-svg" viewBox="0 0 800 500" preserveAspectRatio="xMidYMid slice">
      <rect width="800" height="500" fill="#14141C"/>
      {[...Array(80)].map((_,i)=>{
        const a = (i/80) * Math.PI * 6;
        const r = 30 + i*2;
        const cx = 400 + Math.cos(a) * r;
        const cy = 250 + Math.sin(a) * r * 0.5;
        return <circle key={i} cx={cx} cy={cy} r={3 + (i%5)} fill={accent} fillOpacity={0.15 + (i%5)*0.08}/>
      })}
      <text x="40" y="40" fontFamily="JetBrains Mono, monospace" fontSize="11" fill="#8A8A94" letterSpacing="2">// CHROMATIN • HI-C • D3</text>
      <text x="40" y="470" fontFamily="JetBrains Mono, monospace" fontSize="10" fill="#555560" letterSpacing="2">SKETCH v0.3 — 2026.04.18</text>
    </svg>
  );
}

/* ──────────────────────────────────────────
   Footer
   ────────────────────────────────────────── */
function Footer() {
  const [secret, setSecret] = useState(false);
  return (
    <footer className="footer">
      <h2 className="big" onMouseEnter={() => setSecret(true)} onMouseLeave={() => setSecret(false)}>
        {secret ? <em>hello.</em> : "Raghu Mina"}
      </h2>
      <div className="footer-cols">
        <div>
          <h6>Sitemap</h6>
          <a href="#work">Work</a>
          <a href="#about">About</a>
          <a href="#journal">Journal</a>
          <a href="#cv">CV</a>
          <a href="#contact">Contact</a>
        </div>
        <div>
          <h6>Elsewhere</h6>
          <a href="https://www.linkedin.com/in/mina-r" target="_blank" rel="noreferrer">LinkedIn ↗</a>
          <a href="mailto:minaraghu1@gmail.com">Email ↗</a>
        </div>
        <div>
          <h6>Colophon</h6>
          <a href="#" onClick={e=>e.preventDefault()}>Type: Fraunces + General Sans</a>
          <a href="#" onClick={e=>e.preventDefault()}>Built with React + CSS grid</a>
          <a href="#" onClick={e=>e.preventDefault()}>Hosted on the open web</a>
        </div>
      </div>
      <div className="footer-meta">
        <span>© 2026 Raghu Mina. All work shown with permission.</span>
        <span>Last updated · Apr 24 2026</span>
        <span>Sydney, AU · UTC+11</span>
      </div>
    </footer>
  );
}

Object.assign(window, { Cursor, Nav, Reveal, ProjectCover, Footer });
