import { getTile } from '@/services/mapService'
import { useGameStore } from '@/stores/gameStore'
import type { Ref } from 'vue'
import { useBaseControlsComposable } from './useBaseControlsComposable'

export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Tilemaps.TilemapLayer, waypoint: Ref<{ visible: boolean; x: number; y: number }>, camera: Phaser.Cameras.Scene2D.Camera) {
  const gameStore = useGameStore()
  const baseHandlers = useBaseControlsComposable(scene, layer, waypoint, camera)

  function handlePointerDown(pointer: Phaser.Input.Pointer) {
    baseHandlers.startDragging(pointer)
  }

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

  function handlePointerUp(pointer: Phaser.Input.Pointer) {
    baseHandlers.stopDragging()

    const pointerTile = getTile(layer, pointer.worldX, pointer.worldY)
    if (!pointerTile) return

    gameStore.connection?.emit('map:character:move', {
      positionX: pointerTile.x,
      positionY: pointerTile.y
    })
  }

  const pressedKeys = new Set<string>()
  let moveInterval: number | null = null

  function handleKeyDown(event: KeyboardEvent) {
    if (!gameStore.character) return

    // console.log(event.key)

    if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)) {
      pressedKeys.add(event.key)

      // Start movement loop if not already running
      if (!moveInterval) {
        moveInterval = window.setInterval(moveCharacter, 100) // Adjust timing as needed
        moveCharacter() // Move immediately on first press
      }
    }

    // Attack on CTRL
    if (event.key === 'Control') {
      gameStore.connection?.emit('map:character:attack')
    }
  }

  function handleKeyUp(event: KeyboardEvent) {
    pressedKeys.delete(event.key)

    // If no movement keys are pressed, clear the interval
    if (pressedKeys.size === 0 && moveInterval) {
      clearInterval(moveInterval)
      moveInterval = null
    }
  }

  function moveCharacter() {
    if (!gameStore.character) return
    const { positionX, positionY } = gameStore.character

    if (pressedKeys.has('ArrowLeft')) {
      gameStore.connection?.emit('map:character:move', {
        positionX: positionX - 1,
        positionY: positionY
      })
    }
    if (pressedKeys.has('ArrowRight')) {
      gameStore.connection?.emit('map:character:move', {
        positionX: positionX + 1,
        positionY: positionY
      })
    }
    if (pressedKeys.has('ArrowUp')) {
      gameStore.connection?.emit('map:character:move', {
        positionX: positionX,
        positionY: positionY - 1
      })
    }
    if (pressedKeys.has('ArrowDown')) {
      gameStore.connection?.emit('map:character:move', {
        positionX: positionX,
        positionY: positionY + 1
      })
    }
  }

  const setupControls = () => {
    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)
    scene.input.on(Phaser.Input.Events.POINTER_WHEEL, baseHandlers.handleZoom)
    scene.input.keyboard!.on('keydown', handleKeyDown)
    scene.input.keyboard!.on('keyup', handleKeyUp)
  }

  const cleanupControls = () => {
    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)
    scene.input.off(Phaser.Input.Events.POINTER_WHEEL, baseHandlers.handleZoom)
    scene.input.keyboard!.off('keydown', handleKeyDown)
    scene.input.keyboard!.off('keyup', handleKeyUp)
  }

  return { setupControls, cleanupControls }
}
