import { type Ref, ref } from 'vue'
import { getTile, tileToWorldXY } from '@/composables/zoneComposable'
import { useGameStore } from '@/stores/gameStore'
import config from '@/config'

export function useGamePointerHandlers(scene: Phaser.Scene, layer: Phaser.Tilemaps.TilemapLayer, waypoint: Ref<{ visible: boolean; x: number; y: number }>, camera: Phaser.Cameras.Scene2D.Camera) {
  const gameStore = useGameStore()
  const pointerStartPosition = ref({ x: 0, y: 0 })
  const dragThreshold = 5 // pixels

  function updateWaypoint(worldX: number, worldY: number) {
    const pointerTile = getTile(layer, worldX, worldY)
    if (pointerTile) {
      const worldPoint = tileToWorldXY(layer, pointerTile.x, pointerTile.y)
      waypoint.value = {
        visible: true,
        x: worldPoint.positionX,
        y: worldPoint.positionY + config.tile_size.y + 15
      }
    } else {
      waypoint.value.visible = false
    }
  }

  function handlePointerDown(pointer: Phaser.Input.Pointer) {
    pointerStartPosition.value = { x: pointer.x, y: pointer.y }
    gameStore.setPlayerDraggingCamera(true)
  }

  function handlePointerMove(pointer: Phaser.Input.Pointer) {
    const { worldX, worldY } = pointer
    updateWaypoint(worldX, worldY)

    if (gameStore.game.isPlayerDraggingCamera) {
      const distance = Phaser.Math.Distance.Between(pointerStartPosition.value.x, pointerStartPosition.value.y, pointer.x, pointer.y)

      if (distance > dragThreshold) {
        const { x, y, prevPosition } = pointer
        const { scrollX, scrollY, zoom } = camera
        camera.setScroll(scrollX - (x - prevPosition.x) / zoom, scrollY - (y - prevPosition.y) / zoom)
      }
    }
  }

  function handlePointerUp(pointer: Phaser.Input.Pointer) {
    const distance = Phaser.Math.Distance.Between(pointerStartPosition.value.x, pointerStartPosition.value.y, pointer.x, pointer.y)

    if (distance <= dragThreshold) {
      const pointerTile = getTile(layer, pointer.worldX, pointer.worldY)
      if (pointerTile) {
        gameStore.connection?.emit('character:move', {
          positionX: pointerTile.x,
          positionY: pointerTile.y
        })
      }
    }

    gameStore.setPlayerDraggingCamera(false)
  }

  const setupPointerHandlers = () => {
    scene.input.on(Phaser.Input.Events.POINTER_DOWN, handlePointerDown)
    scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
    scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
  }

  const cleanupPointerHandlers = () => {
    scene.input.off(Phaser.Input.Events.POINTER_DOWN, handlePointerDown)
    scene.input.off(Phaser.Input.Events.POINTER_MOVE, handlePointerMove)
    scene.input.off(Phaser.Input.Events.POINTER_UP, handlePointerUp)
  }

  return { setupPointerHandlers, cleanupPointerHandlers }
}
