<template>
  <q-dialog ref="dlgRef" persistent>
    <q-card class="bg-dark text-grey-1 add-loc-card q-pa-sm" v-if="operation == 'clear'">
      <q-toolbar>
        <q-avatar icon="mdi-star" color="secondary" text-color="yellow" />
        <q-toolbar-title>Clear Favorite</q-toolbar-title>
      </q-toolbar>
      <q-card-section class="q-ml-lg">
        Are you sure you want to clear favorite {{ formData.name }}?
      </q-card-section>
      <q-separator />
      <q-card-actions align="right">
        <q-btn flat label="OK" @click="onOkClick" />
        <q-btn flat label="Cancel" @click="onDialogCancel" />
      </q-card-actions>
    </q-card>
    <q-card class="bg-dark text-grey-1 add-loc-card q-pa-sm" v-else>
      <q-toolbar>
        <q-avatar icon="mdi-star" color="secondary" text-color="yellow" />
        <q-toolbar-title v-if="!isFavorite && operation == 'set'"
          >Save Location as Favorite</q-toolbar-title
        >
        <q-toolbar-title v-else-if="!isFavorite && operation == 'edit'"
          >Edit Favorite</q-toolbar-title
        >
      </q-toolbar>
      <q-card-section class="q-ml-lg">
        <q-input
          color="secondary"
          v-model="formData.name"
          label="Favorite Name"
          autofocus
          @keyup.enter="onOkClick"
          style="max-width: 250px"
        />
        <div class="flex col q-col-gutter-md">
          <q-select
            color="accent"
            v-model="formData.category"
            :options="categories"
            label="Category"
            use-input
            new-value-mode="add-unique"
            style="max-width: 150px"
          >
            <template v-slot:no-option>
              <q-item>
                <q-item-section class="text-grey"> No results or loading... </q-item-section>
              </q-item>
            </template>
          </q-select>
          <q-select
            color="accent"
            v-model="formData.icon"
            :options="filteredIcons"
            option-label="name"
            option-value="icon"
            emit-value
            map-options
            use-input
            clearable
            label="Select Icon"
            @filter="iconFilterFcn"
            style="max-width: 150px"
          >
            <template v-slot:append>
              <q-icon
                :name="formData.icon ? formData.icon : 'mdi-library'"
                class="cursor-pointer"
              />
            </template>
            <template v-slot:option="scope">
              <q-item v-bind="scope.itemProps">
                <q-item-section avatar>
                  <q-icon :name="scope.opt.icon" />
                </q-item-section>
                <q-item-section>
                  <q-item-label>{{ scope.opt.name }}</q-item-label>
                </q-item-section>
              </q-item>
            </template>
          </q-select>
        </div>
        <div class="flex col q-col-gutter-md">
          <q-input
            v-model="formData.longitude"
            label="Longitude"
            style="max-width: 150px"
            color="secondary"
            readonly
          />
          <q-input
            v-model="formData.latitude"
            label="Latitude"
            style="max-width: 150px"
            color="secondary"
            readonly
          />
        </div>
      </q-card-section>
      <q-separator />
      <q-card-actions align="right">
        <q-btn flat label="OK" @click="onOkClick" />
        <q-btn flat label="Cancel" @click="onDialogCancel" />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script setup lang="ts">
import { useFavoriteStore } from 'stores/favorite';
import { useDialogPluginComponent } from 'quasar';
import type { Favorite } from 'components/models';
import { computed, onMounted, reactive, ref } from 'vue';
import { reverseGeocodeRateLimited } from 'functions/reverseGeocodeSocket';
import iconList from '@quasar/extras/mdi-v7/icons.json';

interface Props {
  lat: number;
  lng: number;
  isFavorite: boolean;
  operation: string;
}

const favoriteStore = useFavoriteStore();

const props = defineProps<Props>();

defineEmits([...useDialogPluginComponent.emits]);

const { dialogRef: dlgRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();

const iconsList = ref(iconList);

interface FormattedIcon {
  name: string;
  icon: string;
}
const iconsListFormatted: FormattedIcon[] = iconsList.value.map((str) => {
  const name = str
    .replace(/^[a-z]+/, '')
    .replace(/([A-Z])/g, ' $1')
    .trim();
  const icon = str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  return { name, icon };
});

const filteredIcons = ref(iconsListFormatted.slice(0, 100));
const icon = ref();
const name = ref();
const address = ref();
const category = ref();
const categories = computed({
  get: () => favoriteStore.categories,
  set: (value) => {
    favoriteStore.categories = value;
  },
});
const formData: Favorite = reactive({
  name: name.value,
  longitude: props.lng,
  latitude: props.lat,
  category: category.value,
  icon: icon.value,
}) as Favorite;
const loading = ref(true);

function iconFilterFcn(val: string, update: (callback: () => void) => void) {
  update(() => {
    if (val === '') {
      filteredIcons.value = iconsListFormatted.slice(0, 100);
    } else {
      const needle = val.toLowerCase();
      filteredIcons.value = iconsListFormatted
        .filter(v =>
          v.name.toLowerCase().includes(needle) ||
          v.icon.toLowerCase().includes(needle)
        )
        .slice(0, 100);
    }
  });
}

function onOkClick() {
  if (props.isFavorite && props.operation === 'clear') {
    favoriteStore.favoriteControl({ command: 'delete', favorite: formData });
  }
  favoriteStore.favoriteControl({ command: 'set', favorite: formData });
  onDialogOK({ operation: props.operation, data: formData });
}

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

onMounted(async () => {
  try {
    loading.value = true;
    const response = await reverseGeocodeRateLimited(props.lat, props.lng);
    console.log('reverse geocode response: ', response);
    address.value = response.address;
    if (response.favorite) {
      formData.name = response.favorite.name;
      formData.category = response.favorite.category;
      formData.icon = response.favorite.icon;
    }
  } catch (error) {
    console.error('Error fetching reverse geocode:', error);
    throw error;
  } finally {
    await sleep(500);
    loading.value = false;
  }
});
</script>
<style lang="sass" scoped>
.add-loc-card
  width: 100%
  max-width: 450px
</style>
