<script lang="ts">
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import { useQuery } from 'convex-svelte';
	import type { FunctionReference } from 'convex/server';
	import {
		ChevronDown,
		ClipboardCheck,
		FileText,
		GitMerge,
		Home,
		Settings,
		Tag,
		Users,
		Briefcase,
		UserPlus
	} from 'lucide-svelte';
	import { resolve } from '$app/paths';
	import { page } from '$app/state';

	interface MenuItemPermission {
		recurso: string;
		acao: string;
	}

	interface SubMenuItem {
		label: string;
		link: string;
		permission?: MenuItemPermission;
		excludePaths?: string[];
		exact?: boolean;
	}

	interface MenuItem {
		label: string;
		icon: string;
		link: string;
		permission?: MenuItemPermission;
		submenus?: SubMenuItem[];
		excludePaths?: string[];
		exact?: boolean;
	}

	// Estrutura do menu definida no frontend
	const MENU_STRUCTURE = [
		{
			label: 'Dashboard',
			icon: 'Home',
			link: '/'
		},
		{
			label: 'Gestão de Pessoas',
			icon: 'Users',
			link: '/recursos-humanos',
			permission: { recurso: 'gestao_pessoas', acao: 'ver' },
			submenus: [
				{
					label: 'Funcionários',
					link: '/recursos-humanos/funcionarios',
					permission: { recurso: 'funcionarios', acao: 'listar' },
					exact: true
				},
				{
					label: 'Cadastro de Funcionários',
					link: '/recursos-humanos/funcionarios/cadastro',
					permission: { recurso: 'funcionarios', acao: 'criar' }
				},
				{
					label: 'Exclusão de Funcionários',
					link: '/recursos-humanos/funcionarios/excluir',
					permission: { recurso: 'funcionarios', acao: 'excluir' }
				},
				{
					label: 'Férias',
					link: '/recursos-humanos/ferias',
					permission: { recurso: 'ferias', acao: 'dashboard' }
				},
				{
					label: 'Atestados de Licenças',
					link: '/recursos-humanos/atestados-licencas',
					permission: { recurso: 'atestados_licencas', acao: 'listar' }
				},
				{
					label: 'Controle de Ponto',
					link: '/recursos-humanos/controle-ponto',
					permission: { recurso: 'ponto', acao: 'ver' },
					exact: true
				},
				{
					label: 'Banco de Horas',
					link: '/recursos-humanos/controle-ponto/banco-horas',
					permission: { recurso: 'banco_horas', acao: 'ver' }
				},
				{
					label: 'Registro de Ponto',
					link: '/recursos-humanos/registro-pontos',
					permission: { recurso: 'ponto', acao: 'ver' }
				},
				{
					label: 'Símbolos',
					link: '/recursos-humanos/simbolos',
					permission: { recurso: 'simbolos', acao: 'listar' }
				}
			]
		},
		{
			label: 'Pedidos',
			icon: 'ClipboardCheck',
			link: '/pedidos',
			permission: { recurso: 'pedidos', acao: 'listar' },
			submenus: [
				{
					label: 'Meus Pedidos',
					link: '/pedidos',
					permission: { recurso: 'pedidos', acao: 'listar' },
					excludePaths: ['/pedidos/aceite', '/pedidos/minhas-analises']
				},
				{
					label: 'Pedidos para Aceite',
					link: '/pedidos/aceite',
					permission: { recurso: 'pedidos', acao: 'aceitar' }
				},
				{
					label: 'Minhas Análises',
					link: '/pedidos/minhas-analises',
					permission: { recurso: 'pedidos', acao: 'aceitar' }
				}
			]
		},
		{
			label: 'Objetos',
			icon: 'Tag',
			link: '/compras/objetos',
			permission: { recurso: 'objetos', acao: 'listar' }
		},
		{
			label: 'Atas de Registro',
			icon: 'FileText',
			link: '/compras/atas',
			permission: { recurso: 'atas', acao: 'listar' }
		},
		{
			label: 'Contratos',
			icon: 'FileText',
			link: '/licitacoes/contratos',
			permission: { recurso: 'contratos', acao: 'listar' }
		},
		{
			label: 'Empresas',
			icon: 'Briefcase',
			link: '/licitacoes/empresas',
			permission: { recurso: 'empresas', acao: 'listar' }
		},
		{
			label: 'Fluxos & Processos',
			icon: 'GitMerge',
			link: '/fluxos',
			permission: { recurso: 'fluxos_instancias', acao: 'listar' },
			submenus: [
				{
					label: 'Meus Processos',
					link: '/fluxos/meus-processos',
					permission: { recurso: 'fluxos_instancias', acao: 'listar' }
				},
				{
					label: 'Modelos de Fluxo',
					link: '/fluxos/templates',
					permission: { recurso: 'fluxos_templates', acao: 'listar' }
				}
			]
		},
		{
			label: 'Painel de TI',
			icon: 'Settings',
			link: '/ti',
			permission: { recurso: 'ti_painel_administrativo', acao: 'ver' }
		}
	] as const satisfies readonly MenuItem[];

	type IconType = typeof Home;

	type SidebarProps = {
		onNavigate?: () => void;
	};

	const { onNavigate }: SidebarProps = $props();

	let currentPath = $derived(page.url.pathname);
	const permissionsQuery = useQuery(api.menu.getUserPermissions as FunctionReference<'query'>, {});

	// Filtrar menu baseado nas permissões do usuário
	function filterSubmenusByPermissions(
		items: readonly SubMenuItem[],
		isMaster: boolean,
		permissionsSet: Set<string>
	): SubMenuItem[] {
		if (isMaster) return [...items];

		return items.filter((item) => {
			if (!item.permission) return true;
			const key = `${item.permission.recurso}.${item.permission.acao}`;
			return permissionsSet.has(key);
		});
	}

	function filterMenuByPermissions(
		items: readonly MenuItem[],
		isMaster: boolean,
		permissionsSet: Set<string>
	): MenuItem[] {
		if (isMaster) return [...items];

		const filtered: MenuItem[] = [];

		for (const item of items) {
			// Verifica permissão do item atual
			let hasPermission = true;
			if (item.permission) {
				const key = `${item.permission.recurso}.${item.permission.acao}`;
				hasPermission = permissionsSet.has(key);
			}

			if (!hasPermission) continue;

			// Se tiver submenus, filtra e só mantém se sobrar algo
			let filteredSubmenus: SubMenuItem[] | undefined = undefined;
			if (item.submenus) {
				const subs = filterSubmenusByPermissions(item.submenus, isMaster, permissionsSet);
				filteredSubmenus = subs.length > 0 ? subs : undefined;
			}

			filtered.push({
				...item,
				submenus: filteredSubmenus
			});
		}

		return filtered;
	}

	// Menu filtrado reativo
	let menuItems = $derived.by(() => {
		const data = permissionsQuery.data;
		if (!data) return [];

		const permissionsSet = new Set((data.permissions ?? []) as string[]);
		return filterMenuByPermissions(MENU_STRUCTURE, data.isMaster, permissionsSet);
	});

	const iconMap: Record<string, IconType> = {
		Home,
		UserPlus,
		Users,
		ClipboardCheck,
		FileText,
		Briefcase,
		ChevronDown,
		GitMerge,
		Settings,
		Tag
	};

	function getIconComponent(name: string): IconType {
		return iconMap[name] || Home;
	}

	function isRouteActive(path: string, options: { exact?: boolean; excludePaths?: string[] } = {}) {
		const { exact = false, excludePaths = [] } = options;

		if (excludePaths.length > 0) {
			if (excludePaths.some((excludePath) => currentPath.startsWith(excludePath))) {
				return false;
			}
		}

		if (exact) return currentPath === path;
		return currentPath === path || currentPath.startsWith(path + '/');
	}

	function getMenuClasses(active: boolean, isSub = false, isParent = false) {
		const base =
			'flex items-center gap-3 rounded-r-md border-l-4 px-3 py-2.5 text-base font-medium transition-all duration-200';

		// Premium active state with indicator
		const activeLeafClass = 'border-primary bg-primary/5 text-primary font-semibold';
		const activeParentClass = 'border-transparent text-primary font-semibold';

		const inactiveClass =
			'border-transparent text-base-content/70 hover:bg-primary/10 hover:text-primary';
		const subClass = isSub ? 'pl-8 text-sm' : '';

		if (active) {
			return `${base} ${isParent ? activeParentClass : activeLeafClass} ${subClass}`;
		}

		return `${base} ${inactiveClass} ${subClass}`;
	}

	function getSolicitarClasses(active: boolean) {
		return getMenuClasses(active);
	}
</script>

<nav
	class="menu text-base-content bg-base-200 border-base-100 h-[calc(100vh-64px)] w-full flex-col gap-2 overflow-y-auto p-4"
>
	{#snippet menuItem(item: MenuItem)}
		{@const Icon = getIconComponent(item.icon)}
		{@const isActive = isRouteActive(item.link, {
			exact: item.link === '/',
			excludePaths: item.excludePaths
		})}
		{@const hasSubmenus = item.submenus && item.submenus.length > 0}

		<li class="mb-1">
			{#if hasSubmenus}
				<details open={isActive} class="group/details">
					<summary
						class="{getMenuClasses(
							isActive,
							false,
							true
						)} cursor-pointer list-none justify-between [&::-webkit-details-marker]:hidden"
					>
						<div class="flex items-center gap-3">
							<Icon class="h-5 w-5" strokeWidth={2} />
							<span>{item.label}</span>
						</div>
						<ChevronDown
							class="h-4 w-4 opacity-50 transition-transform duration-200 group-open/details:rotate-180"
						/>
					</summary>
					<ul class="border-base-200 mt-1 ml-4 space-y-1 pl-2">
						{#if item.submenus}
							{#each item.submenus as sub (sub.link)}
								{@const isSubActive = isRouteActive(sub.link, {
									excludePaths: sub.excludePaths,
									exact: sub.exact
								})}
								<li>
									<a
										href={resolve(sub.link as any)}
										class={getMenuClasses(isSubActive, true)}
										onclick={() => onNavigate?.()}
									>
										<span>{sub.label}</span>
									</a>
								</li>
							{/each}
						{/if}
					</ul>
				</details>
			{:else}
				<a
					href={resolve(item.link as any)}
					aria-current={isActive ? 'page' : undefined}
					class={getMenuClasses(isActive)}
					onclick={() => onNavigate?.()}
				>
					<Icon class="h-5 w-5" strokeWidth={2} />
					<span>{item.label}</span>
				</a>
			{/if}
		</li>
	{/snippet}

	<ul class="menu w-full flex-1 p-0 px-2">
		{#if permissionsQuery.isLoading}
			<div class="flex flex-col gap-2 p-4">
				{#each Array(5)}
					<div class="skeleton h-12 w-full rounded-lg"></div>
				{/each}
			</div>
		{:else}
			{#each menuItems as item (item.link)}
				{@render menuItem(item)}
			{/each}
		{/if}
	</ul>

	<ul class="menu mt-auto w-full p-0 px-2">
		<div class="divider before:bg-base-300 after:bg-base-300 my-2 px-2"></div>

		<li class="px-2">
			<a
				href={resolve('/abrir-chamado')}
				class={getSolicitarClasses(currentPath === '/abrir-chamado')}
				onclick={() => onNavigate?.()}
			>
				<UserPlus class="h-5 w-5" strokeWidth={2} />
				<span>Abrir Chamado</span>
			</a>
		</li>
	</ul>
</nav>

<style>
	/* Remove default details marker */
	details > summary {
		list-style: none;
	}
	details > summary::-webkit-details-marker {
		display: none;
	}
	/* Remove DaisyUI default arrow */
	details > summary::after {
		display: none;
	}
</style>
