<script lang="ts">
	import { API, api, inferOutput } from "astro-typesafe-api/client";

	export let name: string;
	export let readonly: boolean = false;
	export let city: string | null | undefined;
	export let zip: string | null = "";


	let hideZipDropdown: boolean = true;
	let zipCodes: inferOutput<API["postleitzahlen"]["GET"]> = [];

	async function fetchZipCodeInformation() {
		if (!zip || (zip.length < 2)) {
			return
		}

		try {
			const result = await api.postleitzahlen.GET.fetch({ plz: zip, limit: 10 });
			
			if (result.length > 0) {
				zipCodes = result;
				hideZipDropdown = false;
			}
		} catch(e) {
			console.error(e);
		}
	}

	function clickOutside(element: HTMLElement, callbackFunction: () => any) {
		function onClick(event: MouseEvent) {
			if (!element.contains(event.target as HTMLElement)) {
				callbackFunction();
			}
		}
		
		document.body.addEventListener('click', onClick);
		
		return {
			destroy() {
				document.body.removeEventListener('click', onClick);
			}
		}
	}

</script>

<div use:clickOutside={() => {
	hideZipDropdown = true;
}} class="relative">
	
	<input
		name={name}
		id={name}
		type="text"
		required
		readonly={readonly}
		{...$$restProps}
		bind:value={zip}
		on:input={fetchZipCodeInformation}
		on:focus={() => {
			if (zipCodes.length > 0) {
				hideZipDropdown = false
			}
		}}
		maxlength="5"
	/>

	<div data-cy="plz-container" class="absolute top-[calc(100%+4px)] flex flex-col left-0 bg-white py-1 shadow-md rounded-lg z-10" class:hidden={hideZipDropdown}>
		{#each zipCodes as zipCode}
			<button class="hover:bg-gray-100 cursor-pointer px-2 py-1 text-nowrap" type="button" tabindex="-1" on:click={() => {
				zip = zipCode.plz;
				city = zipCode.stadt;
				hideZipDropdown = true;
			}}>{zipCode.plz}, {zipCode.stadt}</button>
		{/each}
	</div>
</div>

<style>
	button:not(:last-of-type) {
		@apply border-b border-b-gray-200;
	}
</style>