<template>
  <Image v-for="tile in zoneEditorStore.zone?.zoneEventTiles" v-bind="getImageProps(tile)" />
</template>

<script setup lang="ts">
import { type ZoneEventTile, ZoneEventTileType } from '@/application/types'
import { useZoneEditorStore } from '@/stores/zoneEditorStore'
import { Image, useScene } from 'phavuer'
import { getTile, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
import { uuidv4 } from '@/application/utilities'
import { onMounted, onUnmounted } from 'vue'

const scene = useScene()
const zoneEditorStore = useZoneEditorStore()

const props = defineProps<{
  tilemap: Phaser.Tilemaps.Tilemap
}>()

function getImageProps(tile: ZoneEventTile) {
  return {
    x: tileToWorldX(props.tilemap, tile.positionX, tile.positionY),
    y: tileToWorldY(props.tilemap, tile.positionX, tile.positionY),
    texture: tile.type,
    depth: 999
  }
}

function pencil(pointer: Phaser.Input.Pointer) {
  // Check if zone is set
  if (!zoneEditorStore.zone) return

  // Check if tool is pencil
  if (zoneEditorStore.tool !== 'pencil') return

  // Check if draw mode is blocking tile or teleport
  if (zoneEditorStore.drawMode !== 'blocking tile' && zoneEditorStore.drawMode !== 'teleport') return

  // Check if left mouse button is pressed
  if (!pointer.isDown) return

  // Check if shift is not pressed, this means we are moving the camera
  if (pointer.event.shiftKey) return

  // Check if there is a tile
  const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
  if (!tile) return

  // Check if event tile already exists on position
  const existingEventTile = zoneEditorStore.zone.zoneEventTiles.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
  if (existingEventTile) return

  // If teleport, check if there is a selected zone
  if (zoneEditorStore.drawMode === 'teleport' && !zoneEditorStore.teleportSettings.toZoneId) return

  const newEventTile = {
    id: uuidv4(),
    zoneId: zoneEditorStore.zone.id,
    zone: zoneEditorStore.zone,
    type: zoneEditorStore.drawMode === 'blocking tile' ? ZoneEventTileType.BLOCK : ZoneEventTileType.TELEPORT,
    positionX: tile.x,
    positionY: tile.y,
    teleport:
      zoneEditorStore.drawMode === 'teleport'
        ? {
            toZoneId: zoneEditorStore.teleportSettings.toZoneId,
            toPositionX: zoneEditorStore.teleportSettings.toPositionX,
            toPositionY: zoneEditorStore.teleportSettings.toPositionY,
            toRotation: zoneEditorStore.teleportSettings.toRotation
          }
        : undefined
  }

  zoneEditorStore.zone.zoneEventTiles = zoneEditorStore.zone.zoneEventTiles.concat(newEventTile as ZoneEventTile)
}

function eraser(pointer: Phaser.Input.Pointer) {
  // Check if zone is set
  if (!zoneEditorStore.zone) return

  // Check if tool is pencil
  if (zoneEditorStore.tool !== 'eraser') return

  // Check if draw mode is blocking tile or teleport
  if (zoneEditorStore.eraserMode !== 'blocking tile' && zoneEditorStore.eraserMode !== 'teleport') return

  // Check if left mouse button is pressed
  if (!pointer.isDown) return

  // Check if shift is not pressed, this means we are moving the camera
  if (pointer.event.shiftKey) return

  // Check if there is a tile
  const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY)
  if (!tile) return

  // Check if event tile already exists on position
  const existingEventTile = zoneEditorStore.zone.zoneEventTiles.find((eventTile) => eventTile.positionX === tile.x && eventTile.positionY === tile.y)
  if (!existingEventTile) return

  // Remove existing event tile
  zoneEditorStore.zone.zoneEventTiles = zoneEditorStore.zone.zoneEventTiles.filter((eventTile) => eventTile.id !== existingEventTile.id)
}

onMounted(() => {
  scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
  scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
  scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser)
  scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
})

onUnmounted(() => {
  scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
  scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
  scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
  scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser)
})
</script>
