<script lang="ts">
	import { onMount } from 'svelte';
	import { useQuery, useConvexClient } from 'convex-svelte';
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { resolve } from '$app/paths';
	import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
	import { MapPin, Plus, X, Edit, Trash2, Search } from 'lucide-svelte';
	import { toast } from 'svelte-sonner';

	const client = useConvexClient();
	const funcionarioId = $derived($page.params.funcionarioId as Id<'funcionarios'>);

	// Queries
	const funcionarioQuery = useQuery(
		api.funcionarios.getFichaCompleta,
		funcionarioId ? { id: funcionarioId } : 'skip'
	);
	const associacoesQuery = useQuery(
		api.funcionarioEnderecos.listarAssociacoesFuncionario,
		funcionarioId ? { funcionarioId, incluirInativos: true } : 'skip'
	);
	const enderecosDisponiveisQuery = useQuery(api.enderecosMarcacao.listarEnderecos, {
		incluirInativos: false
	});

	const funcionario = $derived(funcionarioQuery?.data);
	const associacoes = $derived(associacoesQuery?.data || []);
	const enderecosDisponiveis = $derived(enderecosDisponiveisQuery?.data || []);

	// Estados
	let mostrarModalAssociacao = $state(false);
	let editandoAssociacao: (typeof associacoes)[number] | null = $state(null);
	let processando = $state(false);
	let termoBusca = $state('');

	// Campos do formulário
	let enderecoSelecionado: Id<'enderecosMarcacao'> | '' = $state('');
	let raioPersonalizado: number | '' = $state('');
	let dataInicio = $state('');
	let dataFim = $state('');

	// Filtrar associacoes
	const associacoesFiltradas = $derived(
		associacoes.filter((a) => {
			if (!termoBusca) return true;
			const busca = termoBusca.toLowerCase();
			return (
				a.endereco.nome.toLowerCase().includes(busca) ||
				a.endereco.endereco.toLowerCase().includes(busca) ||
				a.endereco.cidade.toLowerCase().includes(busca) ||
				a.endereco.tipo.toLowerCase().includes(busca)
			);
		})
	);

	// Endereços já associados (para não mostrar no select)
	const enderecosJaAssociados = $derived(
		new Set(associacoes.filter((a) => a.ativo).map((a) => a.endereco._id))
	);

	// Endereços disponíveis para associar (não associados e ativos)
	const enderecosParaAssociar = $derived(
		enderecosDisponiveis.filter((e) => e.ativo && !enderecosJaAssociados.has(e._id))
	);

	function limparFormulario() {
		enderecoSelecionado = '';
		raioPersonalizado = '';
		dataInicio = '';
		dataFim = '';
		editandoAssociacao = null;
		mostrarModalAssociacao = false;
	}

	function abrirFormularioEdicao(associacao: (typeof associacoes)[number]) {
		editandoAssociacao = associacao;
		enderecoSelecionado = associacao.endereco._id;
		raioPersonalizado = associacao.raioMetrosPersonalizado ?? '';
		dataInicio = associacao.dataInicio || '';
		dataFim = associacao.dataFim || '';
		mostrarModalAssociacao = true;
	}

	async function salvarAssociacao() {
		if (!enderecoSelecionado) {
			toast.error('Selecione um endereço');
			return;
		}

		if (raioPersonalizado !== '' && (raioPersonalizado < 0 || raioPersonalizado > 50000)) {
			toast.error('Raio personalizado deve estar entre 0 e 50000 metros');
			return;
		}

		if (dataInicio && dataFim && dataInicio > dataFim) {
			toast.error('Data de início deve ser anterior à data de fim');
			return;
		}

		processando = true;
		try {
			if (editandoAssociacao) {
				await client.mutation(api.funcionarioEnderecos.atualizarAssociacao, {
					associacaoId: editandoAssociacao._id,
					raioMetrosPersonalizado: raioPersonalizado !== '' ? Number(raioPersonalizado) : undefined,
					dataInicio: dataInicio || undefined,
					dataFim: dataFim || undefined
				});
				toast.success('Associação atualizada com sucesso!');
			} else {
				await client.mutation(api.funcionarioEnderecos.associarEnderecoFuncionario, {
					funcionarioId,
					enderecoMarcacaoId: enderecoSelecionado as Id<'enderecosMarcacao'>,
					raioMetrosPersonalizado: raioPersonalizado !== '' ? Number(raioPersonalizado) : undefined,
					dataInicio: dataInicio || undefined,
					dataFim: dataFim || undefined
				});
				toast.success('Endereço associado com sucesso!');
			}

			limparFormulario();
		} catch (error) {
			console.error('Erro ao salvar associação:', error);
			toast.error(
				error instanceof Error ? error.message : 'Erro ao salvar associação. Tente novamente.'
			);
		} finally {
			processando = false;
		}
	}

	async function removerAssociacao(associacaoId: Id<'funcionarioEnderecosMarcacao'>) {
		if (!confirm('Tem certeza que deseja remover esta associação?')) {
			return;
		}

		try {
			await client.mutation(api.funcionarioEnderecos.removerAssociacao, { associacaoId });
			toast.success('Associação removida com sucesso!');
		} catch (error) {
			console.error('Erro ao remover associação:', error);
			toast.error('Erro ao remover associação. Tente novamente.');
		}
	}

	// Verificar se funcionário existe
	onMount(() => {
		if (!funcionarioId) {
			goto(resolve('/recursos-humanos/funcionarios'));
		}
	});

	const tiposLabel: Record<string, string> = {
		sede: 'Sede Principal',
		home_office: 'Home Office',
		deslocamento: 'Deslocamento',
		cliente: 'Cliente'
	};
</script>

<div class="container mx-auto max-w-7xl px-4 py-6">
	<!-- Breadcrumb -->
	<div class="breadcrumbs mb-4 text-sm">
		<ul>
			<li>
				<a href={resolve('/recursos-humanos')} class="text-primary hover:underline">
					Recursos Humanos
				</a>
			</li>
			<li>
				<a href={resolve('/recursos-humanos/funcionarios')} class="text-primary hover:underline">
					Funcionários
				</a>
			</li>
			{#if funcionario}
				<li>
					<a
						href={resolve(`/recursos-humanos/funcionarios/${funcionarioId}`)}
						class="text-primary hover:underline"
					>
						{funcionario.nome}
					</a>
				</li>
			{/if}
			<li>Endereços de Marcação</li>
		</ul>
	</div>

	<!-- Header -->
	<div class="mb-6 flex items-center justify-between">
		<div class="flex items-center gap-4">
			<div class="bg-primary/10 rounded-xl p-3">
				<MapPin class="text-primary h-8 w-8" />
			</div>
			<div>
				<h1 class="text-base-content text-3xl font-bold">Endereços de Marcação</h1>
				<p class="text-base-content/60 mt-1">
					{#if funcionario}
						Gerenciar locais permitidos para registro de ponto de {funcionario.nome}
					{:else}
						Carregando...
					{/if}
				</p>
			</div>
		</div>
		{#if enderecosParaAssociar.length > 0}
			<button
				class="btn btn-primary gap-2"
				onclick={() => {
					limparFormulario();
					mostrarModalAssociacao = true;
				}}
				disabled={mostrarModalAssociacao}
			>
				<Plus class="h-5 w-5" />
				Associar Endereço
			</button>
		{/if}
	</div>

	<!-- Modal de Associação -->
	{#if mostrarModalAssociacao}
		<div class="modal modal-open">
			<div class="modal-box max-w-2xl">
				<div class="mb-4 flex items-center justify-between">
					<h2 class="text-2xl font-bold">
						{editandoAssociacao ? 'Editar Associação' : 'Associar Endereço'}
					</h2>
					<button class="btn btn-sm btn-circle btn-ghost" onclick={limparFormulario}>
						<X class="h-5 w-5" />
					</button>
				</div>

				<div class="space-y-4">
					<!-- Endereço -->
					<div class="form-control">
						<label class="label">
							<span class="label-text font-medium">Endereço *</span>
						</label>
						<select
							bind:value={enderecoSelecionado}
							class="select select-bordered"
							disabled={!!editandoAssociacao}
						>
							<option value="">Selecione um endereço</option>
							{#if editandoAssociacao}
								<!-- Ao editar, mostrar apenas o endereço atual -->
								<option value={editandoAssociacao.endereco._id}>
									{editandoAssociacao.endereco.nome} - {editandoAssociacao.endereco.endereco}, {editandoAssociacao
										.endereco.cidade}/{editandoAssociacao.endereco.estado}
									(raio padrão: {editandoAssociacao.endereco.raioMetros}m)
								</option>
							{:else}
								<!-- Ao criar, mostrar apenas endereços disponíveis para associar -->
								{#each enderecosParaAssociar as endereco (endereco._id)}
									<option value={endereco._id}>
										{endereco.nome} - {endereco.endereco}, {endereco.cidade}/{endereco.estado}
										(raio padrão: {endereco.raioMetros}m)
									</option>
								{/each}
							{/if}
						</select>
						<div class="label">
							<span class="label-text-alt">
								{#if editandoAssociacao}
									Não é possível alterar o endereço. Crie uma nova associação se necessário.
								{:else}
									Selecione um endereço que ainda não está associado a este funcionário
								{/if}
							</span>
						</div>
					</div>

					<!-- Raio Personalizado -->
					<div class="form-control">
						<label class="label">
							<span class="label-text font-medium">Raio Personalizado (metros)</span>
						</label>
						<input
							type="number"
							bind:value={raioPersonalizado}
							min="0"
							max="50000"
							placeholder="Deixe vazio para usar o raio padrão do endereço"
							class="input input-bordered"
						/>
						<div class="label">
							<span class="label-text-alt">
								Opcional. Se informado, sobrescreve o raio padrão do endereço para este funcionário.
							</span>
						</div>
					</div>

					<!-- Período de Validade -->
					<div class="divider">Período de Validade (opcional)</div>

					<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
						<div class="form-control">
							<label class="label">
								<span class="label-text font-medium">Data Início</span>
							</label>
							<input type="date" bind:value={dataInicio} class="input input-bordered" />
							<div class="label">
								<span class="label-text-alt">Para deslocamentos temporários</span>
							</div>
						</div>

						<div class="form-control">
							<label class="label">
								<span class="label-text font-medium">Data Fim</span>
							</label>
							<input type="date" bind:value={dataFim} class="input input-bordered" />
							<div class="label">
								<span class="label-text-alt">Para deslocamentos temporários</span>
							</div>
						</div>
					</div>
				</div>

				<div class="modal-action">
					<button class="btn btn-ghost" onclick={limparFormulario} disabled={processando}>
						Cancelar
					</button>
					<button class="btn btn-primary" onclick={salvarAssociacao} disabled={processando}>
						{#if processando}
							<span class="loading loading-spinner loading-sm"></span>
						{:else}
							Salvar
						{/if}
					</button>
				</div>
			</div>
		</div>
	{/if}

	<!-- Barra de Busca -->
	<div class="card bg-base-100 mb-6 shadow-xl">
		<div class="card-body p-4">
			<div class="form-control">
				<div class="relative">
					<Search
						class="text-base-content/50 absolute top-1/2 left-3 h-5 w-5 -translate-y-1/2 transform"
					/>
					<input
						type="text"
						bind:value={termoBusca}
						placeholder="Buscar por nome, endereço, cidade ou tipo..."
						class="input input-bordered w-full pl-10"
					/>
				</div>
			</div>
		</div>
	</div>

	<!-- Aviso sobre endereços tipo "sede" -->
	{#if associacoes.length === 0}
		<div class="alert alert-info mb-6">
			<svg
				xmlns="http://www.w3.org/2000/svg"
				fill="none"
				viewBox="0 0 24 24"
				class="h-6 w-6 shrink-0 stroke-current"
			>
				<path
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
				></path>
			</svg>
			<span>
				Este funcionário não possui endereços específicos associados. O sistema usará
				automaticamente os endereços tipo "Sede Principal" configurados globalmente.
			</span>
		</div>
	{/if}

	<!-- Lista de Associações -->
	<div class="grid grid-cols-1 gap-4">
		{#if associacoesFiltradas.length === 0}
			<div class="card bg-base-100 shadow-xl">
				<div class="card-body py-12 text-center">
					<MapPin class="text-base-content/20 mx-auto mb-4 h-16 w-16" />
					<p class="text-base-content/60 text-lg">
						{termoBusca ? 'Nenhuma associação encontrada' : 'Nenhum endereço associado'}
					</p>
				</div>
			</div>
		{:else}
			{#each associacoesFiltradas as associacao (associacao._id)}
				{@const raioUsado = associacao.raioMetros}
				<div class="card bg-base-100 shadow-xl {associacao.ativo ? '' : 'opacity-60'}">
					<div class="card-body">
						<div class="flex items-start justify-between">
							<div class="flex-1">
								<div class="mb-2 flex items-center gap-3">
									<h3 class="text-xl font-bold">{associacao.endereco.nome}</h3>
									<span class="badge {associacao.ativo ? 'badge-success' : 'badge-error'}">
										{associacao.ativo ? 'Ativa' : 'Inativa'}
									</span>
									<span class="badge badge-outline">
										{tiposLabel[associacao.endereco.tipo] || associacao.endereco.tipo}
									</span>
								</div>
								<div class="space-y-1 text-sm">
									<p class="text-base-content/80">
										<strong>Endereço:</strong>
										{associacao.endereco.endereco}
									</p>
									<p class="text-base-content/80">
										<strong>Cidade:</strong>
										{associacao.endereco.cidade}/
										{associacao.endereco.estado}
									</p>
									<p class="text-base-content/80">
										<strong>Raio Permitido:</strong>
										{#if raioUsado >= 1000}
											{@const raioKm = (raioUsado / 1000).toFixed(2)}
											{raioKm} km
										{:else}
											{raioUsado} metros
										{/if}
										{#if associacao.raioMetrosPersonalizado !== null && associacao.raioMetrosPersonalizado !== undefined}
											<span class="badge badge-sm badge-primary ml-2"> Personalizado </span>
										{:else}
											<span class="badge badge-sm badge-outline ml-2">
												Padrão ({associacao.endereco.raioMetros}m)
											</span>
										{/if}
									</p>
									{#if associacao.dataInicio || associacao.dataFim}
										<p class="text-base-content/80">
											<strong>Período:</strong>
											{#if associacao.dataInicio}
												{@const dataInicioFormatada = new Date(
													associacao.dataInicio + 'T00:00:00'
												).toLocaleDateString('pt-BR')}
												{dataInicioFormatada}
											{:else}
												...
											{/if}
											até
											{#if associacao.dataFim}
												{@const dataFimFormatada = new Date(
													associacao.dataFim + 'T00:00:00'
												).toLocaleDateString('pt-BR')}
												{dataFimFormatada}
											{:else}
												...
											{/if}
										</p>
									{/if}
								</div>
							</div>

							<div class="flex flex-col gap-2">
								<button
									class="btn btn-sm btn-outline btn-primary gap-2"
									onclick={() => abrirFormularioEdicao(associacao)}
								>
									<Edit class="h-4 w-4" />
									Editar
								</button>
								<button
									class="btn btn-sm btn-outline btn-error gap-2"
									onclick={() => removerAssociacao(associacao._id)}
								>
									<Trash2 class="h-4 w-4" />
									Remover
								</button>
							</div>
						</div>
					</div>
				</div>
			{/each}
		{/if}
	</div>
</div>
