"use client";

import React, { useRef, useEffect, useState } from 'react'
import Experience from './components/Experience'
import ScrollRig from './components/ScrollRig'
import Navbar from './components/ui/Navbar'
import FirstMile from './components/sections/FirstMile'
import MidMile from './components/sections/MidMile'
import LastMile from './components/sections/LastMile'
import Analytics from './components/sections/Analytics'
import { useSceneStore } from './store/useSceneStore'
import './styles/experience.css'

import Lenis from 'lenis'
import gsap from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'

gsap.registerPlugin(ScrollTrigger)

/**
 * Experience3D
 * ---------------------------------------------------------------------------
 * The full scroll-driven 3D logistics story, ported from the standalone Vite
 * app's App.jsx and embedded as the body of the How It Works page (below the
 * existing Elementor hero, above the global Footer).
 *
 * Two integration changes vs. the standalone app:
 *  1. Self-managed fixed pin. The site has a fixed header and an ancestor with
 *     `overflow:hidden`, both of which break CSS `position: sticky`. So this is
 *     a tall `position:relative` section (`.dm-hiw-3d`, its height supplied by
 *     the 900vh ScrollRig spacer) with an absolutely-positioned `.dm-hiw-3d-stage`
 *     toggled absolute(top) → fixed → absolute(bottom) via the ScrollTrigger pin
 *     state — the same approach the site's other 3D sections use (StrategySection).
 *  2. The global Lenis is disabled on `/how-it-works` (SmoothScroll.tsx) so the
 *     experience runs its own tuned Lenis here without a second instance fighting
 *     it. The internal "Scroll to start" Hero overlay is dropped because the page
 *     keeps the Elementor HowItWorksHero above this section.
 */
export default function Experience3D() {
  const scrollProgress = useSceneStore((state) => state.scrollProgress)
  const setLenis = useSceneStore((state) => state.setLenis)

  const containerRef = useRef(null)
  const [pinState, setPinState] = useState('before')
  // Defer mounting the WebGL Canvas until the section nears the viewport. This
  // mirrors the site's other 3D sections (StrategySection's `mountScene`): besides
  // saving the heavy 32MB scene until needed, it keeps the Canvas out of React
  // StrictMode's initial synchronous double-mount, which otherwise creates and
  // immediately loses the WebGL context in dev ("THREE.WebGLRenderer: Context Lost"),
  // leaving a blank canvas. Once mounted it stays mounted.
  const [mountScene, setMountScene] = useState(false)

  useEffect(() => {
    const el = containerRef.current
    if (!el) return
    const io = new IntersectionObserver(
      (entries) => {
        if (entries.some((e) => e.isIntersecting)) {
          setMountScene(true)
          io.disconnect()
        }
      },
      { rootMargin: '200% 0px' }, // mount well before it scrolls into view
    )
    io.observe(el)
    return () => io.disconnect()
  }, [])

  // Own Lenis instance (global Lenis is gated off for this route).
  useEffect(() => {
    const lenis = new Lenis({
      duration: 1.2,
      lerp: 0.08,
      syncTouch: true,
    })

    setLenis(lenis)
    lenis.on('scroll', ScrollTrigger.update)

    let rafId
    function raf(time) {
      lenis.raf(time)
      rafId = requestAnimationFrame(raf)
    }
    rafId = requestAnimationFrame(raf)

    gsap.ticker.lagSmoothing(0)
    ScrollTrigger.refresh()

    return () => {
      cancelAnimationFrame(rafId)
      lenis.destroy()
      setLenis(null)
    }
  }, [setLenis])

  // 3D references shared between R3F and the GSAP scroll system.
  const truckRef = useRef(null)

  const wheelRefs = React.useMemo(() => [
    { current: null }, // FR
    { current: null }, // FL
    { current: null }, // RL
    { current: null }, // RR
  ], [])

  const dashboardRefs = React.useMemo(() => ({
    bars: [
      { current: null }, { current: null }, { current: null },
      { current: null }, { current: null }, { current: null }
    ],
    floorBars: [
      { current: null }, { current: null }, { current: null },
      { current: null }, { current: null }
    ],
    pieQuarters: [
      { current: null }, { current: null }, { current: null }, { current: null }
    ]
  }), [])

  return (
    <div ref={containerRef} className={`dm-hiw-3d is-${pinState}`}>
      {/* Pinned stage: canvas + HTML overlays. Stays fixed across the scroll. */}
      <div className="dm-hiw-3d-stage">
        <div
          className="canvas-wrapper"
          style={{
            opacity: scrollProgress >= 0.92 ? 0.85 : 1.0,
            transition: 'opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1)',
          }}
        >
          {mountScene && (
            <Experience
              truckRef={truckRef}
              wheelRefs={wheelRefs}
              dashboardRefs={dashboardRefs}
            />
          )}
        </div>

        {/* In-experience section navigation */}
        <Navbar />

        {/* Story stage text panels (revealed at their scroll ranges) */}
        <div className="sections-overlay-container">
          <FirstMile active={scrollProgress >= 0.02 && scrollProgress < 0.14} />
          <MidMile active={scrollProgress >= 0.38 && scrollProgress < 0.50} />
          <LastMile active={scrollProgress >= 0.80 && scrollProgress < 0.92} />
          <Analytics active={scrollProgress >= 0.94} />
        </div>
      </div>

      {/* GSAP scroll system: 900vh in-flow spacer that gives the section its
          height, drives scroll progress, and reports pin state. */}
      <ScrollRig dashboardRefs={dashboardRefs} onPinState={setPinState} />
    </div>
  )
}
