<template>
  <div v-if="!hasCoords" class="p-4 text-center">
    ⏳ Определяем ваше местоположение...
  </div>

  <YandexMap
    v-else
    v-model="map"
    class="w-full"
    :settings="{ location }"
    style="height: calc(100dvh - 54px)"
  >
    <YandexMapDefaultSchemeLayer />
    <YandexMapDefaultFeaturesLayer />

    <YandexMapClusterer
      v-model="clusterer"
      :grid-size="64"
      zoom-on-cluster-click
      @true-bounds="trueBounds = $event"
    >
      <YandexMapMarker
        v-for="pickupPoint in pickupPoints"
        :key="pickupPoint.id"
        position="top-center left-center"
        :settings="{ coordinates: [pickupPoint.position.longitude, pickupPoint.position.latitude] }"
        @click="centerMap(pickupPoint)"
      >
        <div class="marker">
          <Icon name="i-lucide-map-pin" class="marker__icon" />
        </div>
      </YandexMapMarker>

      <template #cluster="{ length }">
        <div class="cluster fade-in">
          {{ length }}
        </div>
      </template>
    </YandexMapClusterer>
  </YandexMap>
</template>

<script setup lang="ts">
import type { LngLatBounds, YMap } from '@yandex/ymaps3-types'
import type { YMapLocationRequest } from '@yandex/ymaps3-types/imperative/YMap'
import type { YMapClusterer } from '@yandex/ymaps3-types/packages/clusterer'
import type { PickupPoint } from '~/server/shared/types/yandex_pvz'
import { useGeolocation } from '@vueuse/core'
import { computed, shallowRef } from 'vue'
import {
  YandexMap,
  YandexMapClusterer,
  YandexMapDefaultFeaturesLayer,
  YandexMapDefaultSchemeLayer,
  YandexMapMarker,
} from 'vue-yandex-maps'
import { useCheckout } from '~/composables/useCheckout'

defineProps<{ pickupPoints: PickupPoint[] }>()

const { setCheckoutPickupPoint, isPickupPointSelected } = useCheckout()
const { coords } = useGeolocation()
const clusterer = shallowRef<YMapClusterer | null>(null)
const trueBounds = ref<LngLatBounds>([[0, 0], [0, 0]])
const map = shallowRef<null | YMap>(null)

const hasCoords = computed(() => coords.value?.latitude !== Infinity && coords.value?.longitude !== Infinity)

const location = ref<YMapLocationRequest>({
  zoom: 2,
})

function centerMap(pickupPoint: PickupPoint) {
  location.value = {
    center: [pickupPoint.position.longitude, pickupPoint.position.latitude],
    zoom: 18,
    duration: 500,
  }

  setCheckoutPickupPoint(pickupPoint)
  isPickupPointSelected.value = true
}

watch(coords, (newCoords) => {
  if (newCoords && hasCoords.value) {
    location.value = {
      center: [newCoords.longitude, newCoords.latitude],
      zoom: 9,
      duration: 2500,
    }
  }
}, { once: true })

defineExpose({ centerMap, location })
</script>

<style lang="scss" scoped>
.marker {
  position: relative;
  background-color: #0f172b;
  border: 1px solid #0f172b;
  border-radius: 12px;
  padding: 6px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
  transition:
    transform 0.2s ease,
    background-color 0.3s ease;

  &:hover {
    transform: scale(1.1);
    background-color: #1e293b;
  }

  &::after {
    content: '';
    position: absolute;
    bottom: -6px;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-top: 6px solid #0f172b;
    filter: drop-shadow(0 2px 1px rgba(0, 0, 0, 0.15));
  }

  &__icon {
    color: white;
    width: 20px;
    height: 20px;
  }
}

.cluster {
  background-color: #0f172b;
  color: white;
  border-radius: 50%;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 14px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
  border: 2px solid #fff;
  transition:
    transform 0.2s ease,
    background-color 0.3s ease;

  &:hover {
    transform: scale(1.1);
    background-color: #1e293b;
  }
}
</style>
