<script>
	import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index.js';
	import * as Select from '$lib/components/ui/select/index.js';
	import * as Popover from "$lib/components/ui/popover/index.js";
	import { Toggle } from '$lib/components/ui/toggle/index.js';
	import { Button } from '$lib/components/ui/button/index.js';
	import { Input } from '$lib/components/ui/input/index.js';
	import { Label } from '$lib/components/ui/label/index.js';
	import { Spinner } from '$lib/components/ui/spinner/index.js';
	import ReusableCalendar from '$lib/components/reusable/reusable-calendar.svelte';
	import { Badge } from '$lib/components/ui/badge/index.js';
	import * as InputGroup from '$lib/components/ui/input-group/index.js';
	import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
	import { Textarea } from '$lib/components/ui/textarea/index.js';
	import MoveLeftIcon from '@lucide/svelte/icons/move-left';
	import MoveRightIcon from '@lucide/svelte/icons/move-right';
	import BrushCleaningIcon from '@lucide/svelte/icons/brush-cleaning';
	import DeleteIcon from '@lucide/svelte/icons/delete';
	import Trash2Icon from '@lucide/svelte/icons/trash-2';
	import PlusIcon from '@lucide/svelte/icons/plus';
	import CornerDownLeftIcon from '@lucide/svelte/icons/corner-down-left';
	import CheckIcon from "@lucide/svelte/icons/check";
    import XIcon from "@lucide/svelte/icons/x";

	let {
		formState,
		formFields,
		mode = 'create',
		disabledResultTypes = [],
		disabledReferenceTypes = [],
		disabledSign = false,
		disabledFlag = false,
		joinFields = $bindable(),
		hiddenFields,
		handleTestTypeChange,
		handleResultTypeChange,
		handleRefTypeChange,
		onAddMember,
		onRemoveMember,
		//starthere
		tokens = [],
		cursorIndex = 0,
		onUnselectAll,
		onGetErrorStatus,
		onAddLiteral,
		onAddNewline,
		onSetCursor,
		operators,
		logicalop,
		comparisonop,
		onMoveCursorLeft,
		onMoveCursorRight,
		onDeleteChar,
		onClearExpression,
		onAddOperator,
		onAddValue,
	} = $props();


	let searchQuery = $state({});
	let dropdownOpen = $state({});

	let numberPopoverOpen = $state(false);
	let stringPopoverOpen = $state(false);
	let stringLiteralInput = $state('');
	let numberLiteralInput = $state(null);
	
	function getFilteredOptions(key) {
		const query = searchQuery[key] || '';
		if (!query) return formState.selectOptions?.[key] ?? [];

		return (formState.selectOptions?.[key] ?? []).filter((opt) =>
			opt.label.toLowerCase().includes(query.toLowerCase())
		);
	}

	async function initializeDefaultValues() {
		for (const group of formFields) {
			for (const row of group.rows) {
				for (const col of row.columns) {
					if (col.type === 'group') {
						for (const child of col.columns) {
							await handleDefaultValue(child);
						}
					} else {
						await handleDefaultValue(col);
					}
				}
			}
		}
	}

	async function handleDefaultValue(field) {
		if (!field.defaultValue || !field.optionsEndpoint) return;

		await formState.fetchOptions(field, formState.form);

		if (!formState.form[field.key]) {
			formState.form[field.key] = field.defaultValue;
		}
	}

	$effect(() => {
		initializeDefaultValues();
	});

	const expressionString = $derived(
		tokens.map(t => t.type === 'newline' ? '\n' : t.value).join(' ').replace(/ \n /g, '\n')
	);
</script>

{#snippet Fieldset({
	key,
	label,
	required,
	type,
	optionsEndpoint,
	options,
	optionsToggle,
	validateOn,
	dependsOn,
	endpointParamKey,
	valueKey,
	labelKey,
	txtKey
})}
	<div class="flex w-full flex-col gap-1.5">
		<div class="flex justify-between items-center w-full">
			<Label>{label}</Label>
			{#if required}
				<span class="text-destructive text-xl leading-none h-3.5">*</span>
			{/if}
			{#if key === 'FormulaCode' && formState.form.FormulaInput?.length}
				{@const inputStatus = onGetErrorStatus?.()}
				<div class="flex items-center gap-2 text-sm text-destructive">
					<span>Must included :</span>

					<div class="flex gap-1 flex-wrap">
						{#each inputStatus as item (item.value)}
							<Badge class="px-1 text-[10px]" variant={item.done ? 'default' : 'destructive'}>
								{item.value}
							</Badge>
						{/each}
					</div>
				</div>
			{/if}
		</div>

		<div class="relative flex flex-col items-center w-full">
			{#if type === 'text'}
				<Input
					type="text"
					bind:value={formState.form[key]}
					oninput={() => {
						if (validateOn?.includes('input')) {
							formState.validateField(key, formState.form[key], false);
						}
					}}
					onblur={() => {
						if (validateOn?.includes('blur')) {
							validateFieldAsync(key, mode, originalData?.[key]);
						}
					}}
					readonly={key === 'NumRefType' || key === 'TxtRefType' || key === 'Level'}
					disabled={key === 'Flag' && disabledFlag}
				/>
			{:else if type === 'email'}
				<Input
					type="email"
					bind:value={formState.form[key]}
					oninput={() => {
						if (validateOn?.includes('input')) {
							formState.validateField(key, formState.form[key], false);
						}
					}}
					onblur={() => {
						if (validateOn?.includes('blur')) {
							formState.validateField(key, formState.form[key], false);
						}
					}}
				/>
			{:else if type === 'number'}
				<Input
					type="number"
					bind:value={formState.form[key]}
					oninput={() => {
						if (validateOn?.includes('input')) {
							formState.validateField(key, formState.form[key], false);
						}
					}}
					onblur={() => {
						if (validateOn?.includes('blur')) {
							formState.validateField(key, formState.form[key], false);
						}
					}}
					onkeydown={(e) => ['e', 'E', '+', '-'].includes(e.key) && e.preventDefault()}
				/>
			{:else if type === 'textarea'}
				<Textarea
					class="flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
					oninput={() => {
						if (validateOn?.includes('input')) {
							formState.validateField(key, formState.form[key], false);
						}
					}}
					onblur={() => {
						if (validateOn?.includes('blur')) {
							formState.validateField(key, formState.form[key], false);
						}
					}}
					bind:value={formState.form[key]}
				/>
			{:else if type === 'select'}
				{@const selectedLabel =
					formState.selectOptions?.[key]?.find((opt) => opt.value === formState.form[key])?.label ||
					'Choose'}
				{@const filteredOptions = getFilteredOptions(key)}
				<Select.Root
					type="single"
					bind:value={formState.form[key]}
					onValueChange={(val) => {
						formState.form[key] = val;
						if (validateOn?.includes('input')) {
							formState.validateField?.(key, formState.form[key], false);
						}
						if (key === 'TestType') {
							handleTestTypeChange(val);
						}
						if (key === 'Province') {
							formState.form.City = '';
							if (formState.selectOptions) {
								formState.selectOptions.City = [];
							}
							if (formState.lastFetched) {
								formState.lastFetched.City = null;
							}
						}
						if (key === 'ResultType') {
							handleResultTypeChange(val);
						}
						if (key === 'RefType') {
							handleRefTypeChange(val);
						}
						if (key === 'HostType') {
							formState.form.HostID = '';
							formState.form.HostTestCode = '';
							formState.form.HostTestName = '';
							formState.selectOptions.HostTestCode = [];
							formState.selectOptions.HostTestName = [];
						}
						if (key === 'HostID') {
							formState.form.HostTestCode = '';
							formState.form.HostTestName = '';
							formState.selectOptions.HostTestCode = [];
							formState.selectOptions.HostTestName = [];
						}
						if (key === 'ClientType') {
							formState.form.ClientID = '';
							formState.form.ClientTestCode = '';
							formState.form.ClientTestName = '';
							formState.selectOptions.ClientTestCode = [];
							formState.selectOptions.ClientTestName = [];
						}
						if (key === 'ClientID') {
							formState.form.ClientTestCode = '';
							formState.form.ClientTestName = '';
							formState.selectOptions.ClientTestCode = [];
							formState.selectOptions.ClientTestName = [];
						}
					}}
					onOpenChange={(open) => {
						if (open) {
							if (options && options.length > 0) {
								if (formState.selectOptions) {
									formState.selectOptions[key] = options;
								}
							} else if (optionsEndpoint) {
								formState.fetchOptions?.(
									{ key, optionsEndpoint, dependsOn, endpointParamKey, valueKey, labelKey },
									formState.form
								);
							}
						}
					}}
				>
					<Select.Trigger class="w-full truncate">
						{selectedLabel}
					</Select.Trigger>
					<Select.Content>
						<div class="p-2">
							<input
								type="text"
								placeholder="Search..."
								class="w-full border rounded px-2 py-1 text-sm"
								bind:value={searchQuery[key]}
							/>
						</div>
						{#if formState.loadingOptions?.[key]}
							<Select.Item disabled value="loading">Loading...</Select.Item>
						{:else}
							{#if !required}
								<Select.Item value="">- None -</Select.Item>
							{/if}
							{#each filteredOptions as option}
								<Select.Item
									value={option.value}
									disabled={(key === 'ResultType' && disabledResultTypes.includes(option.value)) ||
										(key === 'RefType' && disabledReferenceTypes.includes(option.value))}
								>
									{option.label}
								</Select.Item>
							{/each}
						{/if}
					</Select.Content>
				</Select.Root>
			{:else if type === 'selectmultiple'}
				{@const filteredOptions = getFilteredOptions(key)}
				{@const currentValues = Array.isArray(formState.form[key]) ? formState.form[key] : []}
				<Select.Root
					type="multiple"
					value={currentValues.map((item) => item.value)}
					onValueChange={(val) => {
						const selectedObjects = (formState.selectOptions?.[key] ?? []).filter((opt) =>
							val.includes(opt.value)
						);
						formState.form[key] = selectedObjects;
						if (validateOn?.includes('input')) {
							formState.validateField?.(key, selectedObjects, false);
							formState.validateField?.('FormulaCode', formState.form.FormulaCode ?? '', false);
						}
					}}
					onOpenChange={(open) => {
						if (open && optionsEndpoint) {
							formState.fetchOptions?.(
								{ key, optionsEndpoint, dependsOn, endpointParamKey, valueKey, labelKey },
								formState.form
							);
						}
					}}
				>
					<Select.Trigger class="w-full">
						{currentValues.length
							? (formState.selectOptions?.[key] ?? [])
									.filter((o) => currentValues.some((f) => f.value === o.value))
									.map((o) => o.label)
									.join(', ')
							: 'Choose'}
					</Select.Trigger>
					<Select.Content>
						<div class="p-2">
							<input
								type="text"
								placeholder="Search..."
								class="w-full border rounded px-2 py-1 text-sm"
								bind:value={searchQuery[key]}
							/>
						</div>
						<Select.Group>
							{#if formState.loadingOptions?.[key]}
								<div class="p-2 text-sm text-muted-foreground">Loading...</div>
							{:else}
								{#if currentValues.length > 0}
									<Select.Separator />
									<button
										class="w-full px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground"
										onclick={() => onUnselectAll?.(key)}
									>
										Unselect All
									</button>
								{/if}
								{#each filteredOptions as opt (opt.value)}
									<Select.Item value={opt.value} label={opt.label}>
										{opt.label}
									</Select.Item>
								{/each}
							{/if}
						</Select.Group>
					</Select.Content>
				</Select.Root>
			{:else if type === 'date'}
				<ReusableCalendar
					bind:value={formState.form[key]}
					parentFunction={(dateStr) => {
						formState.form[key] = dateStr;
						if (validateOn?.includes('input')) {
							formState.validateField(key, dateStr, false);
						}
					}}
				/>
			{:else if type === 'signvalue'}
				<InputGroup.Root>
					<InputGroup.Input
						placeholder="Type here"
						bind:value={formState.form[txtKey]}
						oninput={() => {
							if (validateOn?.includes('input')) {
								formState.validateField('Low', formState.form[txtKey]);
								formState.validateField('LowSign');
								formState.validateField('High', formState.form[txtKey]);
								formState.validateField('HighSign');
							}
						}}
					/>
					<InputGroup.Addon align="inline-start">
						<DropdownMenu.Root
							onOpenChange={(open) => {
								dropdownOpen[key] = open;
								if (open && optionsEndpoint) {
									formState.fetchOptions?.(
										{ key, optionsEndpoint, valueKey, labelKey },
										formState.form
									);
								}
							}}
						>
							<DropdownMenu.Trigger>
								{#snippet child({ props })}
									<InputGroup.Button {...props} variant="ghost" disabled={disabledSign}>
										{formState.selectOptions?.[key]?.find(
											(opt) => opt.value === formState.form[key]
										)?.label || 'Choose'}
										<ChevronDownIcon />
									</InputGroup.Button>
								{/snippet}
							</DropdownMenu.Trigger>
							<DropdownMenu.Content align="start">
								{#if formState.loadingOptions?.[key]}
									<DropdownMenu.Item disabled>Loading...</DropdownMenu.Item>
								{:else}
									<DropdownMenu.Item
										onSelect={() => {
											formState.form[key] = '';
											dropdownOpen[key] = false;
											formState.validateField('LowSign');
											formState.validateField('HighSign');
										}}
									>
										- None -
									</DropdownMenu.Item>
									{#each formState.selectOptions?.[key] || [] as option}
										<DropdownMenu.Item
											onclick={() => {
												formState.form[key] = option.value;
												dropdownOpen[key] = false;
											}}
											onSelect={() => {
												formState.form[key] = option.value;
												formState.validateField('LowSign');
												formState.validateField('HighSign');
											}}
										>
											{option.label}
										</DropdownMenu.Item>
									{/each}
								{/if}
							</DropdownMenu.Content>
						</DropdownMenu.Root>
					</InputGroup.Addon>
				</InputGroup.Root>
			{:else if type === 'agejoin'}
				<div class="flex items-center gap-2 w-full">
					<InputGroup.Root>
						<InputGroup.Input
							type="number"
							bind:value={joinFields[key].YY}
							oninput={() => {
								if (validateOn?.includes('input')) {
									formState.validateField('AgeStart');
									formState.validateField('AgeEnd');
								}
							}}
						/>
						<InputGroup.Addon align="inline-end">
							<InputGroup.Text>Year</InputGroup.Text>
						</InputGroup.Addon>
					</InputGroup.Root>
					<InputGroup.Root>
						<InputGroup.Input
							type="number"
							bind:value={joinFields[key].MM}
							oninput={() => {
								if (validateOn?.includes('input')) {
									formState.validateField('AgeStart');
									formState.validateField('AgeEnd');
								}
							}}
						/>
						<InputGroup.Addon align="inline-end">
							<InputGroup.Text>Month</InputGroup.Text>
						</InputGroup.Addon>
					</InputGroup.Root>
					<InputGroup.Root>
						<InputGroup.Input
							type="number"
							bind:value={joinFields[key].DD}
							oninput={() => {
								if (validateOn?.includes('input')) {
									formState.validateField('AgeStart');
									formState.validateField('AgeEnd');
								}
							}}
						/>
						<InputGroup.Addon align="inline-end">
							<InputGroup.Text>Day</InputGroup.Text>
						</InputGroup.Addon>
					</InputGroup.Root>
				</div>
			{:else if type === 'formulabuilder'}
				<div class="flex flex-col gap-8 w-full">
					<div class="flex gap-1 w-full">
						<Button type="button" variant="outline" size="icon" onclick={onMoveCursorLeft}>
							<MoveLeftIcon class="w-4 h-4" />
						</Button>
						<div
							class="relative flex-1 min-h-[2rem] rounded-md border bg-background px-3 py-2 font-mono text-sm cursor-text focus-within:ring-1 focus-within:ring-ring"
							role="textbox"
							tabindex="0"
							onkeydown={(e) => {
								if (e.key === 'Backspace') { e.preventDefault(); onDeleteChar(); }
								if (e.key === 'ArrowLeft') onMoveCursorLeft();
								if (e.key === 'ArrowRight') onMoveCursorRight();
							}}
						>
							{#if tokens.length === 0}
								<span class="text-muted-foreground text-xs italic">Select test then click buttons below to build formula</span>
							{:else}
								{@const lines = (() => {
									const result = [[]];
									tokens.forEach((tok, idx) => {
										if (tok.type === 'newline') result.push([]);
										else result[result.length - 1].push({ tok, idx });
									});
									return result;
								})()}
								{#each lines as line, lineIdx}
									<div class="flex flex-wrap items-center gap-1 min-h-[28px] {lineIdx > 0 ? 'mt-1 pt-1 border-t border-dashed border-border' : ''}">
										{#each line as { tok, idx }}
											{#if cursorIndex === idx}
												<span class="animate-cursor inline-block h-5 w-0.5 bg-primary rounded"></span>
											{/if}
											<button
												type="button"
												class="inline-flex items-center px-2 py-0.5 rounded text-xs font-semibold border transition-colors"
												onclick={() => onSetCursor(idx + 1)}
											>
												{tok.value}
											</button>
										{/each}
										{#if line.length > 0 && cursorIndex === line[line.length - 1].idx + 1}
											<span class="animate-cursor inline-block h-5 w-0.5 bg-primary rounded"></span>
										{:else if line.length === 0 && lineIdx === lines.length - 1}
											<span class="animate-cursor inline-block h-5 w-0.5 bg-primary rounded"></span>
										{/if}
									</div>
								{/each}
							{/if}
						</div>
						<Button type="button" variant="outline" size="icon" onclick={onMoveCursorRight}>
							<MoveRightIcon class="w-4 h-4" />
						</Button>
						<Button type="button" variant="outline" size="icon" onclick={onDeleteChar}>
							<DeleteIcon class="w-4 h-4" />
						</Button>
						<Button type="button" variant="outline" size="icon" onclick={onClearExpression}>
							<BrushCleaningIcon class="w-4 h-4" />
						</Button>
						<Button type="button" variant="outline" size="icon" onclick={onAddNewline} title="New line">
							<CornerDownLeftIcon class="w-4 h-4" />
						</Button>
					</div>
					<div class="flex flex-col gap-4">
						{#if formState.form.FormulaInput?.length > 0}
							<div class="flex flex-col gap-4">
								<div class="flex flex-col gap-2">
									<Label class="uppercase tracking-wide">Selected Tests</Label>
									<div class="flex flex-wrap gap-2">
										{#each formState.form.FormulaInput as item (item)}
											<Button
												type="button"
												variant="outline"
												class="h-auto w-auto p-2"
												onclick={() => onAddValue?.(item.value)}
											>
												{item.value}
											</Button>
										{/each}
									</div>
								</div>
							</div>
						{/if}
						<div class="flex flex-col gap-4">
							<div class="flex flex-col gap-2">
								<Label class="uppercase tracking-wide">Custom Values</Label>
								<div class="flex flex-wrap gap-2">
									<Popover.Root bind:open={stringPopoverOpen}>
										<Popover.Trigger>
											{#snippet child({ props: triggerProps })}
											<Button
												{...triggerProps}
												type="button"
												variant="outline"
												class="h-auto w-auto p-2"
											>
												"abc"
											</Button>
											{/snippet}
										</Popover.Trigger>
										<Popover.Content class="w-64" side="bottom" align="start">
											<div>
												<div class="flex flex-col gap-3">
												<p class="text-sm font-semibold">Enter Text Value</p>
												<Input
													type="text"
													placeholder='e.g. F, POS, NEG'
													bind:value={stringLiteralInput}
													onkeydown={(e) => {
													if (e.key === 'Enter' && stringLiteralInput.trim()) {
														onAddLiteral(`"${stringLiteralInput.trim()}"`);
														stringLiteralInput = '';
													}
													}}
												/>
												<div class="flex justify-end gap-2">
													<Button
													type="button"
													size="sm"
													disabled={!stringLiteralInput.trim()}
													onclick={() => {
														onAddLiteral(`"${stringLiteralInput.trim()}"`);
														stringLiteralInput = '';
													}}
													>
													Add
													</Button>
												</div>
												</div>
											</div>
										</Popover.Content>
									</Popover.Root>
		
									<Popover.Root bind:open={numberPopoverOpen}>
										<Popover.Trigger>
											{#snippet child({ props: triggerProps })}
											<Button
												{...triggerProps}
												type="button"
												variant="outline"
												class="h-auto w-auto p-2"
											>
												123
											</Button>
											{/snippet}
										</Popover.Trigger>
										<Popover.Content class="w-64" side="bottom" align="start">
											<div>
												<div class="flex flex-col gap-3">
												<p class="text-sm font-semibold">Enter Number Value</p>
												<Input
												type="number"
												placeholder='e.g. 142'
												bind:value={numberLiteralInput}
												onkeydown={(e) => {
													if (e.key === 'Enter' && numberLiteralInput != null && !isNaN(numberLiteralInput)) {
													onAddLiteral(String(numberLiteralInput));
													numberLiteralInput = null;
													}
												}}
												/>
												<div class="flex justify-end gap-2">
													<Button
													type="button"
													size="sm"
													disabled={numberLiteralInput == null || isNaN(numberLiteralInput)}
													onclick={() => {
														onAddLiteral(String(numberLiteralInput));
														numberLiteralInput = null;
														numberPopoverOpen = false;
													}}
													>
													Add
													</Button>
												</div>
												</div>
											</div>
										</Popover.Content>
									</Popover.Root>
								</div>
							</div>
							<div class="flex flex-col gap-2">
								<Label class="uppercase tracking-wide">Logical Operators</Label>
								<div class="flex flex-wrap gap-2">
									{#each logicalop as op}
										<Button
											type="button"
											variant="outline"
											class="h-auto w-auto p-2"
											onclick={() => onAddOperator?.(op)}
										>
											{op}
										</Button>
									{/each}
								</div>
							</div>
							<div class="flex flex-col gap-2">
								<Label class="uppercase tracking-wide">Comparison Operators</Label>
								<div class="flex flex-wrap gap-2">
									{#each comparisonop as op}
										<Button
											type="button"
											variant="outline"
											size="icon"
											onclick={() => onAddOperator?.(op)}
										>
											{op}
										</Button>
									{/each}
								</div>
							</div>
							<div class="flex flex-col gap-2">
								<Label class="uppercase tracking-wide">Math Operators</Label>
								<div class="flex flex-wrap gap-2">
									{#each operators as op}
										<Button
											type="button"
											variant="outline"
											size="icon"
											onclick={() => onAddOperator?.(op)}
										>
											{op}
										</Button>
									{/each}
								</div>
							</div>
						</div>
					</div>

					{#if tokens.length > 0}
						<div class="flex flex-col gap-2">
							<Label class="uppercase tracking-wide">Preview</Label>
							<div class="border-2 border-dashed border-muted-foreground/30 rounded-lg">
								<pre class="font-mono text-sm bg-muted/50 p-2 rounded">{expressionString}</pre>
							</div>
						</div>
					{/if}
				</div>
			{:else if type === 'members'}
				{@const filteredOptions = getFilteredOptions(key)}
				<div class="flex flex-col gap-2 w-full">
					{#each formState.form.Members as member, index (member.id)}
						{@const selectedLabel =
							formState.selectOptions?.[key]?.find((opt) => opt.value === member.value)?.label ||
							'Choose'}
						<div class="flex gap-1 w-full">
							<Button type="button" variant="outline" size="icon" disabled>
								{index + 1}
							</Button>

							<div class="flex-1">
								<Select.Root
									type="single"
									bind:value={member.value}
									onOpenChange={(open) => {
										if (open && optionsEndpoint) {
											formState.fetchOptions?.(
												{ key, optionsEndpoint, dependsOn, endpointParamKey, valueKey, labelKey },
												formState.form
											);
										}
									}}
									onValueChange={() => {
										if (validateOn?.includes('input')) {
											formState.validateField?.(key, formState.form[key], false);
										}
									}}
								>
									<Select.Trigger class="w-full">
										{selectedLabel}
									</Select.Trigger>
									<Select.Content>
										<div class="p-2">
											<input
												type="text"
												placeholder="Search..."
												class="w-full border rounded px-2 py-1 text-sm"
												bind:value={searchQuery[key]}
											/>
										</div>
										{#if formState.loadingOptions?.[key]}
											<Select.Item disabled value="loading">Loading...</Select.Item>
										{:else}
											{#if !required}
												<Select.Item value="">- None -</Select.Item>
											{/if}
											{#each filteredOptions as option}
												<Select.Item value={option.value}>
													{option.label}
												</Select.Item>
											{/each}
										{/if}
									</Select.Content>
								</Select.Root>
							</div>
							<Button
								type="button"
								variant="outline"
								size="icon"
								onclick={() => onRemoveMember(member.id)}
							>
								<Trash2Icon class="size-4" />
							</Button>
						</div>
					{/each}
					<Button variant="outline" onclick={onAddMember}>
						<PlusIcon class="size-4" />
						Add Test
					</Button>
				</div>
			{:else if type === "toggle"}
				{@const toggleOff = optionsToggle?.[0] ?? { value: false, label: 'Off' }}
				{@const toggleOn  = optionsToggle?.[1] ?? { value: true,  label: 'On'  }}
				{@const isOn = String(formState.form[key]) === String(toggleOn.value)}
				<div class="flex items-center w-full">
					<Toggle  
						aria-label="Toggle"  
						variant="outline"  
						class="w-full transition-all data-[state=on]:text-primary"
						pressed={isOn}
						onPressedChange={(pressed) => {
							formState.form[key] = pressed ? toggleOn.value : toggleOff.value;
						}}
					>
						{#if isOn}
							<CheckIcon class="mr-2 h-4 w-4" />
						{:else}
							<XIcon class="mr-2 h-4 w-4" />
						{/if}
						{isOn ? toggleOn.label : toggleOff.label}
					</Toggle>
				</div>
			{:else}
				<Input
					type="text"
					bind:value={formState.form[key]}
					placeholder="Custom field type: {type}"
				/>
			{/if}
			<div class={`absolute min-h-[1rem] w-full ${key === 'Members' ? 'right-0 -top-5 text-right' : 'top-10'}`}>
				{#if key !== 'FormulaCode' && (formState.errors[key] || formState.errors[txtKey])}
					{@const errorMessage = formState.errors[key] ?? formState.errors[txtKey]}

					<div class="text-sm text-destructive">
						{errorMessage}
					</div>
				{/if}
			</div>
		</div>
	</div>
{/snippet}

<div class="p-2 space-y-6">
	{#each formFields as group}
		<div class="space-y-6">
			{#if group.title}
				<div class="text-md 2xl:text-lg font-semibold italic">
					<span class="border-b-2 border-primary">{group.title}</span>
				</div>
			{/if}

			{#each group.rows as row}
				{@const visibleColumns = row.columns.filter((col) => !hiddenFields?.includes(col.key))}

				{#if visibleColumns.length > 0}
					<div
						class="grid grid-cols-1 space-y-2 gap-6 md:gap-4"
						class:md:grid-cols-1={visibleColumns.length === 1 &&
							visibleColumns[0].fullWidth !== false}
						class:md:grid-cols-2={visibleColumns.length === 2 ||
							(visibleColumns.length === 1 && visibleColumns[0].fullWidth === false)}
						class:md:grid-cols-3={visibleColumns.length === 3}
					>
						{#each visibleColumns as col}
							{#if col.type === 'group'}
								{@const visibleChildColumns = col.columns.filter(
									(child) => !hiddenFields?.includes(child.key)
								)}

								{#if visibleChildColumns.length > 0}
									<div
										class="grid grid-cols-1 gap-6 md:gap-2"
										class:md:grid-cols-1={visibleChildColumns.length === 1 &&
											visibleChildColumns[0].fullWidth !== false}
										class:md:grid-cols-2={visibleChildColumns.length === 2 ||
											(visibleChildColumns.length === 1 &&
												visibleChildColumns[0].fullWidth === false)}
										class:md:grid-cols-3={visibleChildColumns.length === 3}
									>
										{#each visibleChildColumns as child}
											{@render Fieldset(child)}
										{/each}
									</div>
								{/if}
							{:else}
								{@render Fieldset(col)}
							{/if}
						{/each}
					</div>
				{/if}
			{/each}
		</div>
	{/each}
</div>

<style>
	@keyframes cursor-blink {
		0%,
		50% {
			opacity: 1;
		}
		51%,
		100% {
			opacity: 0;
		}
	}
	.animate-cursor {
		animation: cursor-blink 1s infinite;
	}
</style>
