import { tools } from '@tools'
import { useQuasar } from 'quasar'
import { defineComponent, onMounted, ref, shallowRef, watch, computed } from 'vue'

import 'leaflet/dist/leaflet.css'
import * as L from 'leaflet'
import 'leaflet.markercluster/dist/MarkerCluster.css'
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
import 'leaflet.markercluster'
import '../../utils/leaflet-extensions'; // Importa le estensioni

import { useUserStore } from '@src/store/UserStore'

// Importa le immagini dei marker
import icon from 'leaflet/dist/images/marker-icon.png'
import iconShadow from 'leaflet/dist/images/marker-shadow.png'

export default defineComponent({
  name: 'CMapGetCoordinates',
  setup(props, { emit }) {
    const $q = useQuasar()
    const userStore = useUserStore()

    const iconWidth = ref(25)
    const iconHeight = ref(41)
    const map = shallowRef<L.Map | null>(null)
    const marker = ref<L.Marker | null>(null)
    const address = ref('')
    const suggestions = ref([]);
    const coordinates = ref(<[number, number]>[0, 0])
    const isMapDialogOpen = ref(false)

    const zoomLevel = ref(17)

    const myheight = computed(() => {
      return $q.screen.height - 150
    })

    const initMap = () => {
      // Configura l'icona di default
      const DefaultIcon = L.icon({
        iconUrl: icon,
        shadowUrl: iconShadow,
        iconSize: [iconWidth.value, iconHeight.value],
        iconAnchor: [iconWidth.value / 2, iconHeight.value],
        popupAnchor: [1, -iconHeight.value],
        shadowSize: [iconHeight.value, iconHeight.value]
      })
      L.Marker.prototype.options.icon = DefaultIcon

      map.value = L.map('map',
        {
          zoomControl: true, zoom: zoomLevel.value, zoomAnimation: true,
          fadeAnimation: true, markerZoomAnimation: true,
          center: [42.71, 12.934],
        }
      )
      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map.value)

      const closeButton = L.control({ position: 'topright' });

      closeButton.onAdd = function () {
        const button = L.DomUtil.create('button', 'leaflet-control-button');
        button.innerHTML = 'Chiudi'; // Testo del pulsante
        button.style.backgroundColor = 'red';
        button.style.color = 'white';
        button.style.border = 'none';
        button.style.borderRadius = '5px';
        button.style.padding = '10px';
        button.style.cursor = 'pointer';

        button.onclick = () => {
          isMapDialogOpen.value = false; // Chiudi il dialog della mappa
        };

        return button;
      };

      closeButton.addTo(map.value);

    }

    const updateMarker = (lat: number, lng: number) => {
      console.log('aggiorna marker', lat, lng)
      if (marker.value) {
        marker.value.setLatLng([lat, lng])
      } else {
        marker.value = L.marker([lat, lng], { draggable: true }).addTo(map.value!)
        marker.value.on('dragend', (event: L.LeafletEvent) => {
          const position = (event.target as L.Marker).getLatLng()
          coordinates.value = [
            parseFloat(position.lng.toFixed(6)),
            parseFloat(position.lat.toFixed(6)),
          ]

          emit('update:coordinates', coordinates.value)
        })
      }
      map.value?.setView([lat, lng], 17)
    }

    const searchAddress = async () => {
      try {
        const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address.value)}`)
        const data = await response.json()
        if (data && data.length > 0) {
          coordinates.value = [
            parseFloat(data[0].lon),
            parseFloat(data[0].lat)
          ]
          emit('update:coordinates', coordinates.value)
          isMapDialogOpen.value = true
        }
      } catch (error) {
        console.error('Error searching address:', error)
      }
    }

    // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
    const getAddressSuggestions = async (val: string, update: Function) => {
      try {
        if (val.length === 0) {
          suggestions.value = [];
          update();
          return;
        }

        const response = await fetch(
          `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(val)}`
        );
        const data = await response.json();
        suggestions.value = data.map((item: any) => ({
          label: item.display_name,
          value: item.display_name,
          lat: item.lat,
          lon: item.lon
        }));

        update();
      } catch (error) {
        console.error('Error fetching address suggestions:', error);
      }
    };

    watch(address, (newAddress) => {
      const match: any = suggestions.value.find((suggestion: any) => suggestion.value === newAddress.value);
      if (match && match.lat) {
        coordinates.value = [
          parseFloat(parseFloat(match.lon).toFixed(6)),
          parseFloat(parseFloat(match.lat).toFixed(6))
        ]
      };

      updateMarker(coordinates.value[1], coordinates.value[0]);

    });

    onMounted(() => {
      initMap()
    })

    return {
      address,
      coordinates,
      searchAddress,
      myheight,
      isMapDialogOpen,
      suggestions,
      getAddressSuggestions,
    }
  }
})
