<script lang="ts">
	import {
		CalendarDate,
		today,
		getLocalTimeZone,
		type TimeDuration
	} from '@internationalized/date';
	import Button from '$lib/Button.svelte';
	import ActionSelect from '$lib/ActionSelect.svelte';
	import Checkbox, { type CheckboxState } from '$lib/Checkbox.svelte';
	import Combobox from '$lib/Combobox.svelte';
	import DateInput from '$lib/DateInput.svelte';
	import Dialog from '$lib/Dialog.svelte';
	import FramelessButton from '$lib/FramelessButton.svelte';
	import InputGroup from '$lib/InputGroup.svelte';
	import Link from '$lib/Link.svelte';
	import PinInput from '$lib/PinInput.svelte';
	import RadioGroup from '$lib/RadioGroup.svelte';
	import StyledRawInput from '$lib/StyledRawInput.svelte';
	import TextInput from '$lib/TextInput.svelte';
	import TimeInput, { formatTime } from '$lib/TimeInput.svelte';
	import ToggleGroup from '$lib/ToggleGroup.svelte';
	import ToggleSelect from '$lib/ToggleSelect.svelte';
	import { Toolbar } from '$lib/Toolbar';
	import {
		ArrowUUpLeft,
		ArrowUUpRight,
		DotsThreeOutlineVertical,
		Plus,
		TextB,
		TextItalic,
		TextStrikethrough,
		TextUnderline
	} from 'phosphor-svelte';
	import { createLazyComponent, type ComboboxOption, type Option } from '$lib';
	import Tabs from '$lib/Tabs.svelte';
	import { Time } from '@internationalized/date';
	import { onMount, type Component } from 'svelte';
	import ErrorBox from '$lib/ErrorBox.svelte';
	import TextareaInput from '$lib/TextareaInput.svelte';
	import DurationInput, { formatDuration } from '$lib/DurationInput.svelte';

	// Lazy-load heavy components
	let PhoneInput = createLazyComponent(() => import('$lib/PhoneInput.svelte'));
	let TimezoneInput = createLazyComponent(() => import('$lib/TimezoneInput.svelte'));

	// Load heavy components on mount
	onMount(() => {
		PhoneInput.load();
		TimezoneInput.load();
	});

	const comboboxOptions = [
		{ value: 'option1', label: 'Option 1' },
		{ value: 'option2', label: 'Option 2' },
		{ value: 'option3', label: 'Option 3', disabled: true }
	];
	let lazyOptions: ComboboxOption[] = $state([]);
	let dateInputValue = $state<CalendarDate | undefined>(undefined);
	let checkboxValue = $state<CheckboxState>('indeterminate');
	let dialogOpen = $state(false);
	let scrollableDialogOpen = $state(false);
	let toggleOptions: Option[] = $state([
		'item one',
		'item two',
		{ value: 'complex', label: 'Complex item' }
	]);
	let timeValue = $state<Time | null>(null);
	let durationValue = $state<TimeDuration | null>(null);

	const toolbar = new Toolbar();
	const fontGroup = toolbar.group();
	const boldToggle = fontGroup.toggle();
	const boldStore = boldToggle.store;
</script>

<title>sui</title>

<h1 class="mb-4 text-3xl font-bold">sui — Opinionated Svelte 5 UI toolkit</h1>

<p class="mb-4">
	Welcome to the Svelte UI toolkit! This is a collection of components and utilities designed to
	help you build Svelte applications quickly and efficiently.
</p>

<h2 class="mb-2 text-2xl font-semibold">Component Library</h2>

<div class="component">
	<p class="title">Button, Frameless Button, & Link</p>
	<div class="flex gap-4">
		<Button icon={{ component: Plus }} loading={false} onclick={() => alert('Button clicked!')}
			>Click Me</Button
		>
		<Button icon={{ component: Plus }} loading={true} onclick={() => alert('Button clicked!')}
			>Loading Button</Button
		>

		<FramelessButton icon={{ component: Plus }}>Click Me</FramelessButton>

		<Link href="https://svelte.dev">Visit Svelte</Link>

		<Button onclick={() => (dialogOpen = true)}>Open Dialog</Button>
		<Button onclick={() => (scrollableDialogOpen = true)}>Open Scrollable Dialog</Button>
	</div>
</div>

<div class="component">
	<p class="title">Action Select</p>

	<div class="flex gap-2">
		<ActionSelect
			class="basis-1/2"
			stateless
			label="Stateless Action"
			options={[
				{ label: 'Yeet' },
				{ label: 'Yote' },
				{ label: 'Yote and Yeet' },
				{ label: 'Disabled Action', disabled: true }
			]}
		/>
		<ActionSelect
			class="basis-1/2"
			label="Stateful Action"
			value={{ label: 'Initial Action', onchoose: (value) => console.log('Chosen:', value) }}
			options={[
				{ label: 'Action 1', onchoose: (value) => console.log('Action 1 chosen:', value) },
				{ label: 'Action 2', onchoose: (value) => console.log('Action 2 chosen:', value) },
				{
					label: 'Disabled Action',
					disabled: true,
					onchoose: (value) => console.log('Disabled action chosen:', value)
				}
			]}
		/>
		<ActionSelect
			class="mt-7"
			options={[{ label: 'Option 1' }, { label: 'Option 2' }, { label: 'Option 3' }]}
			sameWidth={false}
			frameless={true}
			stateless={true}
		>
			<DotsThreeOutlineVertical class="text-sui-text" size="1.2em" />
		</ActionSelect>
	</div>
</div>

<div class="component">
	<p class="title">Combobox</p>

	<InputGroup>
		<Combobox
			name="example-combobox"
			label="Select an option"
			placeholder="Choose..."
			options={comboboxOptions}
			onchange={(e) => console.log('Selected:', e.value)}
			onvalidate={(e) => console.log('Validation:', e.detail)}
		/>

		<Combobox
			loading
			label="Loading stateless combobox"
			stateless
			placeholder="Choose..."
			options={[
				{ value: 'option1', label: 'Option 1' },
				{ value: 'option2', label: 'Option 2' },
				{ value: 'option3', label: 'Option 3' }
			]}
			onchange={(e) => console.log('Selected:', e.value)}
			onvalidate={(e) => console.log('Validation:', e.detail)}
		/>

		<Combobox
			icon={{
				component: Plus,
				props: {
					size: '1.2em'
				}
			}}
			label="Lazy combobox"
			placeholder="Choose..."
			options={lazyOptions}
			lazy
			onlazy={() => {
				setTimeout(() => {
					lazyOptions = [
						{ value: 'option1', label: 'Option 1' },
						{ value: 'option2', label: 'Option 2' },
						{ value: 'option3', label: 'Option 3' }
					];
				}, 2500);
			}}
		/>
		<Combobox
			label="Compact combobox"
			placeholder="Choose..."
			lazy
			compact
			options={comboboxOptions}
		/>
	</InputGroup>
</div>

<div class="component">
	<p class="title">Checkbox</p>

	<div class="flex items-center gap-4">
		<Checkbox
			name="example-checkbox"
			bind:value={checkboxValue}
			onchange={(value) => console.log('Checkbox value:', value)}
		>
			Agree to terms and conditions
		</Checkbox>
		<span>Checkbox is {checkboxValue}</span>
		<Button onclick={() => (checkboxValue = 'indeterminate')}>Set Indeterminate</Button>
	</div>

	<Checkbox>Example checkbox</Checkbox>
</div>

<div class="component">
	<p class="title">Dateinput</p>

	<div class="flex items-start gap-4">
		<DateInput bind:value={dateInputValue} />
		<div class="shrink-0">
			<Button
				icon={{ component: Plus }}
				onclick={() => {
					dateInputValue = today(getLocalTimeZone());
					console.log('Dateinput value set to:', dateInputValue);
				}}
			>
				Set Current Date
			</Button>
		</div>
		<span>Selected date is {dateInputValue}</span>
	</div>
</div>

<div class="component">
	<p class="title">Phone Input</p>
	{#if PhoneInput.loading}
		<div class="h-12 animate-pulse rounded bg-gray-200">Loading...</div>
	{:else if PhoneInput.error}
		<div class="text-red-500">Failed to load component</div>
	{:else}
		<PhoneInput.component label="Phone Number" name="phone" defaultISO="CA" />
	{/if}
</div>

<div class="component">
	<p class="title">Pin Input</p>
	<PinInput label="Please enter your 6-digit PIN" length={6} />
</div>

<div class="component">
	<p class="title">Radio Group</p>
	<RadioGroup
		name="example-radio-group"
		label="Choose an option"
		options={[
			'male',
			'female',
			'other',
			{ value: 'prefer_not_to_say', label: 'Prefer not to say' }
		]}
	/>
</div>

<div class="component">
	<p class="title">Styled Raw Input, Text Input, Disabled Input, Compact Input</p>

	<InputGroup>
		<StyledRawInput placeholder="Type here..." class="basis-1/2" />
		<TextInput label="Write something here" placeholder="Enter text..." class="basis-1/2" />
	</InputGroup>

	<InputGroup>
		<TextInput label="Disabled input" placeholder="You can't enter text" disabled />

		<TextInput label="Compact Input" placeholder="Small input field" compact />
	</InputGroup>
</div>

<div class="component">
	<p class="title">Multi-line input (textarea)</p>

	<TextareaInput label="Write your message here" />
</div>

<div class="component">
	<p class="title">Time & Duration Input</p>

	<InputGroup class="gap-8">
		<TimeInput label="Regular time input" name="example-time-input" />
		<TimeInput label="Compact time" compact bind:value={timeValue} />
		<DurationInput
			label="Duration input"
			name="example-duration-input"
			precision={{ min: 'hours', max: 'seconds' }}
			bind:value={durationValue}
		/>
		<DurationInput label="Compact duration" compact />
	</InputGroup>
	<InputGroup>
		<p>Selected time is {formatTime(timeValue, 'undefined')} ({timeValue?.toString()})</p>
		<Button
			onclick={() => {
				timeValue = new Time(15, 0);
			}}
		>
			Set 3:00 PM
		</Button>
		<p>Precise duration is {formatDuration(durationValue)}</p>
	</InputGroup>
</div>

<div class="component">
	<p class="title">TimezoneInput</p>

	{#if TimezoneInput.loading}
		<div class="h-12 animate-pulse rounded bg-gray-200">Loading...</div>
	{:else if TimezoneInput.error}
		<div class="text-red-500">Failed to load component</div>
	{:else}
		<TimezoneInput.component name="example-timezone" label="Pick your timezone" />
	{/if}
</div>

<div class="component">
	<p class="title">Toggle</p>

	<ToggleSelect name="example-toggle-select" class="mb-4">Toggle Me!</ToggleSelect>

	<ToggleGroup label="Toggle Group" options={toggleOptions} />

	<Button
		onclick={() => {
			toggleOptions.push({ value: 'new', label: 'New Option' });
		}}>Add Option</Button
	>
</div>

<div class="component">
	<p class="title">Toolbar</p>

	<div class="my-2">
		<p>Bold is enabled: {$boldStore}</p>
	</div>

	<div
		class="border-sui-text flex w-full min-w-max items-center gap-4 border-b
		bg-white px-3 py-3 text-neutral-700 shadow-xs"
	>
		<div class="flex items-center gap-1">
			<button type="button" class="item" title="Undo" aria-label="undo">
				<ArrowUUpLeft size="1.25em" />
			</button>
			<button type="button" class="item" title="Redo" aria-label="redo">
				<ArrowUUpRight size="1.25em" />
			</button>
		</div>
		<div class="bg-sui-text/50 w-[1px] self-stretch"></div>
		<div class="flex items-center gap-1">
			<button
				type="button"
				class="item"
				title="Toggle Bold"
				aria-label="bold"
				{@attach boldToggle.attachment}
			>
				<TextB size="1.25em" />
			</button>
			<button
				type="button"
				class="item"
				title="Toggle Italic"
				aria-label="italic"
				{@attach fontGroup.toggle().attachment}
			>
				<TextItalic size="1.25em" />
			</button>
			<button
				type="button"
				class="item"
				title="Toggle Underline"
				aria-label="underline"
				{@attach fontGroup.toggle().attachment}
			>
				<TextUnderline size="1.25em" />
			</button>
			<button
				type="button"
				class="item"
				title="Toggle Strikethrough"
				aria-label="strikethrough"
				{...fontGroup.toggle().props}
			>
				<TextStrikethrough size="1.25em" />
			</button>
		</div>
	</div>
</div>

<div class="component">
	<p class="title">Tabs</p>

	<Tabs
		pages={[
			{
				title: 'Dashboard',
				content: tab1
			},
			{
				title: 'Activity',
				content: tab2
			},
			{
				title: 'Settings',
				content: tab3
			}
		]}
	/>

	{#snippet tab1()}
		<h3 class="mb-4 text-2xl font-bold">Dashboard Overview</h3>
		<div class="grid grid-cols-2 gap-4">
			<div class="rounded bg-blue-100 p-4">
				<h4 class="font-semibold">Total Users</h4>
				<p class="text-3xl font-bold text-blue-600">1,247</p>
			</div>
			<div class="rounded bg-green-100 p-4">
				<h4 class="font-semibold">Revenue</h4>
				<p class="text-3xl font-bold text-green-600">$12,450</p>
			</div>
		</div>
	{/snippet}

	{#snippet tab2()}
		<h3 class="mb-3 text-xl font-semibold">Recent Activity</h3>
		<ul class="space-y-2">
			<li class="flex items-center gap-2">
				<span class="h-2 w-2 rounded-full bg-green-500"></span>
				<span>User John Doe logged in</span>
			</li>
			<li class="flex items-center gap-2">
				<span class="h-2 w-2 rounded-full bg-blue-500"></span>
				<span>New order #1234 received</span>
			</li>
			<li class="flex items-center gap-2">
				<span class="h-2 w-2 rounded-full bg-yellow-500"></span>
				<span>System backup completed</span>
			</li>
		</ul>
	{/snippet}

	{#snippet tab3()}
		<h3 class="mb-3 text-xl font-semibold">Settings</h3>
		<form class="space-y-3">
			<div class="flex items-center gap-2">
				<input type="checkbox" id="notifications" checked />
				<label for="notifications">Enable notifications</label>
			</div>
			<div class="flex items-center gap-2">
				<input type="checkbox" id="darkmode" />
				<label for="darkmode">Dark mode</label>
			</div>
			<button type="button" class="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600">
				Save Changes
			</button>
		</form>
	{/snippet}
</div>

<!-- Regular Dialog Demo -->
<Dialog
	bind:open={dialogOpen}
	title="Dialog Title"
	size="sm"
	controls={{
		ok: {
			action: (dialog) => {
				dialog.close();
				alert('Dialog submitted!');
			}
		}
	}}
	onopen={(dialog) => {
		dialog.error('Example error message!');
		dialog.loading();
		setTimeout(() => {
			dialog.loaded();
		}, 2000);
	}}
>
	<p>This is a dialog content area.</p>
</Dialog>

<!-- Scrollable Dialog Demo -->
<Dialog bind:open={scrollableDialogOpen} title="Scrollable Dialog" size="sm">
	<div class="space-y-4">
		<p>
			Ullamco nulla sunt laboris esse commodo irure id pariatur est irure eiusmod. Cupidatat Lorem
			ad deserunt non culpa aliqua qui qui ut reprehenderit minim consequat amet. Qui elit ipsum
			dolor enim laboris. Exercitation sint esse dolore enim irure veniam esse incididunt fugiat.
		</p>
		<p>
			In elit tempor quis enim id fugiat cillum consectetur minim sint ex. Minim reprehenderit culpa
			sunt in reprehenderit. Amet in minim in nulla officia fugiat laborum velit dolor laborum
			deserunt aliqua nostrud.
		</p>
		<p>
			Ad dolor ad nisi est fugiat anim aute amet. Fugiat excepteur proident incididunt anim sunt.
			Proident quis dolor ea voluptate esse commodo voluptate quis culpa cupidatat excepteur.
		</p>
		<p>
			Cillum ut laboris laboris ea ex ex. Aliquip magna irure eiusmod qui eiusmod. Mollit id et
			incididunt sint mollit anim cillum reprehenderit exercitation labore incididunt culpa. Officia
			et ad occaecat quis ipsum. Culpa quis cupidatat reprehenderit reprehenderit incididunt
			excepteur quis minim. Laboris cupidatat laborum est ipsum esse sint aliqua cillum laborum est
			cillum dolore cupidatat pariatur. Dolor ipsum cillum enim esse consectetur dolor sunt magna.
		</p>
		<p>
			Eu cillum reprehenderit Lorem duis sunt. Mollit laborum tempor magna dolor ad ipsum do fugiat
			nisi quis culpa tempor veniam officia. Voluptate irure labore aliqua elit officia nulla dolor.
			Lorem duis ea ea commodo deserunt minim enim. Excepteur non magna cupidatat ea eiusmod dolore
			elit dolor veniam cupidatat. Amet voluptate culpa ut ex consequat culpa cillum. Exercitation
			ex voluptate incididunt laboris qui sint id quis in aliqua excepteur incididunt.
		</p>
	</div>
</Dialog>

<style lang="postcss">
	@reference '$lib/styles/tailwind.css';

	.component .title {
		@apply mb-2 text-lg font-semibold;
	}

	.component {
		@apply mb-6 rounded-lg border p-4;
	}

	.item {
		@apply flex items-center;
		padding: theme('spacing.1');
		border-radius: theme('borderRadius.md');

		&:hover {
			background-color: theme('colors.sui-secondary.100');
		}

		&[data-state='on'] {
			background-color: theme('colors.sui-secondary.200');
			color: theme('colors.sui-accent.900');
		}

		/* &:focus {
			@apply ring-accent-400 ring-2;
		} */
	}

	.separator {
		width: 1px;
		background-color: theme('colors.neutral.300');
		align-self: stretch;
	}
</style>
