<script lang="ts">
	import { useQuery } from 'convex-svelte';
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import { onMount } from 'svelte';
	import type { Snippet } from 'svelte';

	let {
		children,
		requireAuth = true,
		allowedRoles = [],
		maxLevel = 3,
		redirectTo = '/'
	}: {
		children: Snippet;
		requireAuth?: boolean;
		allowedRoles?: string[];
		maxLevel?: number;
		redirectTo?: string;
	} = $props();

	let isChecking = $state(true);
	let hasAccess = $state(false);
	let timeoutId: ReturnType<typeof setTimeout> | null = null;
	let hasCheckedOnce = $state(false);
	let lastUserState = $state<typeof currentUser | undefined>(undefined);
	const currentUser = useQuery(api.auth.getCurrentUser, {});

	// Usar $effect para reagir apenas às mudanças na query currentUser
	$effect(() => {
		// Não verificar novamente se já tem acesso concedido e usuário está autenticado
		if (hasAccess && currentUser?.data) {
			lastUserState = currentUser;
			return;
		}

		// Evitar loop: só verificar se currentUser realmente mudou
		// Comparar dados, não o objeto proxy
		const currentData = currentUser?.data;
		const lastData = lastUserState?.data;
		if (currentData !== lastData || (currentUser === undefined) !== (lastUserState === undefined)) {
			lastUserState = currentUser;
			checkAccess();
		}
	});

	function checkAccess() {
		// Limpar timeout anterior se existir
		if (timeoutId) {
			clearTimeout(timeoutId);
			timeoutId = null;
		}

		// Se a query ainda está carregando (undefined), aguardar
		if (currentUser === undefined) {
			isChecking = true;
			hasAccess = false;
			return;
		}

		// Marcar que já verificou pelo menos uma vez
		hasCheckedOnce = true;

		// Se a query retornou dados, verificar autenticação
		if (currentUser?.data) {
			// Verificar roles
			if (allowedRoles.length > 0) {
				const hasRole = allowedRoles.includes(currentUser.data.role?.nome ?? '');
				if (!hasRole) {
					const currentPath = window.location.pathname;
					window.location.href = `${redirectTo}?error=access_denied&route=${encodeURIComponent(currentPath)}`;
					return;
				}
			}

			// Verificar nível
			if (currentUser.data.role?.nivel && currentUser.data.role.nivel > maxLevel) {
				const currentPath = window.location.pathname;
				window.location.href = `${redirectTo}?error=access_denied&route=${encodeURIComponent(currentPath)}`;
				return;
			}

			// Se chegou aqui, permitir acesso
			hasAccess = true;
			isChecking = false;
			return;
		}

		// Se não tem dados e requer autenticação
		if (requireAuth && !currentUser?.data) {
			// Se a query já retornou (não está mais undefined), finalizar estado
			if (currentUser !== undefined) {
				const currentPath = window.location.pathname;
				// Evitar redirecionamento em loop - verificar se já está na URL de erro
				const urlParams = new URLSearchParams(window.location.search);
				if (!urlParams.has('error')) {
					// Só redirecionar se não estiver em loop
					if (!hasCheckedOnce || currentUser === null) {
						window.location.href = `${redirectTo}?error=auth_required&redirect=${encodeURIComponent(currentPath)}`;
						return;
					}
				}
				// Se já tem erro na URL, permitir renderização para mostrar o alerta
				isChecking = false;
				hasAccess = true;
				return;
			}

			// Se ainda está carregando (undefined), aguardar
			isChecking = true;
			hasAccess = false;
			return;
		}

		// Se não requer autenticação, permitir acesso
		if (!requireAuth) {
			hasAccess = true;
			isChecking = false;
		}
	}
</script>

{#if isChecking}
	<div class="flex min-h-screen items-center justify-center">
		<div class="text-center">
			<span class="loading loading-spinner loading-lg text-primary"></span>
			<p class="text-base-content/70 mt-4">Verificando permissões...</p>
		</div>
	</div>
{:else if hasAccess}
	{@render children()}
{/if}
