"use client";

import { useEffect, useRef, Suspense, useSyncExternalStore, Component, type ReactNode } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { useGLTF } from "@react-three/drei";
import * as THREE from "three";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

const BASKETBALL_GLTF_PATH = "/models/basketball.glb";
const HOOP_GLTF_PATH = "/models/hoop.glb";

// Preload models for immediate rendering
useGLTF.preload(BASKETBALL_GLTF_PATH);
useGLTF.preload(HOOP_GLTF_PATH);

// Error boundary to gracefully degrade if WebGL or assets fail
class SceneErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean }> {
  constructor(props: { children: ReactNode }) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: unknown) {
    console.warn("BasketballScene 3D render caught an error:", error);
  }

  render() {
    if (this.state.hasError) {
      return null;
    }
    return this.props.children;
  }
}

// 3D Basketball Model loading real GLTF asset via useGLTF
function BasketballModel({ ballRef }: { ballRef: React.RefObject<THREE.Group | null> }) {
  const { scene } = useGLTF(BASKETBALL_GLTF_PATH);
  return (
    <group ref={ballRef} position={[2.2, 2.5, 0.5]} scale={[1.1, 1.1, 1.1]}>
      <primitive object={scene} />
    </group>
  );
}

// 3D Basketball Hoop Model loading real GLTF asset via useGLTF
function HoopModel({ hoopRef }: { hoopRef: React.RefObject<THREE.Group | null> }) {
  const { scene } = useGLTF(HOOP_GLTF_PATH);
  return (
    <group
      ref={hoopRef}
      position={[2.2, -2.6, 0.2]}
      scale={[1.2, 1.2, 1.2]}
      rotation={[Math.PI / 16, -Math.PI / 12, 0]}
    >
      <primitive object={scene} />
    </group>
  );
}

// Internal R3F Scene Content with local studio lighting & GSAP ScrollTrigger Integration
function SceneContent() {
  const ballRef = useRef<THREE.Group>(null);
  const hoopRef = useRef<THREE.Group>(null);

  // Subtle idle spin physics
  useFrame((_, delta) => {
    if (ballRef.current) {
      ballRef.current.rotation.x += delta * 0.4;
      ballRef.current.rotation.y += delta * 0.6;
    }
    if (hoopRef.current) {
      hoopRef.current.rotation.y = Math.sin(Date.now() * 0.001) * 0.04;
    }
  });

  useEffect(() => {
    if (typeof window === "undefined") return;

    gsap.registerPlugin(ScrollTrigger);

    const ball = ballRef.current;
    if (!ball) return;

    // GSAP ScrollTrigger timeline driving basketball position and spin across page sections
    const tl = gsap.timeline({
      scrollTrigger: {
        trigger: "body",
        start: "top top",
        end: "bottom bottom",
        scrub: 1.2, // Smooth inertia
      },
    });

    // Milestone 1 (Hero -> About Section): Arc down to left side
    tl.to(ball.position, {
      x: -2.2,
      y: 0.2,
      z: 0.5,
      duration: 1,
      ease: "power1.inOut",
    });

    // Milestone 2 (About -> FAQ Section): Curve into the hoop rim near FAQ section
    tl.to(ball.position, {
      x: 2.2,
      y: -2.6, // Enters hoop center near FAQ section
      z: 0.2,
      duration: 1.2,
      ease: "bounce.out",
    });

    // Ball spin directly tied to page scroll
    tl.to(
      ball.rotation,
      {
        x: Math.PI * 4,
        y: Math.PI * 6,
        z: Math.PI * 2,
        duration: 2.2,
        ease: "none",
      },
      0
    );

    return () => {
      ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
    };
  }, []);

  return (
    <>
      {/* Self-contained studio lighting rig without external CDN HDR download dependencies */}
      <ambientLight intensity={1.2} />
      <hemisphereLight args={["#ffffff", "#0D1B2A", 0.7]} />
      <directionalLight position={[10, 15, 10]} intensity={2.4} castShadow />
      <directionalLight position={[-10, 10, -5]} intensity={1.0} color="#ef7d00" />
      <directionalLight position={[0, 10, -10]} intensity={1.1} color="#38bdf8" />
      <pointLight position={[0, -2, 4]} intensity={1.6} color="#ef7d00" />

      <Suspense fallback={null}>
        <BasketballModel ballRef={ballRef} />
        <HoopModel hoopRef={hoopRef} />
      </Suspense>
    </>
  );
}

const emptySubscribe = () => () => {};
function useIsClient() {
  return useSyncExternalStore(
    emptySubscribe,
    () => true,
    () => false
  );
}

// React Three Fiber Container Component
export default function BasketballScene() {
  const mounted = useIsClient();

  if (!mounted) return null;

  return (
    <SceneErrorBoundary>
      <div
        id="r3f-canvas-container"
        className="fixed inset-0 z-10 pointer-events-none w-full h-full opacity-100"
      >
        <Canvas
          camera={{ position: [0, 0, 9], fov: 50 }}
          gl={{ alpha: true, antialias: true, powerPreference: "high-performance" }}
        >
          <SceneContent />
        </Canvas>
      </div>
    </SceneErrorBoundary>
  );
}

