<script lang="ts">
	import * as Card from '$lib/components/ui/card/index.js';
	import type { CsvUploadItem } from '$lib/config/csv-upload';
	import { UploadCloud, Lock } from 'lucide-svelte';
	import { cn } from '$lib/utils';
	import { toast } from 'svelte-sonner';

	let {
		items,
		onUpload
	}: {
		items: CsvUploadItem[];
		onUpload: (file: File, config: CsvUploadItem) => void;
	} = $props();

	let dragOverId = $state<string | null>(null);

	// Group items
	let groupedItems = $derived.by(() => {
		const groups: Record<string, CsvUploadItem[]> = {};
		const ungrouped: CsvUploadItem[] = [];

		items.forEach((item) => {
			if (item.group) {
				if (!groups[item.group]) groups[item.group] = [];
				groups[item.group].push(item);
			} else {
				ungrouped.push(item);
			}
		});

		return { groups, ungrouped };
	});

	function handleDragEnter(e: DragEvent, id: string, disabled?: boolean) {
		if (disabled) return;
		e.preventDefault();
		e.stopPropagation();
		dragOverId = id;
	}

	function handleDragLeave(e: DragEvent) {
		e.preventDefault();
		e.stopPropagation();
		dragOverId = null;
	}

	function handleDragOver(e: DragEvent, disabled?: boolean) {
		if (disabled) return;
		e.preventDefault();
		e.stopPropagation();
		dragOverId = null;
	}

	function validateAndUpload(file: File, item: CsvUploadItem) {
		const isValidExtension = file.name.toLowerCase().endsWith('.csv');

		if (!isValidExtension) {
			toast.error('Formato inválido. Solo se permiten archivos .csv');
			return;
		}

		onUpload(file, item);
	}

	function handleDrop(e: DragEvent, item: CsvUploadItem) {
		if (item.disabled) return;
		e.preventDefault();
		e.stopPropagation();
		dragOverId = null;

		if (e.dataTransfer && e.dataTransfer.files.length > 0) {
			validateAndUpload(e.dataTransfer.files[0], item);
		}
	}

	function handleClick(id: string, disabled?: boolean) {
		if (disabled) return;
		const input = document.getElementById(`file-input-${id}`) as HTMLInputElement;
		if (input) input.click();
	}

	function handleFileChange(e: Event, item: CsvUploadItem) {
		const target = e.target as HTMLInputElement;
		if (target.files && target.files.length > 0) {
			validateAndUpload(target.files[0], item);
			target.value = '';
		}
	}

	function handleContextMenu(e: MouseEvent, item: CsvUploadItem) {
		if (item.disabled) {
			e.preventDefault();
			return;
		}
		if (!item.templateUrl) return;

		e.preventDefault();

		const link = document.createElement('a');
		link.href = item.templateUrl;
		link.download = item.templateUrl.split('/').pop() || 'plantilla.xls';
		document.body.appendChild(link);
		link.click();
		document.body.removeChild(link);

		toast.info(`Descargando plantilla para ${item.title}...`);
	}
</script>

<div class="flex flex-col gap-6 select-none">
	{#if groupedItems.ungrouped.length > 0}
		<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
			{#each groupedItems.ungrouped as item}
				<div
					class={cn(
						'relative group transition-all duration-200 ease-in-out transform',
						item.disabled ? 'opacity-60 cursor-not-allowed' : 'cursor-pointer',
						!item.disabled && dragOverId === item.id ? 'scale-105' : ''
					)}
					ondragenter={(e) => handleDragEnter(e, item.id, item.disabled)}
					ondragleave={handleDragLeave}
					ondragover={(e) => handleDragOver(e, item.disabled)}
					ondrop={(e) => handleDrop(e, item)}
					oncontextmenu={(e) => handleContextMenu(e, item)}
					roles="button"
					tabindex={item.disabled ? -1 : 0}
					onclick={() => handleClick(item.id, item.disabled)}
					onkeydown={(e) => !item.disabled && e.key === 'Enter' && handleClick(item.id)}
				>
					<input
						type="file"
						id={`file-input-${item.id}`}
						class="hidden"
						accept=".csv"
						onchange={(e) => handleFileChange(e, item)}
						disabled={item.disabled}
					/>

					<Card.Root
						class={cn(
							'h-full border-2 border-dashed border-transparent transition-colors w-full text-left relative overflow-hidden',
							!item.disabled && 'hover:border-primary/50 hover:shadow-md',
							!item.disabled && dragOverId === item.id
								? 'border-primary bg-primary/5 shadow-xl ring-2 ring-primary ring-offset-2'
								: ''
						)}
					>
						{#if item.disabled}
							<div class="absolute inset-0 bg-background/50 z-20 flex items-center justify-center">
								<span
									class="bg-muted px-2 py-1 rounded text-xs font-semibold text-muted-foreground border flex items-center gap-1"
								>
									<Lock class="h-3 w-3" /> Próximamente
								</span>
							</div>
						{/if}

						<Card.Content
							class="flex flex-col items-center justify-center p-6 gap-3 text-center h-full relative z-10"
						>
							{#if !item.disabled && dragOverId === item.id}
								<div class="animate-bounce">
									<UploadCloud class="h-8 w-8 text-primary" />
								</div>
								<span class="text-sm font-semibold text-primary">¡Suelta el archivo!</span>
							{:else}
								<div
									class={cn(
										'p-3 bg-muted rounded-full transition-transform duration-200',
										!item.disabled && 'group-hover:scale-110'
									)}
								>
									<item.icon class="h-6 w-6 text-primary" />
								</div>
								<div class="font-medium text-sm text-balance">{item.title}</div>
							{/if}
						</Card.Content>
					</Card.Root>
				</div>
			{/each}
		</div>
	{/if}

	{#each Object.entries(groupedItems.groups) as [groupName, groupItems]}
		<div class="flex flex-col gap-3">
			<h3 class="text-sm font-semibold text-muted-foreground uppercase tracking-wider pl-1">
				{groupName}
			</h3>
			<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
				{#each groupItems as item}
					<div
						class={cn(
							'relative group transition-all duration-200 ease-in-out transform',
							item.disabled ? 'opacity-60 cursor-not-allowed' : 'cursor-pointer',
							!item.disabled && dragOverId === item.id ? 'scale-105' : ''
						)}
						ondragenter={(e) => handleDragEnter(e, item.id, item.disabled)}
						ondragleave={handleDragLeave}
						ondragover={(e) => handleDragOver(e, item.disabled)}
						ondrop={(e) => handleDrop(e, item)}
						oncontextmenu={(e) => handleContextMenu(e, item)}
						role="button"
						tabindex={item.disabled ? -1 : 0}
						onclick={() => handleClick(item.id, item.disabled)}
						onkeydown={(e) => !item.disabled && e.key === 'Enter' && handleClick(item.id)}
					>
						<input
							type="file"
							id={`file-input-${item.id}`}
							class="hidden"
							accept=".csv"
							onchange={(e) => handleFileChange(e, item)}
							disabled={item.disabled}
						/>

						<Card.Root
							class={cn(
								'h-full border-2 border-dashed border-transparent transition-colors w-full text-left relative overflow-hidden',
								!item.disabled && 'hover:border-primary/50 hover:shadow-md',
								!item.disabled && dragOverId === item.id
									? 'border-primary bg-primary/5 shadow-xl ring-2 ring-primary ring-offset-2'
									: ''
							)}
						>
							{#if item.disabled}
								<div
									class="absolute inset-0 bg-background/50 z-20 flex items-center justify-center"
								>
									<span
										class="bg-muted px-2 py-1 rounded text-xs font-semibold text-muted-foreground border flex items-center gap-1"
									>
										<Lock class="h-3 w-3" /> Próximamente
									</span>
								</div>
							{/if}

							<Card.Content
								class="flex flex-col items-center justify-center p-6 gap-3 text-center h-full relative z-10"
							>
								{#if !item.disabled && dragOverId === item.id}
									<div class="animate-bounce">
										<UploadCloud class="h-8 w-8 text-primary" />
									</div>
									<span class="text-sm font-semibold text-primary">¡Suelta el archivo!</span>
								{:else}
									<div
										class={cn(
											'p-3 bg-muted rounded-full transition-transform duration-200',
											!item.disabled && 'group-hover:scale-110'
										)}
									>
										<item.icon class="h-6 w-6 text-primary" />
									</div>
									<div class="font-medium text-sm text-balance">{item.title}</div>
								{/if}
							</Card.Content>
						</Card.Root>
					</div>
				{/each}
			</div>
		</div>
	{/each}
</div>
