<script lang="ts">
	import { DatePicker } from 'bits-ui';
	import { CalendarDate, today, getLocalTimeZone } from '@internationalized/date';
	import { Calendar, ChevronLeft, ChevronRight } from 'lucide-svelte';
	import { cn } from '$lib/utils';

	interface Props {
		/** The selected date value */
		value?: CalendarDate | undefined;
		/** Callback when date changes */
		onValueChange?: (date: CalendarDate | undefined) => void;
		/** Placeholder text */
		placeholder?: string;
		/** Whether the picker is disabled */
		disabled?: boolean;
		/** Minimum allowed date */
		minValue?: CalendarDate;
		/** Maximum allowed date */
		maxValue?: CalendarDate;
		/** Additional classes for the trigger */
		class?: string;
		/** ID for form association */
		id?: string;
		/** Name for form submission */
		name?: string;
	}

	let {
		value = $bindable(),
		onValueChange,
		placeholder = 'Select a date',
		disabled = false,
		minValue,
		maxValue,
		class: className = '',
		id,
		name
	}: Props = $props();

	let open = $state(false);

	function handleValueChange(newValue: CalendarDate | undefined) {
		value = newValue;
		onValueChange?.(newValue);
		open = false;
	}

	const formattedDate = $derived(
		value
			? value.toDate(getLocalTimeZone()).toLocaleDateString('en-US', {
					year: 'numeric',
					month: 'long',
					day: 'numeric'
				})
			: ''
	);

	// Convert to ISO string for hidden form input
	const isoDate = $derived(
		value ? `${value.year}-${String(value.month).padStart(2, '0')}-${String(value.day).padStart(2, '0')}` : ''
	);
</script>

<DatePicker.Root
	bind:value
	bind:open
	onValueChange={handleValueChange}
	{minValue}
	{maxValue}
>
	<DatePicker.Input
		{id}
		class={cn(
			'flex h-11 w-full items-center justify-between rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm ring-offset-white transition-colors',
			'focus-within:outline-none focus-within:ring-2 focus-within:ring-monaco-500 focus-within:ring-offset-2',
			'hover:border-slate-300',
			disabled && 'cursor-not-allowed opacity-50',
			className
		)}
	>
		{#snippet children({ segments })}
			<div class="flex items-center gap-1">
				{#each segments as { part, value: segValue }}
					{#if part === 'literal'}
						<span class="text-slate-400">{segValue}</span>
					{:else}
						<DatePicker.Segment
							{part}
							class={cn(
								'rounded px-1 py-0.5 tabular-nums',
								'focus:outline-none focus:bg-monaco-100 focus:text-monaco-900',
								'data-[placeholder]:text-slate-400',
								'hover:bg-slate-100'
							)}
						>
							{segValue}
						</DatePicker.Segment>
					{/if}
				{/each}
			</div>
			<DatePicker.Trigger
				class={cn(
					'rounded p-2 transition-colors',
					'hover:bg-slate-100',
					'focus:outline-none focus:ring-2 focus:ring-monaco-500 focus:ring-offset-2',
					disabled && 'pointer-events-none'
				)}
				{disabled}
			>
				<Calendar class="h-4 w-4 text-slate-500" />
			</DatePicker.Trigger>
		{/snippet}
	</DatePicker.Input>

	<DatePicker.Content
		class="z-50 rounded-xl border border-slate-200 bg-white p-3 sm:p-4 shadow-xl w-[calc(100vw-2rem)] sm:w-auto max-w-[320px]"
		sideOffset={8}
	>
		<DatePicker.Calendar>
			{#snippet children({ months, weekdays })}
				<DatePicker.Header class="mb-4 flex items-center justify-between">
					<DatePicker.PrevButton
						class={cn(
							'flex h-10 w-10 sm:h-8 sm:w-8 items-center justify-center rounded-lg transition-colors',
							'hover:bg-slate-100 active:bg-slate-200',
							'focus:outline-none focus:ring-2 focus:ring-monaco-500',
							'disabled:pointer-events-none disabled:opacity-50'
						)}
					>
						<ChevronLeft class="h-5 w-5 sm:h-4 sm:w-4" />
					</DatePicker.PrevButton>
					<DatePicker.Heading class="text-sm font-semibold text-slate-900" />
					<DatePicker.NextButton
						class={cn(
							'flex h-10 w-10 sm:h-8 sm:w-8 items-center justify-center rounded-lg transition-colors',
							'hover:bg-slate-100 active:bg-slate-200',
							'focus:outline-none focus:ring-2 focus:ring-monaco-500',
							'disabled:pointer-events-none disabled:opacity-50'
						)}
					>
						<ChevronRight class="h-5 w-5 sm:h-4 sm:w-4" />
					</DatePicker.NextButton>
				</DatePicker.Header>

				{#each months as month}
					<DatePicker.Grid class="w-full border-collapse">
						<DatePicker.GridHead>
							<DatePicker.GridRow class="flex w-full">
								{#each weekdays as day}
									<DatePicker.HeadCell
										class="w-10 sm:w-9 flex-1 text-center text-xs font-medium text-slate-500"
									>
										{day.slice(0, 2)}
									</DatePicker.HeadCell>
								{/each}
							</DatePicker.GridRow>
						</DatePicker.GridHead>
						<DatePicker.GridBody>
							{#each month.weeks as weekDates}
								<DatePicker.GridRow class="flex w-full">
									{#each weekDates as date}
										<DatePicker.Cell {date} month={month.value} class="flex-1 p-0.5">
											<DatePicker.Day
												class={cn(
													'flex h-10 w-10 sm:h-9 sm:w-9 items-center justify-center rounded-lg text-sm transition-colors min-h-[40px]',
													'hover:bg-slate-100',
													'focus:outline-none focus:ring-2 focus:ring-monaco-500 focus:ring-inset',
													'data-[today]:font-bold data-[today]:text-monaco-600',
													'data-[selected]:bg-monaco-600 data-[selected]:text-white data-[selected]:hover:bg-monaco-700',
													'data-[outside-month]:text-slate-300 data-[outside-month]:pointer-events-none',
													'data-[disabled]:text-slate-300 data-[disabled]:pointer-events-none',
													'data-[unavailable]:text-slate-300 data-[unavailable]:line-through data-[unavailable]:pointer-events-none'
												)}
											/>
										</DatePicker.Cell>
									{/each}
								</DatePicker.GridRow>
							{/each}
						</DatePicker.GridBody>
					</DatePicker.Grid>
				{/each}
			{/snippet}
		</DatePicker.Calendar>
	</DatePicker.Content>
</DatePicker.Root>

<!-- Hidden input for form submission -->
{#if name}
	<input type="hidden" {name} value={isoDate} />
{/if}
