<script lang="ts">
	import LabelWrapper from "$lib/components/atoms/label-wrapper.svelte";
	import Title from "$lib/components/atoms/title.svelte";
	import Input from "$lib/components/ui/input/input.svelte";
	import * as Select from "$lib/components/ui/select";
	import * as Popover from "$lib/components/ui/popover";
	import * as Command from "$lib/components/ui/command";
	import { Button } from "$lib/components/ui/button";
	import { COUNTRIES_SELECT } from "$lib/core/countries";
	import { capitalize } from "$lib/core/string.utils";
	import { PHONE_COUNTRY_CODES } from "@pkg/logic/core/data/phonecc";
	import { cn } from "$lib/utils";
	import { tick } from "svelte";
	import ChevronsUpDownIcon from "~icons/lucide/chevrons-up-down";
	import CheckIcon from "~icons/lucide/check";
	import type { CustomerInfoModel } from "../data";
	import { customerInfoVM } from "./customerinfo.vm.svelte";

	let { info = $bindable() }: { info: CustomerInfoModel } = $props();

	let phoneCodeOpen = $state(false);
	let phoneCodeTriggerRef = $state<HTMLButtonElement>(null!);

	function onSubmit(e: SubmitEvent) {
		e.preventDefault();
		customerInfoVM.validateCustomerInfo(info);
	}

	function debounceValidate() {
		customerInfoVM.debounceValidate(info);
	}

	function closePhoneCodeAndFocus() {
		phoneCodeOpen = false;
		tick().then(() => {
			phoneCodeTriggerRef?.focus();
		});
	}
</script>

<form action="#" class="flex w-full flex-col gap-4" onsubmit={onSubmit}>
	<!-- Name Fields -->
	<div class="flex flex-col gap-4 md:flex-row">
		<LabelWrapper label="First Name" error={customerInfoVM.errors.firstName}>
			<Input
				placeholder="First Name"
				bind:value={info.firstName}
				required
				oninput={() => debounceValidate()}
				minlength={1}
				maxlength={64}
			/>
		</LabelWrapper>

		<LabelWrapper
			label="Middle Name"
			error={customerInfoVM.errors.middleName}
		>
			<Input
				placeholder="Middle Name (Optional)"
				bind:value={info.middleName}
				oninput={() => debounceValidate()}
				maxlength={64}
			/>
		</LabelWrapper>

		<LabelWrapper label="Last Name" error={customerInfoVM.errors.lastName}>
			<Input
				placeholder="Last Name"
				bind:value={info.lastName}
				required
				oninput={() => debounceValidate()}
				minlength={1}
				maxlength={64}
			/>
		</LabelWrapper>
	</div>

	<!-- Email Field -->
	<LabelWrapper label="Email" error={customerInfoVM.errors.email}>
		<Input
			placeholder="Email"
			bind:value={info.email}
			type="email"
			oninput={() => debounceValidate()}
			required
			maxlength={128}
		/>
	</LabelWrapper>

	<!-- Phone Number Field -->
	<LabelWrapper label="Phone Number" error={customerInfoVM.errors.phoneNumber}>
		<div class="flex gap-2">
			<Popover.Root bind:open={phoneCodeOpen}>
				<Popover.Trigger bind:ref={phoneCodeTriggerRef}>
					{#snippet child({ props })}
						<Button
							{...props}
							variant="outline"
							class="w-32 justify-between"
							role="combobox"
							aria-expanded={phoneCodeOpen}
						>
							{info.phoneCountryCode || "Select"}
							<ChevronsUpDownIcon class="h-4 w-4 opacity-50" />
						</Button>
					{/snippet}
				</Popover.Trigger>
				<Popover.Content class="w-[300px] p-0">
					<Command.Root>
						<Command.Input placeholder="Search country..." class="h-9" />
						<Command.List class="command-scrollbar max-h-[300px]">
							<Command.Empty>No country found.</Command.Empty>
							<Command.Group>
								{#each PHONE_COUNTRY_CODES as { country, phoneCode } (country)}
									<Command.Item
										value={`${phoneCode} ${country}`}
										onSelect={() => {
											info.phoneCountryCode = phoneCode;
											debounceValidate();
											closePhoneCodeAndFocus();
										}}
									>
										<CheckIcon
											class={cn(
												"h-4 w-4 flex-shrink-0",
												info.phoneCountryCode !== phoneCode &&
													"text-transparent",
											)}
										/>
										<span class="flex flex-1 items-center justify-between gap-3">
											<span class="font-semibold text-gray-900">{phoneCode}</span>
											<span class="text-sm text-gray-600">{country}</span>
										</span>
									</Command.Item>
								{/each}
							</Command.Group>
						</Command.List>
					</Command.Root>
				</Popover.Content>
			</Popover.Root>

			<Input
				placeholder="Phone Number"
				type="tel"
				bind:value={info.phoneNumber}
				required
				oninput={() => debounceValidate()}
				class="flex-1"
				minlength={1}
				maxlength={20}
			/>
		</div>
	</LabelWrapper>

	<!-- Address Section -->
	<Title size="h5">Address Information</Title>

	<div class="flex flex-col gap-4 md:flex-row">
		<LabelWrapper label="Country" error={customerInfoVM.errors.country}>
			<Select.Root
				type="single"
				required
				onValueChange={(e) => {
					info.country = e;
					debounceValidate();
				}}
				name="country"
			>
				<Select.Trigger class="w-full">
					{capitalize(
						info.country.length > 0 ? info.country : "Select",
					)}
				</Select.Trigger>
				<Select.Content>
					{#each COUNTRIES_SELECT as country}
						<Select.Item value={country.value}>
							{country.label}
						</Select.Item>
					{/each}
				</Select.Content>
			</Select.Root>
		</LabelWrapper>

		<LabelWrapper label="State" error={customerInfoVM.errors.state}>
			<Input
				placeholder="State/Province"
				bind:value={info.state}
				required
				oninput={() => debounceValidate()}
				minlength={1}
				maxlength={128}
			/>
		</LabelWrapper>
	</div>

	<div class="flex flex-col gap-4 md:flex-row">
		<LabelWrapper label="City" error={customerInfoVM.errors.city}>
			<Input
				placeholder="City"
				bind:value={info.city}
				required
				minlength={1}
				maxlength={128}
				oninput={() => debounceValidate()}
			/>
		</LabelWrapper>

		<LabelWrapper label="Zip Code" error={customerInfoVM.errors.zipCode}>
			<Input
				placeholder="Zip/Postal Code"
				bind:value={info.zipCode}
				required
				minlength={1}
				maxlength={21}
				oninput={() => debounceValidate()}
			/>
		</LabelWrapper>
	</div>

	<LabelWrapper label="Address" error={customerInfoVM.errors.address}>
		<Input
			placeholder="Street Address"
			bind:value={info.address}
			required
			minlength={1}
			oninput={() => debounceValidate()}
		/>
	</LabelWrapper>

	<LabelWrapper
		label="Address 2 (Optional)"
		error={customerInfoVM.errors.address2}
	>
		<Input
			placeholder="Apartment, suite, etc. (Optional)"
			bind:value={info.address2}
			oninput={() => debounceValidate()}
		/>
	</LabelWrapper>
</form>
