<template>
  <div class="flex justify-between p-5 w-[calc(100%_-_40px)] fixed bottom-0 left-0 z-20" :class="{ 'list-open': listOpen }">
    <div class="toolbar rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10">
      <div ref="toolbar" class="tools flex gap-2.5" v-if="mapEditor.currentMap.value">
        <button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'move' }" @click="handleClick('move')">
          <img class="invert w-5 h-5" src="/assets/icons/mapEditor/move.svg" alt="Move camera" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'move' }">(M)</span>
        </button>

        <div class="w-px bg-cyan"></div>

        <button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'pencil' }" @click="handleClick('pencil')">
          <img class="invert w-5 h-5" src="/assets/icons/mapEditor/pencil.svg" alt="Pencil" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'pencil' }">(P)</span>
          <div class="select" v-if="mapEditor.tool.value === 'pencil'">
            <div class="select-trigger group capitalize flex gap-3.5" :class="{ open: selectPencilOpen }">
              {{ mapEditor.drawMode.value.replace('_', ' ') }}
              <img class="group-[.open]:rotate-180 invert w-5 h-5 rotate-0 transition ease-in-out duration-200" src="/assets/icons/mapEditor/chevron.svg" alt="" />
            </div>
            <div class="flex flex-col absolute bottom-full mb-5 left-1/2 -translate-x-1/2 bg-gray rounded min-w-28 border border-gray-500 border-solid text-left" v-show="selectPencilOpen && mapEditor.tool.value === 'pencil'">
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('tile', 'pencil')">
                Tile
                <div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
              </span>
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('map_object', 'pencil')">
                Map object
                <div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
              </span>
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('teleport', 'pencil')">
                Teleport
                <div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
              </span>
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('blocking tile', 'pencil')">Blocking tile</span>
            </div>
          </div>
        </button>

        <div class="w-px bg-cyan"></div>

        <button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'eraser' }" @click="handleClick('eraser')">
          <img class="invert w-5 h-5" src="/assets/icons/mapEditor/eraser.svg" alt="Eraser" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'eraser' }">(E)</span>
          <div class="select" v-if="mapEditor.tool.value === 'eraser'">
            <div class="select-trigger group capitalize flex gap-3.5" :class="{ open: selectEraserOpen }">
              {{ mapEditor.drawMode.value.replace('_', ' ') }}
              <img class="group-[.open]:rotate-180 invert w-5 h-5 rotate-0 transition ease-in-out duration-200" src="/assets/icons/mapEditor/chevron.svg" alt="" />
            </div>
            <div class="flex flex-col absolute bottom-full mb-5 left-1/2 -translate-x-1/2 bg-gray rounded min-w-28 border border-gray-500 border-solid text-left" v-show="selectEraserOpen">
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('tile', 'eraser')">
                Tile
                <div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
              </span>
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('map_object', 'eraser')">
                Map object
                <div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
              </span>
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('teleport', 'eraser')">
                Teleport
                <div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
              </span>
              <span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="() => handleModeClick('blocking tile', 'eraser')">Blocking tile</span>
            </div>
          </div>
        </button>

        <div class="w-px bg-cyan"></div>

        <button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'paint' }" @click="handleClick('paint')">
          <img class="invert w-5 h-5" src="/assets/icons/mapEditor/paint.svg" alt="Paint bucket" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'paint' }">(B)</span>
        </button>

        <div class="w-px bg-cyan"></div>

        <button class="flex justify-center items-center min-w-10 p-0 relative" @click="isMapEditorSettingsModalOpen = !isMapEditorSettingsModalOpen"><img class="invert w-5 h-5" src="/assets/icons/mapEditor/gear.svg" alt="Map settings" /> <span class="h-5 ml-2.5">(Z)</span></button>

        <div class="w-px bg-cyan"></div>

        <button class="flex justify-center items-center min-w-10 p-0 relative" @click="isMapEditorSettingsModalOpen = !isMapEditorSettingsModalOpen"><img class="invert w-5 h-5" src="/assets/icons/mapEditor/settings.svg" alt="Map settings" /> <span class="h-5 ml-2.5">(S)</span></button>
      </div>
    </div>
    <div class="toolbar rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10 space-x-2">
      <button class="btn-cyan px-3.5" @click="() => emit('open-maps')">Load</button>
      <button class="btn-cyan px-3.5" @click="() => emit('save')" v-if="mapEditor.currentMap.value">Save</button>
      <button class="btn-cyan px-3.5" @click="() => emit('clear')" v-if="mapEditor.currentMap.value">Clear</button>
      <button class="btn-cyan px-3.5" @click="() => mapEditor.toggleActive()">Exit</button>
    </div>
  </div>

  <Modal :isModalOpen="isMapEditorSettingsModalOpen" @modal:close="() => (isMapEditorSettingsModalOpen = false)" :modal-width="300" :modal-height="350" :is-resizable="false" bg-style="none">
    <template #modalHeader>
      <h3 class="m-0 font-medium shrink-0 text-white">Map editor settings</h3>
    </template>
    <template #modalBody>
      <div class="m-4 flex items-center space-x-2">
        <input id="continuous-drawing" @change="toggleContinuousDrawing" v-model="isContinuousDrawingEnabled" type="checkbox" class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500" />
        <label for="continuous-drawing" class="text-sm font-medium text-gray-200 cursor-pointer"> Continuous Drawing </label>
      </div>
      <div class="m-4 flex items-center space-x-2">
        <input id="show-placed-map-object-preview" @change="mapEditor.togglePlacedMapObjectPreview()" v-model="isShowPlacedMapObjectPreviewEnabled" type="checkbox" class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500" />
        <label for="show-placed-map-object-preview" class="text-sm font-medium text-gray-200 cursor-pointer"> Show placed map object preview </label>
      </div>
    </template>
  </Modal>
</template>

<script setup lang="ts">
import Modal from '@/components/utilities/Modal.vue'
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
import { onClickOutside } from '@vueuse/core'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'

const mapEditor = useMapEditorComposable()

const emit = defineEmits(['save', 'clear', 'open-maps', 'open-settings', 'open-teleport'])

// States
const toolbar = ref(null)
const isMapEditorSettingsModalOpen = ref(false)
const selectPencilOpen = ref(false)
const selectEraserOpen = ref(false)
const isContinuousDrawingEnabled = ref<Boolean>(false)
const isShowPlacedMapObjectPreviewEnabled = ref<Boolean>(mapEditor.isPlacedMapObjectPreviewEnabled.value)
const listOpen = computed(() => (mapEditor.tool.value === 'pencil' && (mapEditor.drawMode.value === 'tile' || mapEditor.drawMode.value === 'map_object')) || mapEditor.tool.value === 'paint')

// drawMode
function setDrawMode(value: string) {
  mapEditor.setDrawMode(value)
  selectPencilOpen.value = false
  selectEraserOpen.value = false
}

function setPencilMode() {
  mapEditor.setTool('pencil')
  selectPencilOpen.value = false
}

// drawMode
function setEraserMode() {
  mapEditor.setTool('eraser')
  selectEraserOpen.value = false
}

function toggleContinuousDrawing() {
  mapEditor.setInputMode(isContinuousDrawingEnabled.value ? 'hold' : 'tap')
}

function handleModeClick(mode: string, type: 'pencil' | 'eraser') {
  setDrawMode(mode)
  type === 'pencil' ? setPencilMode() : setEraserMode()
}

function handleClick(tool: string) {
  mapEditor.setTool(tool)
  if (tool === 'paint') mapEditor.setDrawMode('tile')
  selectPencilOpen.value = tool === 'pencil' ? !selectPencilOpen.value : false
  selectEraserOpen.value = tool === 'eraser' ? !selectEraserOpen.value : false
  if (mapEditor.drawMode.value === 'teleport') emit('open-teleport')
}

function cycleToolMode(tool: 'pencil' | 'eraser') {
  const modes = ['tile', 'map_object', 'teleport', 'blocking tile']
  const currentIndex = modes.indexOf(mapEditor.drawMode.value)
  const nextIndex = (currentIndex + 1) % modes.length
  const nextMode = modes[nextIndex]

  setDrawMode(nextMode)
}

function initKeyShortcuts(event: KeyboardEvent) {
  // Check if map is set
  if (!mapEditor.currentMap.value) return

  // prevent if focused on inputs
  if (document.activeElement?.tagName === 'INPUT') return

  if (event.ctrlKey) return

  const keyActions: { [key: string]: string } = {
    m: 'move',
    p: 'pencil',
    e: 'eraser',
    b: 'paint',
    z: 'settings',
    s: 'mapEditorSettings'
  }

  if (keyActions.hasOwnProperty(event.key)) {
    const tool = keyActions[event.key]
    if ((tool === 'pencil' || tool === 'eraser') && mapEditor.tool.value === tool) {
      cycleToolMode(tool)
    } else {
      handleClick(tool)
    }
  }
}

function handleClickOutside() {
  selectPencilOpen.value = false
  selectEraserOpen.value = false
}
onClickOutside(toolbar, handleClickOutside)

onMounted(() => {
  addEventListener('keydown', initKeyShortcuts)
})

onBeforeUnmount(() => {
  removeEventListener('keydown', initKeyShortcuts)
})
</script>
