import { Suspense, useRef, useCallback, forwardRef, useImperativeHandle } from 'react'
import { Canvas, useThree } from '@react-three/fiber'
import { OrbitControls, AdaptiveDpr, AdaptiveEvents } from '@react-three/drei'
import * as THREE from 'three'
import type { TransformedGraph } from './types'
import { CAMERA, SCENE, FORCE_PARAMS } from './constants'
import { useForceLayout } from './useForceLayout'
import { useGraphInteraction } from './useGraphInteraction'
import NodeCloud from './NodeCloud'
import EdgeLines from './EdgeLines'
import NeuralPulse from './NeuralPulse'
import NodeTooltip from './NodeTooltip'

function SceneContent({ graph }: { graph: TransformedGraph }) {
  const { positions } = useForceLayout(graph, FORCE_PARAMS)
  const { hovered, highlightSet, onHover, onClick } = useGraphInteraction(graph)

  if (!positions) return null

  return (
    <>
      {/* Invisible background plane — click to clear selection */}
      <mesh position={[0, 0, -200]} onClick={() => onClick(null)}>
        <planeGeometry args={[2000, 2000]} />
        <meshBasicMaterial transparent opacity={0} />
      </mesh>
      <EdgeLines graph={graph} positions={positions} highlightSet={highlightSet} />
      <NodeCloud
        graph={graph}
        positions={positions}
        highlightSet={highlightSet}
        onHover={onHover}
        onClick={onClick}
      />
      <NeuralPulse graph={graph} positions={positions} />
      <NodeTooltip hovered={hovered} />
    </>
  )
}

export interface SceneHandle {
  zoomIn: () => void
  zoomOut: () => void
  resetView: () => void
}

const SceneControls = forwardRef<SceneHandle>((_props, ref) => {
  const { camera } = useThree()

  useImperativeHandle(ref, () => ({
    zoomIn: () => {
      const dist = camera.position.length()
      if (dist > 15) camera.position.multiplyScalar(0.75)
    },
    zoomOut: () => {
      const dist = camera.position.length()
      if (dist < 400) camera.position.multiplyScalar(1.5)
    },
    resetView: () => {
      camera.position.set(...CAMERA.position)
      camera.lookAt(0, 0, 0)
    },
  }), [camera])

  return null
})

export default function BrainGraph3DScene({ graph }: { graph: TransformedGraph }) {
  const controlsRef = useRef<SceneHandle>(null)

  const handleZoomIn = useCallback(() => controlsRef.current?.zoomIn(), [])
  const handleZoomOut = useCallback(() => controlsRef.current?.zoomOut(), [])
  const handleReset = useCallback(() => controlsRef.current?.resetView(), [])

  return (
    <>
      <Canvas
        camera={{ fov: CAMERA.fov, near: CAMERA.near, far: CAMERA.far, position: CAMERA.position }}
        gl={{ antialias: true, alpha: false, powerPreference: 'high-performance' }}
        onCreated={({ scene }) => {
          scene.background = new THREE.Color(SCENE.bgColor)
        }}
        style={{ width: '100%', height: '100%' }}
      >
        <ambientLight intensity={0.3} />
        <pointLight position={[30, 30, 30]} intensity={0.8} />
        <pointLight position={[-20, -20, -20]} intensity={0.4} color="#06b6d4" />

        <Suspense fallback={null}>
          <SceneContent graph={graph} />
        </Suspense>

        <SceneControls ref={controlsRef} />

        <OrbitControls
          enableDamping
          dampingFactor={0.08}
          minDistance={15}
          maxDistance={400}
          autoRotate={false}
          enableZoom
          zoomSpeed={0.8}
        />
        <AdaptiveDpr pixelated />
        <AdaptiveEvents />
      </Canvas>

      {/* Zoom control overlay */}
      <div className="absolute bottom-3 right-3 flex flex-col gap-1.5 z-10">
        <button
          onClick={handleZoomIn}
          className="w-8 h-8 rounded-lg bg-slate-800/80 border border-slate-600/50 text-slate-300
            hover:bg-slate-700/80 hover:text-white transition-colors text-sm font-bold flex items-center justify-center"
          title="Zoom in"
        >+</button>
        <button
          onClick={handleZoomOut}
          className="w-8 h-8 rounded-lg bg-slate-800/80 border border-slate-600/50 text-slate-300
            hover:bg-slate-700/80 hover:text-white transition-colors text-sm font-bold flex items-center justify-center"
          title="Zoom out"
        >-</button>
        <button
          onClick={handleReset}
          className="w-8 h-8 rounded-lg bg-slate-800/80 border border-slate-600/50 text-slate-300
            hover:bg-slate-700/80 hover:text-white transition-colors text-[10px] flex items-center justify-center"
          title="Reset view"
        >RST</button>
      </div>
    </>
  )
}
