'use client'

import { useEffect, useRef } from 'react'
import * as THREE from 'three'

export function ThreeBackground() {
  const canvasRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!canvasRef.current) return

    let animationId: number
    let cleanup: (() => void) | null = null

    // Dynamically import Three.js
    import('three').then((THREE) => {
      const container = canvasRef.current!
      const scene = new THREE.Scene()

      // Use THREE.Timer instead of deprecated THREE.Clock
      const timer = new (THREE as any).Timer()

      const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      )
      const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true })

      renderer.setSize(window.innerWidth, window.innerHeight)
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
      container.appendChild(renderer.domElement)

      // Create particles (matching template: 1500 count, spread 50, size 0.05)
      const particlesGeometry = new THREE.BufferGeometry()
      const particlesCount = 1500
      const posArray = new Float32Array(particlesCount * 3)
      const colorsArray = new Float32Array(particlesCount * 3)

      for (let i = 0; i < particlesCount * 3; i += 3) {
        posArray[i] = (Math.random() - 0.5) * 50
        posArray[i + 1] = (Math.random() - 0.5) * 50
        posArray[i + 2] = (Math.random() - 0.5) * 50

        // Template particle colors: R: 0.4-0.8, G: 0.2-0.5, B: 0.8-1.0
        colorsArray[i] = 0.4 + Math.random() * 0.4
        colorsArray[i + 1] = 0.2 + Math.random() * 0.3
        colorsArray[i + 2] = 0.8 + Math.random() * 0.2
      }

      particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3))
      particlesGeometry.setAttribute('color', new THREE.BufferAttribute(colorsArray, 3))

      const particlesMaterial = new THREE.PointsMaterial({
        size: 0.05,
        vertexColors: true,
        transparent: true,
        opacity: 0.8,
        blending: THREE.AdditiveBlending,
      })

      const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial)
      scene.add(particlesMesh)

      // Create floating geometric shapes (matching template: 15 shapes, spread 40)
      const geometries = [
        new THREE.IcosahedronGeometry(1, 0),
        new THREE.OctahedronGeometry(1, 0),
        new THREE.TetrahedronGeometry(1, 0),
      ]

      const shapes: THREE.Mesh[] = []
      const shapeCount = 15

      for (let i = 0; i < shapeCount; i++) {
        const geometry = geometries[Math.floor(Math.random() * geometries.length)]
        // Template: HSL hue 0.6-0.8, saturation 0.7, lightness 0.5
        const material = new THREE.MeshBasicMaterial({
          color: new THREE.Color().setHSL(0.6 + Math.random() * 0.2, 0.7, 0.5),
          wireframe: true,
          transparent: true,
          opacity: 0.3,
        })

        const mesh = new THREE.Mesh(geometry, material)
        mesh.position.set(
          (Math.random() - 0.5) * 40,
          (Math.random() - 0.5) * 40,
          (Math.random() - 0.5) * 40
        )
        mesh.rotation.set(
          Math.random() * Math.PI,
          Math.random() * Math.PI,
          0
        )

        mesh.userData = {
          rotationSpeed: {
            x: (Math.random() - 0.5) * 0.01,
            y: (Math.random() - 0.5) * 0.01,
            z: (Math.random() - 0.5) * 0.01,
          },
          floatSpeed: Math.random() * 0.02 + 0.01,
          floatOffset: Math.random() * Math.PI * 2,
        }

        shapes.push(mesh)
        scene.add(mesh)
      }

      // Connection lines between nearby shapes (matching template)
      const lineMaterial = new THREE.LineBasicMaterial({
        color: 0x667eea,
        transparent: true,
        opacity: 0.08,
      })

      const lineGeometry = new THREE.BufferGeometry()
      const linePositions = new Float32Array(shapeCount * shapeCount * 6)
      lineGeometry.setAttribute('position', new THREE.BufferAttribute(linePositions, 3))
      const connectionLines = new THREE.LineSegments(lineGeometry, lineMaterial)
      scene.add(connectionLines)

      camera.position.z = 30

      // Mouse interaction
      let mouseX = 0
      let mouseY = 0
      let touchX: number | null = null
      let touchY: number | null = null

      const windowHalfX = window.innerWidth / 2
      const windowHalfY = window.innerHeight / 2

      const handleMouseMove = (event: MouseEvent) => {
        mouseX = (event.clientX - windowHalfX) / 100
        mouseY = (event.clientY - windowHalfY) / 100
      }

      // Touch interaction for mobile (matching template design)
      const handleTouchMove = (event: TouchEvent) => {
        if (event.touches.length > 0) {
          const touch = event.touches[0]
          touchX = (touch.clientX - windowHalfX) / 100
          touchY = (touch.clientY - windowHalfY) / 100
        }
      }

      const handleTouchEnd = () => {
        touchX = null
        touchY = null
      }

      document.addEventListener('mousemove', handleMouseMove)
      document.addEventListener('touchmove', handleTouchMove, { passive: true })
      document.addEventListener('touchend', handleTouchEnd)

      // Animation loop using THREE.Timer (not deprecated Clock)
      function animate() {
        animationId = requestAnimationFrame(animate)

        // Get delta from Timer
        const delta = timer.getDelta()
        const time = timer.elapsedTime

        // Use touch if available, else mouse
        const targetX = touchX !== null ? touchX : mouseX
        const targetY = touchY !== null ? touchY : mouseY

        // Template: camera lerp factor 0.05, sensitivity 2
        camera.position.x += (targetX * 2 - camera.position.x) * 0.05
        camera.position.y += (-targetY * 2 - camera.position.y) * 0.05
        camera.lookAt(scene.position)

        // Template: rotation Y speed 0.05, X speed 0.02
        particlesMesh.rotation.y += delta * 0.05
        particlesMesh.rotation.x += delta * 0.02

        shapes.forEach((shape) => {
          shape.rotation.x += shape.userData.rotationSpeed.x
          shape.rotation.y += shape.userData.rotationSpeed.y
          shape.rotation.z += shape.userData.rotationSpeed.z
          // Template: float amplitude 0.02
          shape.position.y += Math.sin(
            time * shape.userData.floatSpeed + shape.userData.floatOffset
          ) * 0.02
        })

        // Update connection lines between nearby shapes
        const positions = connectionLines.geometry.attributes.position.array as Float32Array
        let lineIndex = 0
        const connectionDistance = 15

        for (let i = 0; i < shapes.length; i++) {
          for (let j = i + 1; j < shapes.length; j++) {
            const dist = shapes[i].position.distanceTo(shapes[j].position)
            if (dist < connectionDistance) {
              positions[lineIndex++] = shapes[i].position.x
              positions[lineIndex++] = shapes[i].position.y
              positions[lineIndex++] = shapes[i].position.z
              positions[lineIndex++] = shapes[j].position.x
              positions[lineIndex++] = shapes[j].position.y
              positions[lineIndex++] = shapes[j].position.z
            }
          }
        }

        // Zero out unused positions
        for (let i = lineIndex; i < positions.length; i++) {
          positions[i] = 0
        }
        connectionLines.geometry.attributes.position.needsUpdate = true

        // Particle wave animation (matching template: wave speed 0.5, amplitude 0.02, frequency 0.1)
        const particlePositions = particlesGeometry.attributes.position.array as Float32Array
        for (let i = 0; i < particlesCount * 3; i += 3) {
          particlePositions[i + 1] += Math.sin(time * 0.5 + particlePositions[i] * 0.1) * 0.02
        }
        particlesGeometry.attributes.position.needsUpdate = true

        renderer.render(scene, camera)
      }

      animate()

      // Handle resize
      const handleResize = () => {
        camera.aspect = window.innerWidth / window.innerHeight
        camera.updateProjectionMatrix()
        renderer.setSize(window.innerWidth, window.innerHeight)
      }

      window.addEventListener('resize', handleResize)

      // Cleanup function
      cleanup = () => {
        document.removeEventListener('mousemove', handleMouseMove)
        document.removeEventListener('touchmove', handleTouchMove)
        document.removeEventListener('touchend', handleTouchEnd)
        window.removeEventListener('resize', handleResize)
        cancelAnimationFrame(animationId)
        if (container.contains(renderer.domElement)) {
          container.removeChild(renderer.domElement)
        }
        renderer.dispose()
        particlesGeometry.dispose()
        particlesMaterial.dispose()
        shapes.forEach((shape) => {
          shape.geometry.dispose()
          ;(shape.material as THREE.Material).dispose()
        })
        lineGeometry.dispose()
        lineMaterial.dispose()
      }
    })

    return () => {
      cleanup?.()
    }
  }, [])

  return (
    <div
      ref={canvasRef}
      className="fixed inset-0 z-[-1]"
      style={{
        background: 'radial-gradient(circle at center, #1a1a2e 0%, #0a0a0a 100%)',
      }}
    />
  )
}
