<script lang="ts">
	import * as Select from '$lib/components/ui/select';
	import * as RadioGroup from '$lib/components/ui/radio-group';
	import { Switch } from '$lib/components/ui/switch';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import { Button } from '$lib/components/ui/button';
	import { FolderOpen } from 'lucide-svelte';

	interface Props {
		key: string;
		label?: string;
		value: any;
		onChange: (val: any) => void;
		options?: { value: any, label: string }[];
		type?: 'switch' | 'input' | 'select' | 'path' | 'radio' | 'password' | 'number';
		hint?: string;
		disabled?: boolean;
	}

	let { key, label, value, onChange, options, type, hint, disabled }: Props = $props();

	// Heuristic to detect toggleable (boolean-like) legacy fields (0/1)
	const isToggleable = (k: string, v: any) => {
		const toggles = [
			'act', 'valid', 'mostr', 'usar', 'utiliz', 'restring', 'bloqueo', 
			'omiti', 'oculta', 'resaltar', 'cal', 'mues', 'mens', 'cont', 'firm', 
			'esc', 'adv', 'val', 'tom', 'nom', 'rev', 'imp', 'temp', 'costo',
			'des', 'asig', 'calc', 'param', 'fracc', 'valor', 'cove', 'loc', 'inter', 'inclu', 'actvalor', 'trans', 'cambiar', 'reasigna'
		];
		// Be more lenient: if it has the prefix and is 0, 1, or null, it's likely a toggle
		return (v === 0 || v === 1 || v === null || v === undefined) && 
			   toggles.some(t => k.toLowerCase().startsWith(t));
	}

	const isPath = $derived(
		key.toLowerCase().includes('path') || 
		key.toLowerCase().includes('arch') || 
		key.toLowerCase().includes('ruta')
	);

	// Heuristic or explicit type
	let mode = $derived(type || (options ? 'select' : (isToggleable(key, value) ? 'switch' : (isPath ? 'path' : 'input'))));

	function handleBrowse() {
		try {
			if (typeof window !== 'undefined' && 'showDirectoryPicker' in window) {
				// @ts-ignore
				window.showDirectoryPicker().then((handle: any) => {
					onChange(handle.name); 
				}).catch((err: any) => console.log("Browse cancelled:", err));
			}
		} catch (err) {
			console.log("Browse failed:", err);
		}
	}
	let selectValue = $state(String(value));
	$effect(() => {
		selectValue = String(value);
	});

	function handleSelectChange(v: string) {
		selectValue = v;
		onChange(v);
	}
</script>

<div class="flex flex-col gap-2.5">
	<div class="flex flex-col gap-2 {mode === 'switch' ? 'flex-row items-center justify-between' : ''}">
		<Label for={key} class="text-sm font-medium {disabled ? 'opacity-50 cursor-not-allowed' : ''} {mode === 'switch' ? 'cursor-pointer' : ''}">
			{label || key}
		</Label>

		{#if mode === 'select' && options}
			<Select.Root 
				type="single"
				bind:value={selectValue}
				onValueChange={handleSelectChange}
				disabled={disabled}
			>
				<Select.Trigger class="w-full">
					<span class="truncate">
						{options.find(opt => String(opt.value) === selectValue)?.label || "Seleccionar..."}
					</span>
				</Select.Trigger>
				<Select.Content>
					{#each options as opt}
						<Select.Item value={String(opt.value)} label={opt.label}>
							{opt.label}
						</Select.Item>
					{/each}
				</Select.Content>
			</Select.Root>
		{:else if mode === 'radio'}
			<RadioGroup.Root 
				value={String(value)} 
				onValueChange={onChange}
				disabled={disabled}
				class="flex flex-col gap-3"
			>
				{#each options || [] as opt}
					<div class="flex items-center space-x-3">
						<RadioGroup.Item value={String(opt.value)} id={`${key}-${opt.value}`} />
						<Label for={`${key}-${opt.value}`} class="text-sm font-medium cursor-pointer {disabled ? 'cursor-not-allowed' : ''}">
							{opt.label}
						</Label>
					</div>
				{/each}
			</RadioGroup.Root>
		{:else if mode === 'switch'}
			<Switch 
				id={key} 
				checked={value === 1 || value === '1' || value === true || value === 'true'} 
				onCheckedChange={(val) => onChange(val ? 1 : 0)}
				disabled={disabled}
			/>
		{:else}
			<div class="space-y-1.5">
				{#if mode === 'path'}
					<div class="flex gap-2">
						<Input 
							id={key} 
							value={value || ""} 
							oninput={(e: any) => onChange(e.target.value)}
							placeholder="Ruta del directorio..."
							disabled={disabled}
							class="font-mono text-xs text-foreground bg-background"
						/>
						<Button 
							variant="outline" 
							size="icon"
							disabled={disabled}
							onclick={handleBrowse}
							class="shrink-0"
						>
							<FolderOpen class="w-4 h-4" />
						</Button>
					</div>
				{:else if mode === 'password'}
					<Input 
						id={key} 
						type="password"
						value={value || ""} 
						oninput={(e: any) => onChange(e.target.value)}
						placeholder="••••••••"
						disabled={disabled}
						class="text-foreground bg-background"
					/>
				{:else if mode === 'number'}
					<Input 
						id={key} 
						type="number"
						value={value || ""} 
						oninput={(e: any) => onChange(Number(e.target.value))}
						disabled={disabled}
						class="text-right text-foreground bg-background"
					/>
				{:else}
					<Input 
						id={key} 
						value={value || ""} 
						oninput={(e: any) => onChange(e.target.value)}
						disabled={disabled}
						class="text-foreground bg-background"
					/>
				{/if}
				{#if hint}
					<p class="text-[10px] text-muted-foreground ml-1 font-medium italic">
						{hint}
					</p>
				{/if}
			</div>
		{/if}
	</div>
</div>

