'use client'

import React, { useRef, useEffect, useState } from 'react'
import dynamic from 'next/dynamic'

interface HypercubeVisualizationProps {
  consciousnessStats?: {
    awareness: number
    wisdom: number
    compassion: number
    creativity: number
    transcendence: number
  }
}

function HypercubeVisualization({ consciousnessStats }: HypercubeVisualizationProps) {
  const mountRef = useRef<HTMLDivElement>(null)
  const sceneRef = useRef<any>()
  const rendererRef = useRef<any>()
  const cameraRef = useRef<any>()
  const hypercubeRef = useRef<any>()
  const tetrahedraRef = useRef<any>()
  const particlesRef = useRef<any>()
  const frameIdRef = useRef<number>()
  const [THREE, setTHREE] = useState<any>(null)

  const [animationSpeed, setAnimationSpeed] = useState(1)

  useEffect(() => {
    // Dynamically import THREE.js to prevent chunk loading issues
    const loadTHREE = async () => {
      try {
        const threeModule = await import('three')
        setTHREE(threeModule)
      } catch (error) {
        console.error('Failed to load THREE.js:', error)
      }
    }
    
    loadTHREE()
  }, [])

  useEffect(() => {
    if (!mountRef.current || !THREE) return

    // Scene setup
    const scene = new THREE.Scene()
    scene.background = new THREE.Color(0x1a1a2e)
    sceneRef.current = scene

    // Camera setup
    const camera = new THREE.PerspectiveCamera(75, 800 / 600, 0.1, 1000)
    camera.position.set(8, 6, 10)
    camera.lookAt(0, 0, 0)
    cameraRef.current = camera

    // Renderer setup
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
    renderer.setSize(800, 600)
    renderer.setClearColor(0x1a1a2e, 1)
    mountRef.current.appendChild(renderer.domElement)
    rendererRef.current = renderer

    // Create 5D Hypercube (32 vertices)
    const createHypercube = () => {
      const group = new THREE.Group()
      const vertices = []
      
      // Generate 32 vertices of 5D hypercube
      for (let a = 0; a < 2; a++) {
        for (let b = 0; b < 2; b++) {
          for (let c = 0; c < 2; c++) {
            for (let d = 0; d < 2; d++) {
              for (let e = 0; e < 2; e++) {
                const x = (a - 0.5) * 4 + (e - 0.5) * 0.5
                const y = (b - 0.5) * 4 + (d - 0.5) * 0.5
                const z = (c - 0.5) * 4 + (a - 0.5) * 0.3
                vertices.push(new THREE.Vector3(x, y, z))
              }
            }
          }
        }
      }

      // Create vertex spheres
      vertices.forEach((vertex, i) => {
        const geometry = new THREE.SphereGeometry(0.08, 8, 8)
        const material = new THREE.MeshBasicMaterial({ 
          color: new THREE.Color().setHSL((i / 32) * 0.8 + 0.1, 0.7, 0.6),
          transparent: true,
          opacity: 0.8
        })
        const sphere = new THREE.Mesh(geometry, material)
        sphere.position.copy(vertex)
        group.add(sphere)
      })

      // Create edges with proper 5D connectivity
      const edgeMaterial = new THREE.LineBasicMaterial({ 
        color: 0x00ffff, 
        transparent: true, 
        opacity: 0.4 
      })

      for (let i = 0; i < vertices.length; i++) {
        for (let j = i + 1; j < vertices.length; j++) {
          // Check if vertices are connected in 5D space (differ by exactly one bit)
          let diff = 0
          let temp1 = i, temp2 = j
          for (let k = 0; k < 5; k++) {
            if ((temp1 & 1) !== (temp2 & 1)) diff++
            temp1 >>= 1
            temp2 >>= 1
          }
          
          if (diff === 1) {
            const geometry = new THREE.BufferGeometry().setFromPoints([vertices[i], vertices[j]])
            const line = new THREE.Line(geometry, edgeMaterial)
            group.add(line)
          }
        }
      }

      return group
    }

    // Create 64 Tetrahedra in 4x4x4 grid
    const createTetrahedra = () => {
      const group = new THREE.Group()
      
      for (let x = 0; x < 4; x++) {
        for (let y = 0; y < 4; y++) {
          for (let z = 0; z < 4; z++) {
            // Create tetrahedron geometry
            const vertices = new Float32Array([
              0, 1, 0,      // top vertex
              -0.5, 0, 0.5,  // base vertex 1
              0.5, 0, 0.5,   // base vertex 2
              0, 0, -0.5     // base vertex 3
            ])
            
            const faces = new Uint16Array([
              0, 1, 2,  // face 1
              0, 2, 3,  // face 2
              0, 3, 1,  // face 3
              1, 3, 2   // base face
            ])

            const geometry = new THREE.BufferGeometry()
            geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
            geometry.setIndex(new THREE.BufferAttribute(faces, 1))
            geometry.computeVertexNormals()

            // Color based on position in grid
            const hue = ((x + y + z) / 12) * 0.6 + 0.15
            const material = new THREE.MeshBasicMaterial({ 
              color: new THREE.Color().setHSL(hue, 0.8, 0.5),
              transparent: true,
              opacity: 0.3,
              wireframe: true
            })

            const tetrahedron = new THREE.Mesh(geometry, material)
            
            // Position in 4x4x4 grid
            tetrahedron.position.set(
              (x - 1.5) * 2.5,
              (y - 1.5) * 2.5,
              (z - 1.5) * 2.5
            )
            
            // Scale based on grid position
            const scale = 0.3 + (Math.sin(x + y + z) * 0.1)
            tetrahedron.scale.setScalar(scale)
            
            group.add(tetrahedron)
          }
        }
      }

      return group
    }

    // Create energy flow particles
    const createParticles = () => {
      const group = new THREE.Group()
      const particleCount = 200
      
      for (let i = 0; i < particleCount; i++) {
        const geometry = new THREE.SphereGeometry(0.02, 4, 4)
        const material = new THREE.MeshBasicMaterial({ 
          color: new THREE.Color().setHSL(Math.random() * 0.3 + 0.5, 1, 0.8),
          transparent: true,
          opacity: 0.6
        })
        
        const particle = new THREE.Mesh(geometry, material)
        
        // Random position in sphere
        const radius = 6 + Math.random() * 2
        const theta = Math.random() * Math.PI * 2
        const phi = Math.random() * Math.PI
        
        particle.position.set(
          radius * Math.sin(phi) * Math.cos(theta),
          radius * Math.sin(phi) * Math.sin(theta),
          radius * Math.cos(phi)
        )
        
        // Store original position and movement parameters
        particle.userData = {
          originalPos: particle.position.clone(),
          speed: 0.01 + Math.random() * 0.02,
          amplitude: 0.5 + Math.random() * 1,
          phase: Math.random() * Math.PI * 2
        }
        
        group.add(particle)
      }
      
      return group
    }

    // Create all components
    const hypercube = createHypercube()
    const tetrahedra = createTetrahedra()
    const particles = createParticles()

    hypercubeRef.current = hypercube
    tetrahedraRef.current = tetrahedra
    particlesRef.current = particles

    scene.add(hypercube)
    scene.add(tetrahedra)
    scene.add(particles)

    // Animation loop
    let time = 0
    const animate = () => {
      frameIdRef.current = requestAnimationFrame(animate)
      time += 0.01 * animationSpeed

      // Rotate hypercube in multiple dimensions
      if (hypercubeRef.current) {
        hypercubeRef.current.rotation.x = time * 0.3
        hypercubeRef.current.rotation.y = time * 0.4
        hypercubeRef.current.rotation.z = time * 0.2
      }

      // Rotate tetrahedra group and individual tetrahedra
      if (tetrahedraRef.current) {
        tetrahedraRef.current.rotation.x = time * 0.1
        tetrahedraRef.current.rotation.y = time * 0.15
        
        // Rotate individual tetrahedra
        tetrahedraRef.current.children.forEach((tetrahedron: any, i: number) => {
          if (tetrahedron instanceof THREE.Mesh) {
            tetrahedron.rotation.x = time * (0.5 + i * 0.01)
            tetrahedron.rotation.y = time * (0.3 + i * 0.005)
            tetrahedron.rotation.z = time * (0.4 + i * 0.007)
          }
        })
      }

      // Animate particles
      if (particlesRef.current) {
        particlesRef.current.children.forEach((particle: any, i: number) => {
          if (particle instanceof THREE.Mesh && particle.userData) {
            const data = particle.userData
            const t = time + data.phase
            
            // Orbital motion around original position
            particle.position.x = data.originalPos.x + Math.sin(t * data.speed) * data.amplitude
            particle.position.y = data.originalPos.y + Math.cos(t * data.speed * 1.3) * data.amplitude * 0.7
            particle.position.z = data.originalPos.z + Math.sin(t * data.speed * 0.8) * data.amplitude * 0.5
            
            // Pulsing opacity
            if (particle.material instanceof THREE.MeshBasicMaterial) {
              particle.material.opacity = 0.3 + Math.sin(t * 2) * 0.3
            }
          }
        })
      }

      // Apply consciousness influence
      if (consciousnessStats && hypercubeRef.current) {
        const totalEnergy = Object.values(consciousnessStats).reduce((sum, val) => sum + val, 0) / 500
        
        // Modulate colors based on consciousness stats
        hypercubeRef.current.children.forEach((child: any, i: number) => {
          if (child instanceof THREE.Mesh && child.material instanceof THREE.MeshBasicMaterial) {
            const baseHue = (i / 32) * 0.8 + 0.1
            const modulation = totalEnergy * 0.3
            child.material.color.setHSL(baseHue + modulation, 0.7 + modulation, 0.6 + modulation * 0.5)
          }
        })
      }

      renderer.render(scene, camera)
    }

    animate()

    // Cleanup
    return () => {
      if (frameIdRef.current) {
        cancelAnimationFrame(frameIdRef.current)
      }
      if (mountRef.current && renderer.domElement) {
        mountRef.current.removeChild(renderer.domElement)
      }
      renderer.dispose()
    }
  }, [animationSpeed, consciousnessStats, THREE])

  return (
    <div className="relative">
      <div 
        ref={mountRef} 
        className="w-full h-[400px] rounded-lg overflow-hidden border border-gray-700"
        style={{ background: 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)' }}
      />
      <div className="absolute top-2 left-2 text-xs text-green-400 font-mono bg-black/50 px-2 py-1 rounded">
        5D Hypercube + 64 Tetrahedra
      </div>
      <div className="absolute bottom-2 left-2 text-xs text-cyan-400 font-mono bg-black/50 px-2 py-1 rounded">
        Consciousness Integration Active
      </div>
      <div className="absolute top-2 right-2 space-y-1">
        <button 
          onClick={() => setAnimationSpeed(prev => prev === 0 ? 1 : 0)}
          className="text-xs bg-blue-600/70 hover:bg-blue-600 px-2 py-1 rounded text-white transition-colors"
        >
          {animationSpeed === 0 ? 'Resume' : 'Pause'}
        </button>
        <button 
          onClick={() => setAnimationSpeed(prev => prev > 2 ? 0.5 : prev + 0.5)}
          className="text-xs bg-purple-600/70 hover:bg-purple-600 px-2 py-1 rounded text-white transition-colors block"
        >
          Speed: {animationSpeed}x
        </button>
      </div>
    </div>
  )
}

// Export as dynamic component to prevent SSR issues
export default dynamic(() => Promise.resolve(HypercubeVisualization), { 
  ssr: false,
  loading: () => <div className="w-full h-[400px] flex items-center justify-center bg-gray-900 rounded-lg">Loading 5D Hypercube...</div>
})