<template>
  <div style="height:600px; width:800px">
      <q-toolbar class="bg-primary text-white q-my-md shadow-2">
      <q-btn flat round dense icon="menu" class="q-mr-sm" />
      <q-separator dark vertical inset />
      <q-btn stretch flat :icon="home.icon" @click="handleFavClick(home.coords)" />

      <q-space />

      <q-btn-dropdown stretch flat label="Favorites">
        <q-list>
          <q-item
            v-for="fav in favorites"
            :key="fav.id"
            clickable
            v-ripple
            v-close-popup
            @click="handleFavClick(fav.coords)"
          >
            <q-item-section avatar>
              <q-avatar :icon="fav.icon" color="primary" text-color="white" />
            </q-item-section>
            <q-item-section>
              <q-item-label>{{ fav.name }}</q-item-label>
           </q-item-section>
        </q-item>
        </q-list>
      </q-btn-dropdown>
    </q-toolbar>
    <l-map @ready="onMapReady" ref="mapRef" :zoom="zoom" :center="center" style="height: 500px; width: 100%;" @click="updateMarker">
      <l-tile-layer
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        layer-type="base"
        name="OpenStreetMap"
        @click="updateMarker($event.latlng)"
      ></l-tile-layer>
     <l-marker :lat-lng="markerLatLng" @click="handleMarkerClick"></l-marker>
    </l-map>
     <StatusBar />
  </div>
</template>

<script setup lang="ts">
import { useQuasar } from "quasar";
import { Ref, ref } from "vue";
import "leaflet/dist/leaflet.css";
import { LMap, LTileLayer, LMarker } from "@vue-leaflet/vue-leaflet";
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';
import "leaflet-geosearch/dist/geosearch.css";
import "leaflet/dist/leaflet.css";
import type { Map, LeafletMouseEvent } from 'leaflet';
import SetLocationDialog from "components/SetLocationDialog.vue";
import StatusBar from "components/StatusBar.vue"
import { api } from "boot/axios";

const $q = useQuasar();
const mapRef = ref(null);
const zoom = ref(10);
const center: Ref<[number, number]> = ref([40.71278, -74.00594]);
const markerLatLng: Ref<[number, number]> = ref([40.71278, -74.00594]);
const responseMessage = ref("");

interface coords {
  lat: number;
  lng: number;
}

interface SearchControlProps {
  provider: OpenStreetMapProvider;
  showMarker: boolean;
  autoClose: boolean;
  updateMap: boolean;
  showPopup: boolean;
  style: 'button' | 'bar';
  acceptAutoLoad: boolean;
  autoComplete: boolean;
  autoCompleteDelay: number;
  retainZoomLevel: boolean;
  animateZoom: boolean;
  keepResult: boolean;
}
const onMapReady = (map: Map) => {
  const provider = new OpenStreetMapProvider();
  const searchOptions: SearchControlProps = {
    provider: provider,
    showMarker: false,
    autoClose: true,
    updateMap: true,
    showPopup: true,
    style: 'bar',
    acceptAutoLoad: true,
    autoComplete: true,
    autoCompleteDelay: 250,
    retainZoomLevel: false,
    animateZoom: true,
    keepResult: true
  };

  const searchControl = new GeoSearchControl(searchOptions);
  map.addControl(searchControl);
};

function updateMarker(event: LeafletMouseEvent) {
  markerLatLng.value = [event.latlng.lat, event.latlng.lng];
  center.value = [event.latlng.lat, event.latlng.lng];
}

function handleMarkerClick(event: LeafletMouseEvent) {
  $q.dialog({
    component: SetLocationDialog,
    componentProps: {
      lat: event.latlng.lat,
      lng: event.latlng.lng
    }
  }).onOk(() => {
    void setLocation({ lat: event.latlng.lat, lng: event.latlng.lng });
    console.log("Dialog confirmed");
  }).onCancel(() => {
    console.log("Dialog cancelled");
  }).onDismiss(() => {
    console.log("Dialog dismissed");
  });
}

function handleFavClick(coords: coords) {
  center.value = [coords.lat, coords.lng];
  markerLatLng.value = [coords.lat, coords.lng];
}

async function setLocation(coords: coords) {
  try {
    const payLoadData = {
      latitude: coords.lat,
      longitude: coords.lng
    };
    const { data } = await api({
      method: "post",
      url: "/set",
      data: payLoadData
    });
    console.log("Location set successfully:", data.data);
    responseMessage.value = `Location successfully set! New location: ${data.lat}, ${data.lng}`;
    $q.notify({ type: 'positive', message: responseMessage.value });
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error("Error setting location:", error.message);
      responseMessage.value = `Failed to set location: ${error.message}`;
    } else {
      console.error("Error setting location:", error);
      responseMessage.value = `Failed to set location: Unknown error`;
    }
    $q.notify({ type: 'negative', message: responseMessage.value });
  }
}

const home = {
  name: "Home",
  coords: {
    lat: 40.71278,
    lng: -74.00594
  },
  icon: "home"
};

const favorites = [
  {
    id: 1,
    name: "Central Park",
    coords: {
      lat: 40.785091,
      lng: -73.968285
    },
    icon: "park"
  },
  {
    id: 2,
    name: "Times Square",
    coords: {
      lat: 40.758896,
      lng: -73.985130,
    },
    icon: "star"
  },
  {
    id: 3,
    name: "Empire State Building",
    coords: {
      lat: 40.748817,
      lng: -73.985428
    },
    icon: "building"
  }
];
</script>

<style>
.l-map {
  height: 100vh;
  width: 100vw;
}
</style>
