<script setup lang="ts">
import {Address, AddressReference} from "ChillMainAssets/types";
import SearchBar from "ChillMainAssets/vuejs/AddressPicker/Component/SearchBar.vue";
import {
    AddressAggregated,
    AssociatedPostalCode, fetchAddressReference,
    getAddressesAggregated,
    getPostalCodes,
} from "ChillMainAssets/vuejs/AddressPicker/driver/local-search";
import { Ref, ref } from "vue";
import AddressAggregatedList from "ChillMainAssets/vuejs/AddressPicker/Component/AddressAggregatedList.vue";
import AddressDetailsForm from "ChillMainAssets/vuejs/AddressPicker/Component/AddressDetailsForm.vue";

interface AddressPickerProps {
    suggestions?: Address[];
}

const props = withDefaults(defineProps<AddressPickerProps>(), {
    suggestions: () => [],
});

const addresses: Ref<AddressAggregated[]> = ref([]);
const postalCodes: Ref<AssociatedPostalCode[]> = ref([]);
const searchTokens: Ref<string[]> = ref([]);
const addressReference: Ref<AddressReference|null> = ref(null);

let abortControllerSearchAddress: null | AbortController = null;
let abortControllerSearchPostalCode: null | AbortController = null;

const onSearch = async function (search: string): Promise<void> {
    performSearchForAddress(search);
    performSearchForPostalCode(search);
    searchTokens.value = [search];
};

const onPickPosition = async (id: string) => {
    console.log('Pick Position', id);
    addressReference.value = await fetchAddressReference(id);
}

const performSearchForAddress = async (search: string): Promise<void> => {
    if (null !== abortControllerSearchAddress) {
        abortControllerSearchAddress.abort();
    }

    if ("" === search) {
        addresses.value = [];
        abortControllerSearchAddress = null;
        return;
    }

    abortControllerSearchAddress = new AbortController();

    console.log("onSearch", search);
    try {
        addresses.value = await getAddressesAggregated(
            search,
            abortControllerSearchAddress,
        );
        abortControllerSearchAddress = null;
    } catch (e: unknown) {
        if (e instanceof DOMException && e.name === "AbortError") {
            console.log("search aborted for:", search);

            return;
        }

        throw e;
    }
};

const performSearchForPostalCode = async (search: string): Promise<void> => {
    if (null !== abortControllerSearchPostalCode) {
        abortControllerSearchPostalCode.abort();
    }

    if ("" === search) {
        addresses.value = [];
        abortControllerSearchPostalCode = null;
        return;
    }

    abortControllerSearchPostalCode = new AbortController();

    console.log("onSearch", search);
    try {
        postalCodes.value = await getPostalCodes(
            search,
            abortControllerSearchPostalCode,
        );
        abortControllerSearchPostalCode = null;
    } catch (e: unknown) {
        if (e instanceof DOMException && e.name === "AbortError") {
            console.log("search postal code aborted for:", search);

            return;
        }

        throw e;
    }
};
</script>

<template>
    <search-bar @search="onSearch"></search-bar>
    <div class="address-pick-content">
        <div>
            <address-aggregated-list :addresses="addresses" :search-tokens="searchTokens" @pick-position="(id) => onPickPosition(id)"></address-aggregated-list>
        </div>
        <div v-if="addressReference !== null">
            <address-details-form :address="addressReference"></address-details-form>
        </div>
    </div>

</template>

<style scoped lang="scss">
.address-pick-content {
    display: flex;
    flex-direction: row;
}
</style>
