<template>
  <div class="flex flex-col gap-4">
    <!-- Search -->
    <MapSearch
      v-if="currentMapId != null && currentCoords != null"
      :maps="maps"
      :quest-givers="questGivers"
      :markers="markers"
      :overlay-map-id="props.overlayMapId"
      :current-map-id="currentMapId"
      :current-coords="currentCoords"
      :touch-friendly="touchFriendly"
      @jump-to-marker="$emit('jumpToMarker', $event)"
    />
    <!-- Zoom -->
    <section class="flex flex-col gap-2">
      <h3 class="text-xs font-semibold uppercase tracking-wider text-base-content/70 flex items-center gap-1.5">
        <icons-icon-zoom-in class="size-3.5 opacity-80" aria-hidden="true" />
        Zoom
      </h3>
      <div class="flex items-center gap-2">
        <button
          type="button"
          class="btn btn-outline btn-sm btn-square transition-all duration-200 hover:scale-105 touch-manipulation"
          :class="touchFriendly ? 'min-h-10 min-w-10' : ''"
          title="Zoom in"
          aria-label="Zoom in"
          @click="$emit('zoomIn')"
        >
          <icons-icon-zoom-in />
        </button>
        <button
          type="button"
          class="btn btn-outline btn-sm btn-square transition-all duration-200 hover:scale-105 touch-manipulation"
          :class="touchFriendly ? 'min-h-10 min-w-10' : ''"
          title="Zoom out"
          aria-label="Zoom out"
          @click="$emit('zoomOut')"
        >
          <icons-icon-zoom-out />
        </button>
        <button
          type="button"
          class="btn btn-outline btn-sm btn-square transition-all duration-200 hover:scale-105 touch-manipulation"
          :class="touchFriendly ? 'min-h-10 min-w-10' : ''"
          title="Reset view — center map and minimum zoom"
          aria-label="Reset view"
          @click="$emit('resetView')"
        >
          <icons-icon-home />
        </button>
      </div>
      <div class="flex items-center gap-2">
        <input
          type="range"
          :min="zoomMin"
          :max="zoomMax"
          :value="currentZoom"
          class="range range-primary range-sm flex-1"
          :class="touchFriendly ? 'range-lg' : ''"
          aria-label="Zoom level"
          @input="onZoomSliderInput($event)"
        >
        <span class="text-xs font-mono w-6 text-right" aria-hidden="true">{{ currentZoom }}</span>
      </div>
    </section>
    <!-- Display -->
    <section class="flex flex-col gap-2">
      <h3 class="text-xs font-semibold uppercase tracking-wider text-base-content/70 flex items-center gap-1.5">
        <icons-icon-eye class="size-3.5 opacity-80" aria-hidden="true" />
        Display
      </h3>
      <label class="label cursor-pointer justify-start gap-2 py-0 hover:bg-base-200/50 rounded-lg px-2 -mx-2 touch-manipulation" :class="touchFriendly ? 'min-h-11' : ''">
        <input v-model="hideMarkers" type="checkbox" class="checkbox checkbox-sm" >
        <span>Hide markers</span>
      </label>
    </section>
    <!-- Navigation -->
    <section class="flex flex-col gap-3">
      <h3 class="text-xs font-semibold uppercase tracking-wider text-base-content/70 flex items-center gap-1.5">
        <icons-icon-map-pin class="size-3.5 opacity-80" aria-hidden="true" />
        Navigation
      </h3>
      <fieldset class="fieldset">
        <label class="label py-0"><span>Jump to Map</span></label>
        <select
          v-model="selectedMapIdSelect"
          class="select select-sm w-full focus:ring-2 focus:ring-primary touch-manipulation"
          :class="touchFriendly ? 'min-h-11 text-base' : ''"
        >
          <option value="">Select map</option>
          <option v-for="m in maps" :key="m.ID" :value="String(m.ID)">{{ m.Name }}</option>
        </select>
      </fieldset>
      <fieldset class="fieldset">
        <label class="label py-0 flex items-center gap-1.5">
          <span>Overlay Map</span>
          <span
            class="inline-flex text-base-content/60 cursor-help"
            title="Overlay shows markers from another map on top of the current one."
            aria-label="Overlay shows markers from another map on top of the current one."
          >
            <icons-icon-info class="size-3.5" />
          </span>
        </label>
        <select
          v-model="overlayMapId"
          class="select select-sm w-full focus:ring-2 focus:ring-primary touch-manipulation"
          :class="touchFriendly ? 'min-h-11 text-base' : ''"
        >
          <option value="-1">None</option>
          <option v-for="m in maps" :key="'overlay-' + m.ID" :value="String(m.ID)">{{ m.Name }}</option>
        </select>
      </fieldset>
      <fieldset class="fieldset">
        <label class="label py-0"><span>Jump to</span></label>
        <div class="join w-full flex">
          <button
            type="button"
            class="btn btn-sm join-item flex-1 touch-manipulation"
            :class="[jumpToTab === 'quest' ? 'btn-active' : 'btn-ghost', touchFriendly ? 'min-h-11 text-base' : '']"
            aria-pressed="jumpToTab === 'quest'"
            @click="jumpToTab = 'quest'"
          >
            Quest giver
          </button>
          <button
            type="button"
            class="btn btn-sm join-item flex-1 touch-manipulation"
            :class="[jumpToTab === 'player' ? 'btn-active' : 'btn-ghost', touchFriendly ? 'min-h-11 text-base' : '']"
            aria-pressed="jumpToTab === 'player'"
            @click="jumpToTab = 'player'"
          >
            Player
          </button>
        </div>
        <select
          v-if="jumpToTab === 'quest'"
          v-model="selectedMarkerIdSelect"
          class="select select-sm w-full focus:ring-2 focus:ring-primary touch-manipulation mt-1"
          :class="touchFriendly ? 'min-h-11 text-base' : ''"
          aria-label="Select quest giver"
        >
          <option value="">Select quest giver</option>
          <option v-for="q in questGivers" :key="q.id" :value="String(q.id)">{{ q.name }}</option>
        </select>
        <select
          v-else
          v-model="selectedPlayerIdSelect"
          class="select select-sm w-full focus:ring-2 focus:ring-primary touch-manipulation mt-1"
          :class="touchFriendly ? 'min-h-11 text-base' : ''"
          aria-label="Select player"
        >
          <option value="">Select player</option>
          <option v-for="p in players" :key="p.id" :value="String(p.id)">{{ p.name }}</option>
        </select>
      </fieldset>
    </section>
    <!-- Saved locations -->
    <MapBookmarks
      :maps="maps"
      :current-map-id="currentMapId ?? null"
      :current-coords="currentCoords ?? null"
      :selected-marker-for-bookmark="selectedMarkerForBookmark ?? null"
      :touch-friendly="touchFriendly"
    />
    <p class="text-xs text-base-content/50 mt-2">
      <kbd class="kbd kbd-xs">?</kbd> for shortcuts
    </p>
  </div>
</template>

<script setup lang="ts">
import type { MapInfo, Marker as ApiMarker } from '~/types/api'
import type { SelectedMarkerForBookmark } from '~/components/map/MapBookmarks.vue'
import MapBookmarks from '~/components/map/MapBookmarks.vue'
import { HnHMinZoom, HnHMaxZoom } from '~/lib/LeafletCustomTypes'

interface QuestGiver {
  id: number
  name: string
}

interface Player {
  id: number
  name: string
}

const zoomMin = HnHMinZoom
const zoomMax = HnHMaxZoom

const props = withDefaults(
  defineProps<{
    maps: MapInfo[]
    questGivers: QuestGiver[]
    players: Player[]
    markers?: ApiMarker[]
    touchFriendly?: boolean
    selectedMapIdSelect: string
    overlayMapId: number
    selectedMarkerIdSelect: string
    selectedPlayerIdSelect: string
    currentZoom?: number
    currentMapId?: number
    currentCoords?: { x: number; y: number; z: number } | null
    selectedMarkerForBookmark?: SelectedMarkerForBookmark
  }>(),
  { touchFriendly: false, markers: () => [], currentZoom: 1, currentMapId: 0, currentCoords: null, selectedMarkerForBookmark: null }
)

const emit = defineEmits<{
  zoomIn: []
  zoomOut: []
  resetView: []
  setZoom: [level: number]
  jumpToMarker: [id: number]
  'update:hideMarkers': [v: boolean]
  'update:selectedMapIdSelect': [v: string]
  'update:overlayMapId': [v: number]
  'update:selectedMarkerIdSelect': [v: string]
  'update:selectedPlayerIdSelect': [v: string]
}>()

function onZoomSliderInput(event: Event) {
  const value = (event.target as HTMLInputElement).value
  const level = Number(value)
  if (!Number.isNaN(level)) emit('setZoom', level)
}

const hideMarkers = defineModel<boolean>('hideMarkers', { required: true })

const jumpToTab = ref<'quest' | 'player'>('quest')

const selectedMapIdSelect = computed({
  get: () => props.selectedMapIdSelect,
  set: (v) => emit('update:selectedMapIdSelect', v),
})
const overlayMapId = computed({
  get: () => String(props.overlayMapId),
  set: (v) => emit('update:overlayMapId', v === '' ? -1 : Number(v)),
})
const selectedMarkerIdSelect = computed({
  get: () => props.selectedMarkerIdSelect,
  set: (v) => emit('update:selectedMarkerIdSelect', v),
})
const selectedPlayerIdSelect = computed({
  get: () => props.selectedPlayerIdSelect,
  set: (v) => emit('update:selectedPlayerIdSelect', v),
})
</script>
