// Shared UI primitives: cursor, nav, reveal-on-scroll hook, section head.
const { useState, useEffect, useRef, useCallback } = React;

function useReveal() {
  useEffect(() => {
    // Run after paint so React children have all mounted.
    let io;
    const rafId = requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        const vh = window.innerHeight || 800;
        const addIn = (el) => {
          // double rAF to guarantee the initial opacity:0 paint committed before transitioning
          requestAnimationFrame(() => requestAnimationFrame(() => el.classList.add('in')));
        };
        if (!('IntersectionObserver' in window)) {
          document.querySelectorAll('.reveal').forEach(addIn);
          return;
        }
        io = new IntersectionObserver((entries) => {
          entries.forEach(e => {
            if (e.isIntersecting) {
              addIn(e.target);
              io.unobserve(e.target);
            }
          });
        }, { threshold: 0.08, rootMargin: '0px 0px -6% 0px' });
        document.querySelectorAll('.reveal').forEach(el => {
          const r = el.getBoundingClientRect();
          // Already on screen at mount? reveal immediately.
          if (r.top < vh * 0.94 && r.bottom > 0) {
            addIn(el);
          } else {
            io.observe(el);
          }
        });
      });
    });
    return () => {
      cancelAnimationFrame(rafId);
      if (io) io.disconnect();
    };
  }, []);
}

function CustomCursor() {
  const dotRef = useRef(null);
  const labelRef = useRef(null);
  useEffect(() => {
    const supportsHover = matchMedia('(hover: hover) and (pointer: fine)').matches;
    if (!supportsHover) return;
    document.body.classList.add('has-custom-cursor');
    let x = window.innerWidth / 2, y = window.innerHeight / 2;
    let tx = x, ty = y;
    const onMove = (e) => { tx = e.clientX; ty = e.clientY; };
    window.addEventListener('mousemove', onMove);

    const raf = () => {
      x += (tx - x) * 0.22;
      y += (ty - y) * 0.22;
      if (dotRef.current) {
        dotRef.current.style.transform = `translate(${x}px, ${y}px) translate(-50%, -50%)`;
      }
      if (labelRef.current) {
        labelRef.current.style.transform = `translate(${x}px, ${y}px) translate(-50%, -50%)`;
      }
      req = requestAnimationFrame(raf);
    };
    let req = requestAnimationFrame(raf);

    const onEnterHover = (e) => {
      const t = e.target.closest('[data-cursor]');
      if (!t) return;
      dotRef.current?.classList.add('hover');
      const lbl = t.getAttribute('data-cursor-label');
      if (lbl && labelRef.current) {
        labelRef.current.textContent = lbl;
        labelRef.current.classList.add('on');
      }
    };
    const onLeaveHover = (e) => {
      const t = e.target.closest?.('[data-cursor]');
      if (!t) return;
      dotRef.current?.classList.remove('hover');
      labelRef.current?.classList.remove('on');
    };
    document.addEventListener('mouseover', onEnterHover);
    document.addEventListener('mouseout', onLeaveHover);
    return () => {
      document.body.classList.remove('has-custom-cursor');
      window.removeEventListener('mousemove', onMove);
      cancelAnimationFrame(req);
      document.removeEventListener('mouseover', onEnterHover);
      document.removeEventListener('mouseout', onLeaveHover);
    };
  }, []);
  return (
    <>
      <div ref={dotRef} className="cursor-dot" />
      <div ref={labelRef} className="cursor-label" />
    </>
  );
}

function Nav({ lang, setLang, section }) {
  const links = CONTENT.nav[lang];
  const ids = ['top', 'projects', 'detail', 'studio', 'process', 'journal', 'contact'];
  // nav labels (6) match ids[1..6] + 'Index' -> 'top'
  const idFor = (label) => {
    const m = ['top', 'projects', 'studio', 'process', 'journal', 'contact'];
    const i = ['Index', 'Projects', 'Studio', 'Process', 'Journal', 'Contact'].indexOf(label);
    return m[i] || 'top';
  };
  return (
    <div className="nav">
      <a href="#top" className="nav-logo" data-cursor data-cursor-label="Top">
        <span className="mark"></span>
        KIRIMA<span style={{opacity: 0.55, marginLeft: 14, letterSpacing: '0.18em'}}>ARCHITECTS</span>
      </a>
      <div className="nav-links">
        {links.map(l => (
          <a key={l} href={`#${idFor(l)}`}
             className={section === idFor(l) ? 'is-active' : ''}
             data-cursor data-cursor-label={l}>{l}</a>
        ))}
      </div>
      <div className="nav-lang">
        <button className={lang === 'ja' ? 'on' : ''} onClick={() => setLang('ja')} data-cursor>JA</button>
        <span className="sep">/</span>
        <button className={lang === 'en' ? 'on' : ''} onClick={() => setLang('en')} data-cursor>EN</button>
      </div>
    </div>
  );
}

function SectionHead({ num, label, meta, className = '' }) {
  return (
    <div className={`edge section-head ${className}`}>
      <div>
        <div className="num reveal">— {num}</div>
        <div className="label reveal d1">{label}</div>
      </div>
      {meta && <div className="meta reveal d2">{meta}</div>}
    </div>
  );
}

Object.assign(window, { useReveal, CustomCursor, Nav, SectionHead });
