<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { loadModules } from 'esri-loader'
import axios from 'axios'

import type { LocationObject } from '@/interface/index/Main'

const emit = defineEmits(['update:location'])

function updateLocation(latitude: number, longitude: number, namePOI: string) {
  // ส่ง event ไปยัง parent component เพื่ออัพเดทค่า props
  emit('update:location', latitude, longitude, namePOI)
}

const poiPlaceName = ref<string>('') // ชื่อพื้นที่ใกล้เคียง

// Replace ArcGIS api key
const apiKey = ref<string>(
  'YLATgWuywoeRLHn6KImj5rg7UaP8bJoR9jiTldoCVBHlqFIebwMSA5wIXEmcYhwXwMHkmNISEYtUz3x0oiGIIx0bIXXnUwi0OzupoOEtDrQIsRPVtor7gaPpXEmH8TrNaMT3snf6zO_yujHLGzborg-L9aeAjTJn4ndL6f8qFmRzYcX93E2vyA-7XCufLYTRsdTE5Aq-9hnx1q9PmYVMqhAZpL7dWqn3JgO33fRXetk.'
  // 'AAPK4f700a4324d04e9f8a1a134e0771ac45FXWawdCl-OotFfr52gz9XKxTDJTpDzw_YYcwbmKDDyAJswf14FoPyw0qBkN64DvP'
)
const zoomMap = ref<number>(18)

async function initializeMap() {
  try {
    // Load modules of ArcGIS
    loadModules([
      'esri/config',
      'esri/Map',
      'esri/views/MapView',
      'esri/Graphic',
      'esri/geometry/Point',
      'esri/symbols/PictureMarkerSymbol',
      'esri/widgets/Search',
    ]).then(
      async ([
        esriConfig,
        Map,
        MapView,
        Graphic,
        Point,
        PictureMarkerSymbol,
        Search,
      ]) => {
        // Set apiKey
        // esriConfig.apiKey =
        //   'AAPK4f700a4324d04e9f8a1a134e0771ac45FXWawdCl-OotFfr52gz9XKxTDJTpDzw_YYcwbmKDDyAJswf14FoPyw0qBkN64DvP'

        // Create a FeatureLayer using a custom server URL
        // const hillshadeLayer = new TileLayer({
        //   url: `https://bmagis.bangkok.go.th/arcgis/rest/services/cache/BMA_3D_2D_Cache/MapServer`,
        // })

        const map = new Map({
          basemap: 'streets',
          // basemap: 'streets-navigation-vector',
          // basemap: 'arcgis-topographic',
          // layers: [hillshadeLayer],
        })

        navigator.geolocation.getCurrentPosition(async (position) => {
          const { latitude, longitude } = position.coords
          const pointDefult = new Point({
            latitude,
            longitude,
          })

          // สร้าง MapView
          const mapView = new MapView({
            container: 'mapViewDisplay', // div ที่จะแสดงแผนที่
            map: map,
            center: {
              latitude: latitude,
              longitude: longitude,
            }, // Set the initial map center current position
            zoom: zoomMap.value, // ระดับการซูม

            ui: {
              components: [], // Empty array to remove all default UI components
            },
          })

          // สร้างสัญลักษณ์ของหมุด
          const markerSymbol = new PictureMarkerSymbol({
            url: 'https://maps.google.com/mapfiles/ms/icons/red-dot.png', // รูปหมุด
            width: '32px',
            height: '32px',
          })

          // สร้าง Search widget เพื่อค้นหาสถานที่
          const search = new Search({
            view: mapView,
            popupEnabled: false,
          })

          // เพิ่ม Search widget ไปยังแผนที่
          mapView.ui.add(search, {
            position: 'top-right', // ตำแหน่งของ Search widget
          })

          await axios
            .get(
              'https://bmagis.bangkok.go.th/portal/sharing/servers/e4732c3a9fe549ab8bc697573b468f68/rest/services/World/GeocodeServer/reverseGeocode/',
              {
                params: {
                  f: 'json', // Format JSON response
                  distance: 2000,
                  category: 'POI',
                  location: {
                    spatialReference: { wkid: 4326 },
                    x: longitude,
                    y: latitude,
                  },
                  token: apiKey.value,
                },
              }
            )
            .then((response) => {
              console.log('poi', response.data.location)
              poiPlaceName.value = response.data.address
                ? response.data.address.PlaceName === ''
                  ? response.data.address.ShortLabel
                  : response.data.address.PlaceName
                : 'ไม่พบข้อมูล'
              const poiPoint = new Point({
                longitude: response.data.location.x,
                latitude: response.data.location.y,
              })

              updateLocation(latitude, longitude, poiPlaceName.value)
            })
            .catch(async () => {
              await axios
                .get(
                  'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode/',
                  {
                    params: {
                      f: 'json', // Format JSON response
                      distance: 2000,
                      category: 'POI',
                      location: {
                        spatialReference: { wkid: 4326 },
                        x: longitude,
                        y: latitude,
                      },
                    },
                  }
                )
                .then((response) => {
                  // console.log('poi', response.data.location)
                  poiPlaceName.value = response.data.address
                    ? response.data.address.PlaceName === ''
                      ? response.data.address.ShortLabel
                      : response.data.address.PlaceName
                    : 'ไม่พบข้อมูล'

                  updateLocation(longitude, latitude, poiPlaceName.value)
                })
            })

          let searchMarker: any = null

          searchMarker = new Graphic({
            geometry: pointDefult,
            symbol: markerSymbol,
          })
          mapView.graphics.add(searchMarker)

          // ฟังก์ชันจับการคลิกบนแผนที่
          search.on('select-result', async function (event: any) {
            const { latitude, longitude } = event.result.extent.center

            const point = new Point({
              latitude,
              longitude,
            })

            // ลบหมุดเก่า (ถ้ามี)
            if (searchMarker) {
              mapView.graphics.remove(searchMarker)
            }

            // สร้างและเพิ่มหมุดใหม่
            searchMarker = new Graphic({
              geometry: point,
              symbol: markerSymbol,
            })
            if (searchMarker) {
              await axios
                .get(
                  'https://bmagis.bangkok.go.th/portal/sharing/servers/e4732c3a9fe549ab8bc697573b468f68/rest/services/World/GeocodeServer/reverseGeocode/',
                  {
                    params: {
                      f: 'json', // Format JSON response
                      distance: 2000,
                      category: 'POI',
                      location: {
                        spatialReference: { wkid: 4326 },
                        x: longitude,
                        y: latitude,
                      },
                      token: apiKey.value,
                    },
                  }
                )
                .then((response) => {
                  console.log('poi', response.data.location)
                  poiPlaceName.value = response.data.address
                    ? response.data.address.PlaceName === ''
                      ? response.data.address.ShortLabel
                      : response.data.address.PlaceName
                    : 'ไม่พบข้อมูล'
                  const poiPoint = new Point({
                    longitude: response.data.location.x,
                    latitude: response.data.location.y,
                  })

                  updateLocation(latitude, longitude, poiPlaceName.value)
                })
                .catch(async () => {
                  await axios
                    .get(
                      'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode/',
                      {
                        params: {
                          f: 'json', // Format JSON response
                          distance: 2000,
                          category: 'POI',
                          location: {
                            spatialReference: { wkid: 4326 },
                            x: longitude,
                            y: latitude,
                          },
                        },
                      }
                    )
                    .then((response) => {
                      // console.log('poi', response.data.location)
                      poiPlaceName.value = response.data.address
                        ? response.data.address.PlaceName === ''
                          ? response.data.address.ShortLabel
                          : response.data.address.PlaceName
                        : 'ไม่พบข้อมูล'

                      updateLocation(longitude, latitude, poiPlaceName.value)
                    })
                })
            }

            mapView.graphics.add(searchMarker)

            // เคลื่อนไปยังตำแหน่งที่เลือก
            mapView.goTo({
              target: point,
              zoom: zoomMap.value,
            })
          })

          mapView.on('click', async function (event: any) {
            const lat = event.mapPoint.latitude
            const lon = event.mapPoint.longitude

            const point = new Point({
              longitude: lon,
              latitude: lat,
            })

            if (!searchMarker) {
              searchMarker = new Graphic({
                geometry: point,
                symbol: markerSymbol,
              })

              mapView.graphics.add(searchMarker)
            } else {
              searchMarker.geometry = point // ย้ายหมุดไปยังตำแหน่งใหม่
              if (searchMarker) {
                await axios
                  .get(
                    'https://bmagis.bangkok.go.th/portal/sharing/servers/e4732c3a9fe549ab8bc697573b468f68/rest/services/World/GeocodeServer/reverseGeocode/',
                    {
                      params: {
                        f: 'json', // Format JSON response
                        distance: 2000,
                        category: 'POI',
                        location: {
                          spatialReference: { wkid: 4326 },
                          x: lon,
                          y: lat,
                        },
                        token: apiKey.value,
                      },
                    }
                  )
                  .then((response) => {
                    console.log('poi', response.data.location)
                    poiPlaceName.value = response.data.address
                      ? response.data.address.PlaceName === ''
                        ? response.data.address.ShortLabel
                        : response.data.address.PlaceName
                      : 'ไม่พบข้อมูล'
                    const poiPoint = new Point({
                      longitude: response.data.location.x,
                      latitude: response.data.location.y,
                    })

                    updateLocation(latitude, longitude, poiPlaceName.value)
                  })
                  .catch(async () => {
                    await axios
                      .get(
                        'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode/',
                        {
                          params: {
                            f: 'json', // Format JSON response
                            distance: 2000,
                            category: 'POI',
                            location: {
                              spatialReference: { wkid: 4326 },
                              x: lon,
                              y: lat,
                            },
                          },
                        }
                      )
                      .then((response) => {
                        // console.log('poi', response.data.location)
                        poiPlaceName.value = response.data.address
                          ? response.data.address.PlaceName === ''
                            ? response.data.address.ShortLabel
                            : response.data.address.PlaceName
                          : 'ไม่พบข้อมูล'

                        updateLocation(lat, lon, poiPlaceName.value)
                      })
                  })
              }
            }

            mapView.goTo({
              target: point,
              zoom: zoomMap.value,
            })
          })
        })
      }
    )
  } catch (error) {
    console.error('Error loading the map', error)
  }
}

onMounted(async () => {
  await initializeMap()
})
</script>

<template>
  <q-card
    bordered
    flat
    class="col-12 bg-grey-2 shadow-0"
    :style="$q.screen.gt.xs ? ';' : 'border-radius: 20px'"
  >
    <div id="mapViewDisplay" style="height: 35vh"></div>

    <div
      :class="
        $q.screen.gt.xs
          ? 'q-pa-xs text-weight-medium text-grey-8'
          : 'q-pa-xs text-weight-medium text-grey-8'
      "
    >
      พื้นที่ใกล้เคียง
      <span class="q-px-sm">:</span>
      {{ poiPlaceName }}
    </div>
  </q-card>
</template>

<style></style>
