import { type SpawnNode, useLiveTransforms, useRegistry } from '@pascal-app/core'
import { useMemo, useRef } from 'react'
import type { Group } from 'three'
import { Color, Shape } from 'three'
import { useNodeEvents } from '../../../hooks/use-node-events'
import useViewer from '../../../store/use-viewer'

const SPAWN_COLOR = new Color('#22c55e')

export const SpawnRenderer = ({ node }: { node: SpawnNode }) => {
  const ref = useRef<Group>(null!)
  const handlers = useNodeEvents(node, 'spawn')
  const liveTransform = useLiveTransforms((state) => state.get(node.id))
  const walkthroughMode = useViewer((state) => state.walkthroughMode)

  useRegistry(node.id, 'spawn', ref)

  const materialProps = useMemo(
    () => ({
      color: SPAWN_COLOR,
      emissive: SPAWN_COLOR,
      emissiveIntensity: 0.08,
      metalness: 0.03,
      roughness: 0.42,
    }),
    [],
  )

  const arrowShape = useMemo(() => {
    const shape = new Shape()
    // Positive local Y becomes negative world Z after the -90deg X rotation below,
    // so this tip points "forward" for the player/spawn direction.
    shape.moveTo(0, 0.24)
    shape.lineTo(-0.18, -0.14)
    shape.lineTo(0.18, -0.14)
    shape.closePath()
    return shape
  }, [])

  return (
    <group
      position={liveTransform?.position ?? node.position}
      ref={ref}
      rotation={[0, liveTransform?.rotation ?? node.rotation, 0]}
      visible={!walkthroughMode}
    >
      <mesh position={[0, 0.09, 0]} rotation={[-Math.PI / 2, 0, 0]} {...handlers}>
        <ringGeometry args={[0.34, 0.48, 48]} />
        <meshStandardMaterial {...materialProps} />
      </mesh>

      <mesh position={[0, 0.1, -0.52]} rotation={[-Math.PI / 2, 0, 0]} {...handlers}>
        <shapeGeometry args={[arrowShape]} />
        <meshStandardMaterial {...materialProps} />
      </mesh>

      <mesh position={[0, 0.41, 0]} {...handlers}>
        <boxGeometry args={[0.3, 0.54, 0.16]} />
        <meshStandardMaterial {...materialProps} />
      </mesh>

      <mesh position={[0, 0.83, 0]} {...handlers}>
        <boxGeometry args={[0.18, 0.18, 0.18]} />
        <meshStandardMaterial {...materialProps} />
      </mesh>
    </group>
  )
}
