'use client';

import { Suspense, useMemo, useRef } from 'react';
import { Canvas, useFrame, useLoader, useThree } from '@react-three/fiber';
import {
  Float,
  ContactShadows,
  Environment,
  Lightformer,
  Sparkles,
  Html,
  useProgress,
} from '@react-three/drei';
import * as THREE from 'three';
import { OBJLoader } from 'three-stdlib';

useLoader.preload(OBJLoader, '/aerox.obj');
useLoader.preload(THREE.TextureLoader, '/jaiben.png');

const ACCENT = '#00bc84';
const ACCENT_BRIGHT = '#10b981';

function Loader() {
  const { progress } = useProgress();
  return (
    <Html center>
      <div className="flex flex-col items-center gap-3">
        <div className="w-12 h-12 border-4 border-emerald-500/30 border-t-emerald-500 rounded-full animate-spin" />
        <p className="text-emerald-400 text-sm font-semibold">{Math.round(progress)}%</p>
      </div>
    </Html>
  );
}

function AeroxModel() {
  const obj = useLoader(OBJLoader, '/uploads_files_3634924_uploads_files_850048_aerox.obj');
  useLoader.preload(OBJLoader, '/uploads_files_3634924_uploads_files_850048_aerox.obj');
  const group = useRef<THREE.Group>(null);

  const model = useMemo(() => {
    const clone = obj.clone(true);
    // Center + reorient + scale. OBJ length is along Z; rotate so length lies along X.
    const box = new THREE.Box3().setFromObject(clone);
    const size = new THREE.Vector3();
    box.getSize(size);
    const center = new THREE.Vector3();
    box.getCenter(center);
    const maxDim = Math.max(size.x, size.y, size.z);
    const scale = 3.2 / maxDim;

    clone.position.sub(center.multiplyScalar(scale));
    clone.scale.setScalar(scale);
    // Lay the scooter along X and stand it upright (Y up).
    clone.rotation.y = -Math.PI / 2;
    clone.rotation.z = 0;

    // Apply a cohesive, premium material across all meshes.
    const bodyMat = new THREE.MeshStandardMaterial({
      color: ACCENT,
      roughness: 0.2,
      metalness: 0.7,
    });
    const accentMat = new THREE.MeshStandardMaterial({
      color: '#e2e8f0',
      roughness: 0.1,
      metalness: 0.9,
    });
    const tireMat = new THREE.MeshStandardMaterial({
      color: '#111111',
      roughness: 0.9,
      metalness: 0.1,
    });

    clone.traverse((child) => {
      if (child instanceof THREE.Mesh) {
        child.castShadow = true;
        child.receiveShadow = true;
        // Heuristic: pick material by geometry size.
        const b = new THREE.Box3().setFromObject(child);
        const s = new THREE.Vector3();
        b.getSize(s);
        const maxLocal = Math.max(s.x, s.y, s.z);
        if (maxLocal < 0.35) child.material = accentMat;
        else if (s.y < 0.25 && maxLocal > 0.5) child.material = tireMat;
        else child.material = bodyMat;
      }
    });
    return clone;
  }, [obj]);

  const { size } = useThree();
  const isMobile = size.width < 1024;
  const targetX = isMobile ? 0 : 2.5;

  useFrame((state) => {
    if (!group.current) return;
    const t = state.clock.elapsedTime;
    // Continuous turntable so all sides are appreciated.
    group.current.rotation.y = t * 0.4;
    group.current.position.y = Math.sin(t * 1.5) * 0.08;
    
    // Smoothly animate position X to be responsive
    group.current.position.x += (targetX - group.current.position.x) * 0.1;
  });

  return (
    <Float speed={1.2} rotationIntensity={0.1} floatIntensity={0.3}>
      <group ref={group} rotation={[0, -0.5, 0]} position={[isMobile ? 0 : 2.5, -0.1, -1]}>
        <primitive object={model} />
      </group>
    </Float>
  );
}

function Battery({ position, scale = 1, rotation = [0, 0, 0] }: { position: [number, number, number]; scale?: number; rotation?: [number, number, number] }) {
  const group = useRef<THREE.Group>(null);
  const logoTexture = useLoader(THREE.TextureLoader, '/jaiben.png');

  useFrame((state, delta) => {
    if (group.current) {
      group.current.rotation.y += delta * 0.4;
      group.current.position.y = position[1] + Math.sin(state.clock.elapsedTime + position[0]) * 0.2;
    }
  });

  return (
    <Float speed={2} rotationIntensity={0.5} floatIntensity={1}>
      <group ref={group} position={position} scale={scale} rotation={new THREE.Euler(...rotation)}>
        {/* Main Battery Body */}
        <mesh position={[0, 0, 0]} castShadow receiveShadow>
          <boxGeometry args={[0.6, 1.2, 0.4]} />
          <meshStandardMaterial color="#1e293b" roughness={0.4} metalness={0.8} />
        </mesh>

        {/* Top Cap */}
        <mesh position={[0, 0.65, 0]} castShadow receiveShadow>
          <boxGeometry args={[0.62, 0.1, 0.42]} />
          <meshStandardMaterial color={ACCENT} roughness={0.3} metalness={0.5} />
        </mesh>

        {/* Handle */}
        <mesh position={[0, 0.70, 0]} castShadow receiveShadow>
          <torusGeometry args={[0.15, 0.04, 16, 32, Math.PI]} />
          <meshStandardMaterial color="#0d7a33" roughness={0.2} metalness={0.9} />
        </mesh>

        {/* Glowing Indicator Light */}
        <mesh position={[0.2, 0.5, 0.201]}>
          <circleGeometry args={[0.03, 16]} />
          <meshBasicMaterial color={ACCENT_BRIGHT} />
        </mesh>

        {/* Logo Decal Plane */}
        <mesh position={[0, 0, 0.201]}>
          <planeGeometry args={[0.35, 0.35]} />
          <meshBasicMaterial map={logoTexture} transparent={true} />
        </mesh>

        {/* Back Logo Decal Plane */}
        <mesh position={[0, 0, -0.201]} rotation={[0, Math.PI, 0]}>
          <planeGeometry args={[0.35, 0.35]} />
          <meshBasicMaterial map={logoTexture} transparent={true} />
        </mesh>
      </group>
    </Float>
  );
}

function Floor() {
  return (
    <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -1.1, 0]} receiveShadow>
      <circleGeometry args={[9, 64]} />
      <meshStandardMaterial color="#0f172a" roughness={0.6} metalness={0.2} transparent opacity={0.4} />
    </mesh>
  );
}

function Scene() {
  return (
    <>
      <ambientLight intensity={0.4} />
      <directionalLight position={[6, 8, 5]} intensity={1.4} color="#f8fafc" castShadow />
      <directionalLight position={[-8, -4, -6]} intensity={0.6} color={ACCENT_BRIGHT} />
      <pointLight position={[0, 3, 4]} intensity={0.8} color={ACCENT_BRIGHT} />
      <spotLight position={[0, 10, 0]} angle={0.5} intensity={1.2} color="#ffffff" penumbra={1} />

      <Suspense fallback={<Loader />}>
        <AeroxModel />
        <Battery position={[-3.8, 1.6, -1]} scale={1.1} />
        <Battery position={[3.8, 1.2, -0.5]} scale={0.8} rotation={[0.2, 0, 0]} />
        <Battery position={[3.4, -0.8, 0.6]} scale={0.6} rotation={[-0.2, 0.5, 0]} />
        <Battery position={[-4.0, -0.4, 0.8]} scale={0.7} rotation={[0, -0.5, 0.1]} />
      </Suspense>

      <Sparkles count={90} scale={[11, 7, 7]} size={3} speed={0.4} color={ACCENT_BRIGHT} opacity={0.7} />

      <ContactShadows position={[0, -1.06, 0]} opacity={0.55} scale={14} blur={2.5} far={4} color={ACCENT} />
      <Floor />

      <Environment resolution={256}>
        <Lightformer intensity={2} position={[0, 5, 5]} scale={[10, 5, 1]} color="#ffffff" />
        <Lightformer intensity={1.2} position={[-5, 2, 3]} scale={[8, 6, 1]} color={ACCENT_BRIGHT} />
        <Lightformer intensity={0.8} position={[5, 1, 3]} scale={[8, 6, 1]} color="#0ea5e9" />
        <Lightformer intensity={0.6} position={[0, -5, 2]} scale={[10, 5, 1]} color="#1e293b" />
      </Environment>
    </>
  );
}

function Rig({ children }: { children: React.ReactNode }) {
  useFrame((state) => {
    const { camera, pointer } = state;
    camera.position.x += (pointer.x * 1.4 - camera.position.x) * 0.04;
    camera.position.y += (-pointer.y * 0.7 + 0.4 - camera.position.y) * 0.04;
    camera.lookAt(0, 0, 0);
  });
  return <>{children}</>;
}

export default function HeroBackground3D() {
  return (
    <div className="absolute inset-0 z-0 overflow-hidden">
      <Canvas
        shadows
        dpr={[1, 2]}
        camera={{ position: [0, 0.4, 8], fov: 42 }}
        gl={{ antialias: true, alpha: true, powerPreference: 'high-performance' }}
        onCreated={({ gl }) => gl.setClearColor(0x000000, 0)}
      >
        <Rig>
          <Scene />
        </Rig>
      </Canvas>
      <div className="pointer-events-none absolute inset-0 bg-gradient-to-r from-slate-900/70 via-slate-900/20 to-transparent lg:from-slate-900/80 lg:via-slate-900/30 lg:to-transparent" />
    </div>
  );
}