/* ═══════════════ Closink Landing · APP (route spine + assembly + mount) ═══════════════ */

/* ════ ROUTE-THREAD SPINE — draws itself on scroll, threads the whole page ════ */
const RouteSpine = () => {
  const X = 70, AMP = 30, SEG = 240;
  const [h, setH] = useState(0);
  const [stops, setStops] = useState([]);
  const [activeY, setActiveY] = useState(0);
  const pathRef = useRef(null);
  const drawRef = useRef(null);
  const dotRef = useRef(null);
  const dotGlowRef = useRef(null);
  const lenRef = useRef(0);

  const measure = useCallback(() => {
    const page = document.getElementById('page');
    if (!page) return;
    setH(page.scrollHeight);
    const els = Array.from(document.querySelectorAll('[data-stop]'));
    setStops(els.map((e) => {
      const top = e.getBoundingClientRect().top + window.scrollY;
      return { y: Math.round(top + 90), n: e.getAttribute('data-stop'), label: e.getAttribute('data-stop-label') };
    }));
  }, []);

  useEffect(() => {
    measure();
    const ro = new ResizeObserver(measure);
    const page = document.getElementById('page');
    if (page) ro.observe(page);
    window.addEventListener('resize', measure);
    const timers = [setTimeout(measure, 400), setTimeout(measure, 1200), setTimeout(measure, 2400)];
    return () => { ro.disconnect(); window.removeEventListener('resize', measure); timers.forEach(clearTimeout); };
  }, [measure]);

  // build weaving path
  let d = `M ${X} 0`;
  let toggle = 1;
  for (let y = SEG; y <= h; y += SEG) {
    const cx = X + AMP * toggle;
    d += ` Q ${cx} ${y - SEG / 2} ${X} ${Math.min(y, h)}`;
    toggle *= -1;
  }

  const draw2Ref = useRef(null);
  useEffect(() => {
    if (!pathRef.current) return;
    const len = pathRef.current.getTotalLength();
    lenRef.current = len;
    [drawRef.current, draw2Ref.current].forEach((el) => {
      if (el) { el.style.strokeDasharray = len; el.style.strokeDashoffset = len; }
    });
  }, [d, h]);

  useEffect(() => {
    let raf = 0;
    const update = () => {
      raf = 0;
      const max = document.documentElement.scrollHeight - window.innerHeight;
      const p = max > 0 ? Math.min(1, Math.max(0, window.scrollY / max)) : 0;
      const len = lenRef.current;
      const off = len * (1 - p);
      if (drawRef.current && len) drawRef.current.style.strokeDashoffset = off;
      if (draw2Ref.current && len) draw2Ref.current.style.strokeDashoffset = off;
      if (pathRef.current && len) {
        const pt = pathRef.current.getPointAtLength(len * p);
        if (dotRef.current) dotRef.current.setAttribute('transform', `translate(${pt.x} ${pt.y})`);
        if (dotGlowRef.current) dotGlowRef.current.setAttribute('transform', `translate(${pt.x} ${pt.y})`);
      }
      setActiveY(window.scrollY + window.innerHeight * 0.5);
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); };
    update();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); if (raf) cancelAnimationFrame(raf); };
  }, [d, stops]);

  return (
    <div className="hidden lg:block absolute top-0 pointer-events-none" aria-hidden="true"
      style={{ height: h, width: 200, left: 'max(8px, calc((100vw - 1240px)/2 - 30px))', zIndex: 5 }}>
      <svg width="200" height={h} style={{ overflow: 'visible' }}>
        <defs>
          <linearGradient id="spineG" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor="#7DD3FC" /><stop offset="0.5" stopColor="#38BDF8" /><stop offset="1" stopColor="#3678F9" />
          </linearGradient>
          <filter id="spineGlow"><feGaussianBlur stdDeviation="5" /></filter>
        </defs>
        {/* faint full track (also the measurement path) */}
        <path ref={pathRef} d={d} fill="none" stroke="rgba(54,120,249,.14)" strokeWidth="2.5" strokeLinecap="round" />
        {/* glow under draw */}
        <path ref={drawRef} d={d} fill="none" stroke="url(#spineG)" strokeWidth="7" strokeLinecap="round" opacity="0.35" filter="url(#spineGlow)" />
        {/* bright draw */}
        <path ref={draw2Ref} d={d} fill="none" stroke="url(#spineG)" strokeWidth="2.5" strokeLinecap="round" />
        {/* stop pins */}
        {stops.map((s, i) => {
          const on = activeY >= s.y - 40;
          return (
            <g key={i} transform={`translate(${X} ${s.y})`} style={{ transition: 'opacity .4s' }}>
              <circle r="13" fill={on ? 'rgba(54,120,249,.16)' : 'rgba(54,120,249,.06)'} style={{ transition: 'all .4s' }} />
              <circle r="6" fill={on ? '#3678F9' : '#FFFFFF'} stroke={on ? '#7DD3FC' : 'rgba(54,120,249,.4)'} strokeWidth="2" style={{ transition: 'all .4s', filter: on ? 'drop-shadow(0 0 8px #38BDF8)' : 'none' }} />
              <text x="26" y="-2" fill={on ? '#1D4ED8' : '#94A3B8'} className="mono" style={{ fontSize: 10, fontWeight: 700, letterSpacing: '1px', transition: 'fill .4s' }}>{s.n}</text>
              <text x="26" y="12" fill={on ? '#0F172A' : '#94A3B8'} style={{ fontSize: 11, fontWeight: 600, transition: 'fill .4s' }}>{s.label}</text>
            </g>
          );
        })}
        {/* moving vehicle dot */}
        <g ref={dotGlowRef}><circle r="16" fill="#38BDF8" opacity="0.25" /></g>
        <g ref={dotRef}>
          <circle r="8" fill="#fff" stroke="rgba(15,23,42,.08)" strokeWidth="1" />
          <circle r="8" fill="none" stroke="#38BDF8" strokeWidth="2" />
          <circle r="3" fill="#3678F9" />
        </g>
      </svg>
    </div>
  );
};

/* ════ scroll progress bar ════ */
const Progress = () => {
  const ref = useRef(null);
  useEffect(() => {
    let raf = 0;
    const upd = () => {
      raf = 0;
      const max = document.documentElement.scrollHeight - window.innerHeight;
      const p = max > 0 ? window.scrollY / max : 0;
      if (ref.current) ref.current.style.transform = `scaleX(${p})`;
    };
    const on = () => { if (!raf) raf = requestAnimationFrame(upd); };
    upd(); window.addEventListener('scroll', on, { passive: true });
    return () => { window.removeEventListener('scroll', on); if (raf) cancelAnimationFrame(raf); };
  }, []);
  return (
    <div className="fixed top-0 left-0 right-0 z-[90]" style={{ height: 3, background: 'transparent' }}>
      <div ref={ref} style={{ height: '100%', transformOrigin: '0 50%', transform: 'scaleX(0)', background: 'linear-gradient(90deg,#7DD3FC,#3678F9,#7C5CFC)' }}></div>
    </div>
  );
};

/* ════ APP ════ */
const App = () => (
  <div id="page" className="relative">
    <Progress />
    <Navbar />
    <RouteSpine />
    <main>
      <Hero />
      <Marquee />
      <Problem />
      <Bento />
      <Cinematic />
      <SosSection />
      <Privacy />
      <Warmth />
      <HowItWorks />
      <Plans />
      <Trust />
      <FinalCta />
    </main>
    <Footer />
  </div>
);

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