<script lang="ts">
	import * as Collapsible from '$lib/components/ui/collapsible/index.js';
	import * as Sidebar from '$lib/components/ui/sidebar/index.js';
	import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index.js';
	import { useSidebar } from '$lib/components/ui/sidebar/context.svelte.js';
	import ChevronRight from '@lucide/svelte/icons/chevron-right';
	import { authStore, permissionsRefreshing, permissionsHydrated, userHasPermission } from '$lib/auth';
	import { systemStore } from '$lib/stores/system.svelte';
	import { page } from '$app/state';

	function resolveVisibleNavItems<T>(
		filtered: T[],
		lastNonEmpty: T[],
		hasAuthenticatedUser: boolean
	): T[] {
		if (filtered.length > 0) return filtered;
		if (hasAuthenticatedUser && lastNonEmpty.length > 0) return lastNonEmpty;
		return filtered;
	}

	let {
		items
	}: {
		items: {
			title: string;
			url: string;
			icon?: any;
			isActive?: boolean;
			permission?: string;
			systemContext?: 'fixed_asset' | 'inventory';
			items?: {
				title: string;
				url: string;
				permission?: string;
				systemContext?: 'fixed_asset' | 'inventory';
			}[];
		}[];
	} = $props();

	function isUrlActive(url: string): boolean {
		const pathname = page.url.pathname;
		return pathname === url || pathname.startsWith(url + '/');
	}

	function matchesSystem(ctx: 'fixed_asset' | 'inventory' | undefined): boolean {
		if (!ctx) return true;
		if (!systemStore.activeSystem) return false;
		return ctx === systemStore.activeSystem;
	}

	// Filtrar items según permisos y sistema activo
	const filteredItems = $derived(
		items
			.map((item) => ({
				...item,
				items: item.items?.filter((subItem) => {
					if (subItem.permission && !userHasPermission($authStore.user, subItem.permission)) return false;
					if (!matchesSystem(subItem.systemContext)) return false;
					return true;
				})
			}))
			.filter((item) => {
				// 1. Filtrar por permiso explícito del item principal
				if (item.permission && !userHasPermission($authStore.user, item.permission)) return false;

				// 2. Filtrar por sistema activo
				if (!matchesSystem(item.systemContext)) return false;

				// 3. Ocultar categorías (url="#") que se quedaron sin sub-items visibles
				if (item.url === '#' && item.items && item.items.length === 0) return false;

				return true;
			})
	);

	type NavMainItem = (typeof items)[number];

	const NAV_SNAPSHOT_KEY = 'app:sidebar:nav-main:v1';

	function loadNavSnapshot(): NavMainItem[] {
		if (typeof window === 'undefined') return [];
		try {
			const raw = sessionStorage.getItem(NAV_SNAPSHOT_KEY);
			if (!raw) return [];
			const parsed = JSON.parse(raw);
			return Array.isArray(parsed) ? (parsed as NavMainItem[]) : [];
		} catch {
			return [];
		}
	}

	function saveNavSnapshot(items: NavMainItem[]): void {
		if (typeof window === 'undefined') return;
		try {
			sessionStorage.setItem(NAV_SNAPSHOT_KEY, JSON.stringify(items));
		} catch {
			// ignore
		}
	}

	// Snapshot del último menú no vacío: evita parpadeo si filteredItems queda [] durante revalidación.
	let lastNonEmptyItems = $state<NavMainItem[]>(loadNavSnapshot());

	$effect(() => {
		if (filteredItems.length > 0) {
			lastNonEmptyItems = filteredItems;
			saveNavSnapshot(filteredItems);
		}
	});

	const visibleItems = $derived(
		resolveVisibleNavItems(
			filteredItems,
			lastNonEmptyItems,
			Boolean($authStore.user)
		)
	);

	const sidebar = useSidebar();

	// Estado del Sistema Híbrido controlado por hover estricto (sin timers)
	let activeTitle = $state<string | null>(null);

	function shouldKeepOpen(event: PointerEvent, title: string) {
		const next = event.relatedTarget as Node | null;
		if (!next) return false;

		const trigger = document.getElementById(`trigger-${title}`);
		const content = document.getElementById(`content-${title}`);

		// Mantenemos abierto si el puntero se mueve hacia el trigger o el contenido del menú
		return (trigger && trigger.contains(next)) || (content && content.contains(next));
	}

	function handleTriggerEnter(title: string) {
		if (sidebar.state !== 'collapsed') return;
		activeTitle = title;
	}

	function handleTriggerLeave(event: PointerEvent, title: string) {
		if (sidebar.state !== 'collapsed') return;

		// Si nos movemos al contenido (o nos quedamos en el trigger), no cerramos
		if (shouldKeepOpen(event, title)) return;

		activeTitle = null;
	}

	function handleContentEnter(title: string) {
		if (sidebar.state !== 'collapsed') return;
		activeTitle = title;
	}

	function handleContentLeave(event: PointerEvent, title: string) {
		if (sidebar.state !== 'collapsed') return;

		// Si nos movemos de vuelta al trigger (o dentro del contenido), no cerramos
		if (shouldKeepOpen(event, title)) return;

		activeTitle = null;
	}

	function onOpenChange(open: boolean, title: string) {
		// Sincronización base
		if (open) {
			activeTitle = title;
		} else {
			if (activeTitle === title) {
				activeTitle = null;
			}
		}
	}
</script>

<Sidebar.Group>
	<Sidebar.GroupLabel class="flex items-center gap-2">
		<span>CRM</span>
		{#if $permissionsRefreshing}
			<span
				class="size-1.5 shrink-0 animate-pulse rounded-full bg-primary"
				title="Actualizando permisos"
				aria-label="Actualizando permisos"
			></span>
		{/if}
	</Sidebar.GroupLabel>
	<Sidebar.Menu
		id="dashboard-sidebar-nav"
		aria-label="Navegación principal"
		class={visibleItems.length === 0 && !$permissionsHydrated ? 'opacity-0' : ''}
	>
		{#each visibleItems as item (item.title)}
			{#if item.items && item.items.length > 0}
				{#if sidebar.state === 'collapsed'}
					<!-- Sidebar Colapsado: Dropdown controlado por eventos estrictos -->
					<Sidebar.MenuItem>
						<DropdownMenu.Root
							open={activeTitle === item.title}
							onOpenChange={(v) => onOpenChange(v, item.title)}
						>
							<DropdownMenu.Trigger>
								{#snippet child({ props })}
									<div
										id={`trigger-${item.title}`}
										class="relative z-30 flex w-full justify-center"
										onpointerenter={() => handleTriggerEnter(item.title)}
										onpointerleave={(e) => handleTriggerLeave(e, item.title)}
									>
										<Sidebar.MenuButton
											{...props}
											tooltipContent={undefined}
											class="justify-center"
										>
											{#if item.icon}
												<item.icon />
											{:else}
												<div class="size-4"></div>
											{/if}
											<!-- Ocultamos el texto en modo colapsado para asegurar que solo sea el icono -->
											<span class="sr-only">{item.title}</span>
										</Sidebar.MenuButton>
									</div>
								{/snippet}
							</DropdownMenu.Trigger>
							<DropdownMenu.Content
								side="right"
								align="start"
								sideOffset={0}
								class="z-50 w-64 overflow-visible rounded-lg p-0 shadow-lg"
								id={`content-${item.title}`}
								onpointerenter={() => handleContentEnter(item.title)}
								onpointerleave={(e) => handleContentLeave(e, item.title)}
							>
								<!-- 
								Header "Tab" (Icono Flotante)
								Posicionado con right-full para estar exactamente donde el trigger termina (offset 0).
								Usamos w-8 h-8 para coincidir con un botón de tamaño estándar de sidebar.
								-->
								<div
									class="absolute top-0 right-full z-50 flex h-8 w-8 items-center justify-center rounded-l-lg border border-r-0 border-sidebar-border bg-sidebar-accent text-sidebar-accent-foreground shadow-none"
								>
									{#if item.icon}
										<item.icon class="size-4 shrink-0" />
									{:else}
										<div class="size-4 shrink-0"></div>
									{/if}
								</div>

								<!-- 
								Panel Principal
								-->
								<div
									class="pointer-events-auto ml-[0px] h-full w-full rounded-lg rounded-tl-none border border-sidebar-border bg-popover p-1"
								>
									<!-- Título en el panel principal -->
									<div
										class="truncate border-b px-2 py-2 text-sm font-medium text-sidebar-foreground"
									>
										{item.title}
									</div>

									<DropdownMenu.DropdownMenuGroup class="mt-1 max-h-80 overflow-y-auto">
										{#each item.items as subItem (subItem.title)}
											<DropdownMenu.Item>
												{#snippet child({ props })}
													<a
														{...props}
														href={subItem.url}
														class="flex w-full items-center gap-2 overflow-hidden"
													>
														<span class="truncate">{subItem.title}</span>
													</a>
												{/snippet}
											</DropdownMenu.Item>
										{/each}
									</DropdownMenu.DropdownMenuGroup>
								</div>
							</DropdownMenu.Content>
						</DropdownMenu.Root>
					</Sidebar.MenuItem>
				{:else}
					<!-- Sidebar Expandido: Collapsible original -->
					<Collapsible.Root
						open={item.isActive || item.items?.some((sub) => isUrlActive(sub.url))}
						class="group/collapsible"
					>
						{#snippet child({ props })}
							<Sidebar.MenuItem {...props}>
								<Collapsible.Trigger>
									{#snippet child({ props })}
										<Sidebar.MenuButton {...props} tooltipContent={item.title}>
											{#if item.icon}
												<item.icon />
											{/if}
											<span>{item.title}</span>
											<ChevronRight
												class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
											/>
										</Sidebar.MenuButton>
									{/snippet}
								</Collapsible.Trigger>
								<Collapsible.Content>
									<Sidebar.MenuSub>
										{#each item.items as subItem (subItem.title)}
											<Sidebar.MenuSubItem>
												<Sidebar.MenuSubButton isActive={isUrlActive(subItem.url)}>
													{#snippet child({ props })}
														<a href={subItem.url} {...props}>
															<span>{subItem.title}</span>
														</a>
													{/snippet}
												</Sidebar.MenuSubButton>
											</Sidebar.MenuSubItem>
										{/each}
									</Sidebar.MenuSub>
								</Collapsible.Content>
							</Sidebar.MenuItem>
						{/snippet}
					</Collapsible.Root>
				{/if}
			{:else}
				<!-- Items sin submenú -->
				<Sidebar.MenuItem>
					<Sidebar.MenuButton tooltipContent={item.title}>
						{#snippet child({ props })}
							<a href={item.url} {...props}>
								{#if item.icon}
									<item.icon />
								{/if}
								<span>{item.title}</span>
							</a>
						{/snippet}
					</Sidebar.MenuButton>
				</Sidebar.MenuItem>
			{/if}
		{/each}
	</Sidebar.Menu>
</Sidebar.Group>
