<template>
  <form ref="addressFormRef" @submit="onSubmit">
      <div class="row">
        <div class="col-xxl-12 col-md-12">
            <div class="profile__input-box">
              <div class="profile__input">
		            <label for="address-default">{{ $t('Default') }}</label>
		            <ui-nice-select
                    ref="niceSelectRef"
                    :default-current="dataUserAddresses?.is_default ? 0 : 1"
                    :options="defaultOptions"
                    name="is_default"
                    v-bind="is_default"
                    @onChange="changeIsDefaultHandler"
                />
                <err-message :msg="errors.is_default" />
              </div>
            </div>
        </div>

        <div class="col-xxl-6 col-md-6">
            <div class="profile__input-box">
              <div class="profile__input">
		            <label for="address-label">{{ $t('Name') }}</label>
		            <input
                    id="address-label"
                    :placeholder="$t('Name')"
                    class="no-icon"
                    name="label"
                    type="text"
                    v-bind="label"
                >
              </div>
              <err-message :msg="errors.label" />
            </div>
        </div>

        <div class="col-xxl-6 col-md-6">
            <div class="profile__input-box">
              <div class="profile__input">
		            <label for="postal_code-label">{{ $t('Postal code') }}</label>
		            <input
                    id="postal_code-label"
                    :placeholder="$t('Postal code')"
                    class="no-icon"
                    name="postal_code"
                    type="text"
                    v-bind="postal_code"
                >
              </div>
              <err-message :msg="errors.postal_code" />
            </div>
        </div>

        <div class="col-xxl-12">
            <div class="profile__input-box">
              <div class="profile__input">
		            <label for="address-address">{{ $t('Address') }}</label>
		            <textarea
                    id="address-address"
                    :placeholder="$t('Address')"
                    class="no-icon"
                    v-bind="address"
                ></textarea>
                <err-message :msg="errors.address" />
              </div>
            </div>
        </div>

        <div class="col-xxl-12">
            <div class="profile__input-box">
              <div class="profile__input">
		            <label for="address-ship_to_location">{{ $t('Shipping Location') }}</label>
		            <textarea
                    id="address-ship_to_location"
                    :placeholder="$t('Shipping Location')"
                    class="no-icon"
                    v-bind="ship_to_location"
                ></textarea>
                <err-message :msg="errors.ship_to_location" />
              </div>
            </div>
        </div>

        <div class="col-xxl-12">
            <div class="profile__input-box">
              <div class="profile__input">
		            <label for="address-bill_to_location">{{ $t('Billing Location') }}</label>
		            <textarea
                    id="address-bill_to_location"
                    :placeholder="$t('Billing Location')"
                    class="no-icon"
                    v-bind="bill_to_location"
                ></textarea>
                <err-message :msg="errors.bill_to_location" />
              </div>
            </div>
        </div>

        <div class="col-xxl-4">
            <div class="profile__input-box">
              <div class="profile__input">
                <label for="address-country_id">{{ $t('Country') }}</label>
                <ui-country-selection
                    v-bind="country_id"
                    :default-current="getCountryIdForUserAddress"
                    name="country_id"
                    @change="changeCountryIdHandler"
                    @update:modelValue="updateCountryIdModelValueHandler"
                />
                <err-message :msg="errors.country_id" />
              </div>
            </div>
        </div>

        <div class="col-xxl-4">
            <div class="profile__input-box">
              <div class="profile__input">
                <label for="address-governorates_id">{{ $t('Governorate') }}</label>
                <ui-governorate-selection
                    :disabled="!governorateSelectState.length"
                    v-bind="governorate_id"
                    :default-current="getGovernorateIdForUserAddress"
                    name="governorate_id"
                    @change="changeGovernorateIdHandler"
                    @update:modelValue="updateGovernorateIdModelValueHandler"
                />
                <err-message :msg="errors.governorate_id" />
              </div>
            </div>
        </div>

        <div class="col-xxl-4">
            <div class="profile__input-box">
              <div class="profile__input">
                <label for="address-cites_id">{{ $t('City') }}</label>
                <ui-city-selection
                    ref="niceSelectCityRef"
                    :disabled="!citySelectState.length"
                    v-bind="city_id"
                    :default-current="getCityIdForUserAddress"
                    name="city_id"
                    @change="changeCityIdHandler"
                    @update:modelValue="updateCityIdModelValueHandler"
                />
                <err-message :msg="errors.city_id" />
              </div>
            </div>
        </div>

        <div class="col-xxl-12">
            <div class="profile__input-box">
              <div class="profile__input">
                <div id="map" style="height: 400px; width: 100%;"></div>
                <err-message :msg="errors.lat_long" />
              </div>
            </div>
        </div>

        <div class="col-xxl-12">
            <div class="profile__btn">
              <button class="tp-btn me-1" type="submit" :disabled="loading">{{ $t(props?.add ? 'Add' : 'Update') }}</button>
              <button class="tp-btn me-1" type="button" @click="onCancel" :disabled="loading">{{ $t('Cancel') }}</button>
            </div>
        </div>
      </div>
  </form>
</template>

<script lang="ts" setup>
import {api} from "@/plugins/api";
import type {IUserAddresses} from "@/types/user-addresses-d-t";
import type {TResponse} from "@/types/response-d-t";
import {toast} from "vue3-toastify";
import formDataService from "@/services/formDataService";
import {useForm} from "vee-validate";
import * as yup from "yup";
import type {IUserAddressesFormValues} from "@/types/user-addresses-form-values-d-t";
import type {ISelect} from "@/types/select-d-t";
import {loadCountriesData} from "@/utils/loadCountriesData";

const countrySelectState = useState('countries_select', () => [] as ISelect[]);
const governorateSelectState = useState('governorates_select', () => [] as ISelect[]);
const citySelectState = useState('cities_select', () => [] as ISelect[]);
const countryState = useState('current_country_id', () => "");
const governorateState = useState('current_governorate_id', (): number | undefined => undefined);
const props = defineProps<{ add?: boolean }>();

const route = useRoute();
const router = useRouter();
const {t} = useI18n();

const id = computed(() => Number(route?.query?.id || 0) || 0);
const addressFormRef = ref<HTMLElement | HTMLFormElement | null>(null);
const niceSelectRef = ref<HTMLElement | null>(null);
const niceSelectCityRef = ref<HTMLElement | null>(null);
const globalLoading = useLoading();
const loading = ref<boolean>(false);
const defaultYesOption = {text: t('Yes'), value: true};
const defaultNoOption = {text: t('No'), value: false};
const defaultOptions = ref([
  defaultYesOption,
  defaultNoOption
]);

const {data: countries, default: default_country} = await loadCountriesData();

const {errors, handleSubmit, defineInputBinds, resetForm, setFieldValue} = useForm<IUserAddressesFormValues>({
  validationSchema: yup.object({
    label: yup.string().required().label(t("Label")),
    ship_to_location: yup.string().required().label(t("Shipping Location")),
    bill_to_location: yup.string().required().label(t("Billing Location")),
    country_id: yup.string().required().label(t("Country")),
    governorate_id: yup.string().required().label(t("Governorate")),
    city_id: yup.string().required().label(t("City")),
    // nighbourhood_id: yup.number().required().label(t("Neighbourhood")),
    address: yup.string().required().label(t("Address")),
    postal_code: yup.string().optional().label(t("Postal code")),
    lat_long: yup.string().required().label(t("Location")),
    is_default: yup.boolean().required().label(t("Default"))
  }),
});

const label = defineInputBinds('label');
const is_default = defineInputBinds('is_default');
const ship_to_location = defineInputBinds('ship_to_location');
const bill_to_location = defineInputBinds('bill_to_location');
const country_id = defineInputBinds('country_id');
const governorate_id = defineInputBinds('governorate_id');
const city_id = defineInputBinds('city_id');
// const nighbourhood_id = defineInputBinds('nighbourhood_id');
const postal_code = defineInputBinds('postal_code');
const address = defineInputBinds('address');
const lat_long = defineInputBinds('lat_long');
// setFieldValue('lat_long', `0,0`);
// setFieldValue('is_default', dataUserAddresses?.value?.is_default || false);

countryState.value = '';
governorateState.value = 0;

const assignValues = (res?: IUserAddresses) => {
  res = (res || {}) as IUserAddresses; // dataUserAddresses.value;

  countryState.value = '';
  governorateState.value = 0;

  setFieldValue('label', res?.label || '');
  setFieldValue('ship_to_location', res?.ship_to_location || '');
  setFieldValue('bill_to_location', res?.bill_to_location || '');
  setFieldValue('country_id', res?.country_id || (countrySelectState.value && getCountryIdForUserAddress.value ? countrySelectState.value?.[getCountryIdForUserAddress.value]?.value : ''));
  // setFieldValue('country_id', /*res?.country_db_id || */res?.country_id || '');
  setFieldValue('governorate_id', res?.governorate_id !== undefined ? String(res?.governorate_id || 0) : undefined);
  setFieldValue('city_id', res?.city_id !== undefined ? String(res?.city_id || 0) : undefined);
  // setFieldValue('nighbourhood_id', res?.nighbourhood_id || '');
  setFieldValue('postal_code', res?.postal_code || '');
  setFieldValue('address', res?.address || '');
  setFieldValue('lat_long', (res?.lat || res?.long) ? `${res?.lat || 0},${res?.long || 0}` : '');
  setFieldValue('is_default', res?.is_default || false);

  countryState.value = String(res?.country_id || '');
  governorateState.value = res?.governorate_id !== undefined ? Number(res?.governorate_id || 0) : undefined;
  // niceSelectRef.value.current = defaultNoOption;

  return res;
};

const {data: dataUserAddresses, pending: pendingUserAddresses, error, execute} = useLazyAsyncData(
    props?.add ? 'user-addresses-add' : `user-address-${id}`,
    () => {
      if (props?.add) {
        assignValues();

        // niceSelectRef.value.current = 0;
        return Promise.resolve({
          label: label.value.value,
          address: address.value.value,
          is_default: (is_default.value.value),
          ...lat_longValue.value,
          // ...lat_long.value.value,
        } as IUserAddresses);
      }

      return api.userAddressesData({id: id.value})
          .then((res: IUserAddresses[]) => {
            // debugger
            return (res[0] || {}) as IUserAddresses
          });
    },
    {
      watch: [route],
      immediate: false,
    }
);

await execute();

const onCancel = () => {
  // router.go(-1);
  reloadNuxtApp({path: router.resolve({hash: route.hash, path: route.path, query: {}}).href});
  scrollToTop();
};

const onSubmit = handleSubmit((values: IUserAddressesFormValues) => {
  if (loading.value) return;

  let _lat_long = (values?.lat_long || '0,0')?.split(',');
  // ["governorate_id", "city_id", "nighbourhood_id"].map((key: string) => {
  //   // @ts-ignore
  //   values[key] = !values[key] ? null : values[key]
  // });

  loading.value = true;
  globalLoading.start();
  $axios
      .post(`addresses` + (id.value ? `/${id.value}` : ''), formDataService({
        ...values,
        is_default: Number(values.is_default ? 1 : 0),
        lat: Number(_lat_long[0]),
        long: Number(_lat_long[1]),
      }))
      .then((response: { data: TResponse }) => {
        globalLoading.start();
        if (response?.data?.status === 'success') {
          nextTick(() => toast.success(response?.data?.message || t(props?.add ? 'Address added successfully' : 'Address updated successfully')))
              .then(()=>{
                resetForm();

                setTimeout(() => {
                  onCancel()
                }, 500);
              })
        } else {
          toast.error(t('Unexpected error. Please try again later.'));
        }
      })
      .catch((error) => {
        if (error?.response?.data?.message) {
          toast.error(error?.response?.data?.message);
        } else if (error?.message) {
          toast.error(error?.message);
        }

        console.error(error);
      })
      .finally(() => {
        setTimeout(() => {
          loading.value = false;
          globalLoading.stop();
        }, 100);
      });
});

const changeIsDefaultHandler = (e: { value: any; text: string }, index: number) => {
  // address.value.is_default = e.value;
  setFieldValue('is_default', (e.value));
  // niceSelectRef.value.current = e.value ? defaultYesOption : defaultNoOption;
};

const updateCountryIdModelValueHandler = (value: string) => {
  console.clear();
  console.log(319, 'Model value updated:', value);
};
const changeCountryIdHandler = (event: Event | { target?: HTMLSelectElement } | any) => {
  let v = String(event?.target?.value || '');
  setFieldValue('country_id', v);
  countryState.value = v;

  setFieldValue('governorate_id', undefined);
  governorateState.value = undefined;
  governorateSelectState.value = [];

  setFieldValue('city_id', undefined);
  citySelectState.value = [];
};
const updateGovernorateIdModelValueHandler = (value: string) => {
  console.clear();
  console.log(326, 'Model value updated:', value);
};
const changeGovernorateIdHandler = (event: Event | { target?: HTMLSelectElement } | any) => {
  let v: number|undefined = event?.target?.value === "" ? undefined : Number(event?.target?.value || 0);
  setFieldValue('governorate_id', v === undefined ? undefined : String(v));
  governorateState.value = v;

  setFieldValue('city_id', undefined);
  citySelectState.value = [];
};
const updateCityIdModelValueHandler = (value: string) => {
  console.clear();
  console.log(358, 'Model value updated:', value);
};
const changeCityIdHandler = (event: Event | { target?: HTMLSelectElement } | any) => {
  let v = Number(event?.target?.value || 0);
  setFieldValue('city_id', String(v));
};

const getCountryIdForUserAddress = computed(() => {
  let i: number|undefined = undefined;

  if (dataUserAddresses.value?.country_db_id) {
    i = Number(
        dataUserAddresses.value?.country_db_id || 0
    ) - 1;
  } else if (dataUserAddresses.value?.country_id) {
    i = Number(
        countrySelectState.value?.findIndex((item) => item?.value == dataUserAddresses.value?.country_id) || 0
    );
  } /*else if (default_country.value) {
    i = Number(
        countrySelectState.value?.findIndex((item) => item?.value == default_country.value) || 0
    );
  }*/

  if (i !== undefined) {
    i = i >= 0 ? i : undefined
  }

  return i;
});
const getGovernorateIdForUserAddress = computed((): number | undefined => {
  return dataUserAddresses.value?.governorate_id !== undefined ? Number(dataUserAddresses.value?.governorate_id || 0) : undefined;
})
const getCityIdForUserAddress = computed((): number | undefined => {
  return dataUserAddresses.value?.city_id !== undefined ? Number(dataUserAddresses.value?.city_id || 0) : undefined;
})

const lat_longValue = computed(() => {
  let v = (lat_long.value.value || '0,0')?.split(',');
  return {
    lat: Number(v?.[0]) || 0,
    long: Number(v?.[1]) || 0,
  }
});


onMounted(() => {
  setTimeout(() => {
    // @ts-ignore
    window.initMap = function () {
      // @ts-ignore
      const map = new google.maps.Map(document.getElementById("map"), {
        center: {lat: lat_longValue.value?.lat || 0, lng: lat_longValue.value?.long || 0},
        zoom: lat_long.value.value ? 17 : 5,
      });

      // @ts-ignore
      const marker = new google.maps.Marker({
        position: {lat: lat_longValue.value?.lat || 0, lng: lat_longValue.value?.long || 0},
        map: map,
        title: label.value.value || '',
      });

      map.addListener("click", (e: any) => {
        const newLat = e.latLng.lat();
        const newLng = e.latLng.lng();
        $axios.get(`https://nominatim.openstreetmap.org/search?q=${newLat},${newLng}&format=json&addressdetails=1`)
            .then(res => {
              let data = res?.data?.[0];
              setFieldValue('address', data?.display_name || address.value.value)
            })
        marker.setPosition({lat: newLat, lng: newLng});
        setFieldValue('lat_long', (newLat || newLng) ? `${newLat || 0},${newLng || 0}` : '');
      });
    };

    const script = document.createElement("script");
    script.src = `https://maps.googleapis.com/maps/api/js?key=${useRuntimeConfig()?.public?.googleMap}&callback=initMap`;
    script.async = true;
    script.defer = true;
    document.head.appendChild(script);
  }, 1000);

  assignValues(dataUserAddresses.value as IUserAddresses);
});

</script>