<script lang="ts">
	import { useQuery } from 'convex-svelte';
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import jsPDF from 'jspdf';
	import autoTable from 'jspdf-autotable';
	import { Printer, X, User, Clock, CheckCircle2, XCircle, Calendar, MapPin } from 'lucide-svelte';
	import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
	import { formatarDataHoraCompleta, getTipoRegistroLabel } from '$lib/utils/ponto';
	import logoGovPE from '$lib/assets/logo_governo_PE.png';

	interface Props {
		registroId: Id<'registrosPonto'>;
		onClose: () => void;
	}

	let { registroId, onClose }: Props = $props();

	const registroQuery = useQuery(api.pontos.obterRegistro, { registroId });
	const configQuery = useQuery(api.configuracaoPonto.obterConfiguracao, {});

	let gerando = $state(false);
	let modalPosition = $state<{ top: number; left: number } | null>(null);

	// Função para calcular a posição baseada no card de registro de ponto
	function calcularPosicaoModal() {
		// Procurar pelo elemento do card de registro de ponto
		const cardRef = document.getElementById('card-registro-ponto-ref');

		if (cardRef) {
			const rect = cardRef.getBoundingClientRect();
			const viewportHeight = window.innerHeight;

			// Posicionar o modal na mesma altura Y do card (top do card) - mesma posição do texto "Registrar Ponto"
			const top = rect.top;

			// Garantir que o modal não saia da viewport
			// Considerar uma altura mínima do modal (aproximadamente 300px)
			const minTop = 20;
			const maxTop = viewportHeight - 350; // Deixar espaço para o modal
			const finalTop = Math.max(minTop, Math.min(top, maxTop));

			// Centralizar horizontalmente
			return {
				top: finalTop,
				left: window.innerWidth / 2
			};
		}

		// Se não encontrar, usar posição padrão (centro da tela)
		return null;
	}

	// Atualizar posição quando o modal for aberto (quando registroQuery tiver dados)
	$effect(() => {
		if (registroQuery?.data) {
			// Usar requestAnimationFrame para garantir que o DOM está completamente renderizado
			const updatePosition = () => {
				requestAnimationFrame(() => {
					const pos = calcularPosicaoModal();
					if (pos) {
						modalPosition = pos;
					} else {
						// Fallback para centralização
						modalPosition = {
							top: window.innerHeight / 2,
							left: window.innerWidth / 2
						};
					}
				});
			};

			// Aguardar um pouco para garantir que o DOM está atualizado
			setTimeout(updatePosition, 50);

			// Adicionar listener de scroll para atualizar posição
			const handleScroll = () => {
				updatePosition();
			};

			window.addEventListener('scroll', handleScroll, true);
			window.addEventListener('resize', handleScroll);

			return () => {
				window.removeEventListener('scroll', handleScroll, true);
				window.removeEventListener('resize', handleScroll);
			};
		} else {
			// Limpar posição quando o modal for fechado
			modalPosition = null;
		}
	});

	// Função para obter estilo do modal baseado na posição calculada
	function getModalStyle() {
		if (modalPosition) {
			// Posicionar na altura do card, centralizado horizontalmente
			// position: fixed já é relativo à viewport, então podemos usar diretamente
			return `position: fixed; top: ${modalPosition.top}px; left: 50%; transform: translateX(-50%); width: 100%; max-width: 700px;`;
		}
		// Se não houver posição calculada, centralizar na tela
		return 'position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; max-width: 700px;';
	}

	async function gerarPDF() {
		if (!registroQuery?.data) return;

		gerando = true;

		try {
			const registro = registroQuery.data;
			const doc = new jsPDF();

			// Adicionar logo no canto superior esquerdo
			let yPosition = 20;
			try {
				const logoImg = await new Promise<HTMLImageElement>((resolve, reject) => {
					const img = new Image();
					img.crossOrigin = 'anonymous';
					img.onload = () => resolve(img);
					img.onerror = (err) => reject(err);
					setTimeout(() => reject(new Error('Timeout loading logo')), 3000);
					img.src = logoGovPE;
				});

				const logoWidth = 25;
				const aspectRatio = logoImg.height / logoImg.width;
				const logoHeight = logoWidth * aspectRatio;

				doc.addImage(logoImg, 'PNG', 15, 10, logoWidth, logoHeight);
				yPosition = 10 + logoHeight + 10;
			} catch (err) {
				console.warn('Erro ao carregar logo:', err);
				yPosition = 20;
			}

			// Cabeçalho padrão do sistema (centralizado)
			doc.setFontSize(14);
			doc.setFont('helvetica', 'bold');
			doc.setTextColor(0, 0, 0);
			doc.text('GOVERNO DO ESTADO DE PERNAMBUCO', 105, Math.max(yPosition - 10, 20), {
				align: 'center'
			});
			doc.setFontSize(12);
			doc.text('SECRETARIA DE ESPORTES', 105, Math.max(yPosition - 2, 28), { align: 'center' });

			yPosition = Math.max(yPosition, 40);
			yPosition += 10;

			// Título do comprovante
			doc.setFontSize(16);
			doc.setTextColor(102, 126, 234); // Cor primária padrão do sistema
			doc.setFont('helvetica', 'bold');
			doc.text('COMPROVANTE DE REGISTRO DE PONTO', 105, yPosition, { align: 'center' });

			yPosition += 15;

			// Informações do Funcionário em tabela
			const funcionarioData: string[][] = [];

			if (registro.funcionario) {
				if (registro.funcionario.matricula) {
					funcionarioData.push(['Matrícula', registro.funcionario.matricula]);
				}
				funcionarioData.push(['Nome', registro.funcionario.nome || '-']);
				if (registro.funcionario.descricaoCargo) {
					funcionarioData.push(['Cargo/Função', registro.funcionario.descricaoCargo]);
				}
				if (registro.funcionario.simbolo) {
					const simboloTipo =
						registro.funcionario.simbolo.tipo === 'cargo_comissionado'
							? 'Cargo Comissionado'
							: 'Função Gratificada';
					funcionarioData.push([
						'Símbolo',
						`${registro.funcionario.simbolo.nome} (${simboloTipo})`
					]);
				}
			}

			if (funcionarioData.length > 0) {
				doc.setFontSize(12);
				doc.setFont('helvetica', 'bold');
				doc.setTextColor(0, 0, 0);
				doc.text('DADOS DO FUNCIONÁRIO', 15, yPosition);
				yPosition += 8;

				autoTable(doc, {
					startY: yPosition,
					head: [['Campo', 'Informação']],
					body: funcionarioData,
					theme: 'striped',
					headStyles: { fillColor: [102, 126, 234] },
					styles: { fontSize: 10 },
					margin: { left: 15, right: 15 }
				});

				type JsPDFWithAutoTable = jsPDF & {
					lastAutoTable?: { finalY: number };
				};
				const finalY = (doc as JsPDFWithAutoTable).lastAutoTable?.finalY ?? yPosition + 10;
				yPosition = finalY + 10;
			}

			// Informações do Registro em tabela
			const config = configQuery?.data;
			const tipoLabel = config
				? getTipoRegistroLabel(registro.tipo, {
						nomeEntrada: config.nomeEntrada,
						nomeSaidaAlmoco: config.nomeSaidaAlmoco,
						nomeRetornoAlmoco: config.nomeRetornoAlmoco,
						nomeSaida: config.nomeSaida
					})
				: getTipoRegistroLabel(registro.tipo);

			const dataHora = formatarDataHoraCompleta(
				registro.data,
				registro.hora,
				registro.minuto,
				registro.segundo
			);

			const registroData: string[][] = [
				['Tipo', tipoLabel],
				['Data e Hora', dataHora],
				['Status', registro.dentroDoPrazo ? 'Dentro do Prazo' : 'Fora do Prazo'],
				['Tolerância', `${registro.toleranciaMinutos} minutos`],
				['Sincronizado', registro.sincronizadoComServidor ? 'Sim (Servidor)' : 'Não (PC Local)']
			];

			doc.setFontSize(12);
			doc.setFont('helvetica', 'bold');
			doc.setTextColor(0, 0, 0);
			doc.text('DADOS DO REGISTRO', 15, yPosition);
			yPosition += 8;

			autoTable(doc, {
				startY: yPosition,
				head: [['Campo', 'Informação']],
				body: registroData,
				theme: 'striped',
				headStyles: { fillColor: [102, 126, 234] },
				styles: { fontSize: 10 },
				margin: { left: 15, right: 15 }
			});

			type JsPDFWithAutoTable2 = jsPDF & {
				lastAutoTable?: { finalY: number };
			};
			const finalY2 = (doc as JsPDFWithAutoTable2).lastAutoTable?.finalY ?? yPosition + 10;
			yPosition = finalY2 + 10;

			// Imagem capturada (se disponível)
			if (registro.imagemUrl) {
				yPosition += 10;
				// Verificar se precisa de nova página
				if (yPosition > 200) {
					doc.addPage();
					yPosition = 20;
				}

				doc.setFontSize(12);
				doc.setFont('helvetica', 'bold');
				doc.setTextColor(0, 0, 0);
				doc.text('FOTO CAPTURADA', 15, yPosition);
				doc.setFont('helvetica', 'normal');
				yPosition += 10;

				try {
					// Carregar imagem usando fetch para evitar problemas de CORS
					const response = await fetch(registro.imagemUrl);
					if (!response.ok) {
						throw new Error('Erro ao carregar imagem');
					}

					const blob = await response.blob();
					const reader = new FileReader();

					// Converter blob para base64
					const base64 = await new Promise<string>((resolve, reject) => {
						reader.onloadend = () => {
							if (typeof reader.result === 'string') {
								resolve(reader.result);
							} else {
								reject(new Error('Erro ao converter imagem'));
							}
						};
						reader.onerror = () => reject(new Error('Erro ao ler imagem'));
						reader.readAsDataURL(blob);
					});

					// Criar elemento de imagem para obter dimensões
					const img = new Image();
					await new Promise<void>((resolve, reject) => {
						img.onload = () => resolve();
						img.onerror = () => reject(new Error('Erro ao processar imagem'));
						img.src = base64;
						setTimeout(() => reject(new Error('Timeout ao processar imagem')), 10000);
					});

					// Calcular dimensões para caber na página (largura máxima 80mm, manter proporção)
					const maxWidth = 80;
					const maxHeight = 60;
					let imgWidth = img.width;
					let imgHeight = img.height;
					const aspectRatio = imgWidth / imgHeight;

					if (imgWidth > maxWidth || imgHeight > maxHeight) {
						if (aspectRatio > 1) {
							// Imagem horizontal
							imgWidth = maxWidth;
							imgHeight = maxWidth / aspectRatio;
						} else {
							// Imagem vertical
							imgHeight = maxHeight;
							imgWidth = maxHeight * aspectRatio;
						}
					}

					// Centralizar imagem
					const xPosition = (doc.internal.pageSize.getWidth() - imgWidth) / 2;

					// Verificar se cabe na página atual
					if (yPosition + imgHeight > doc.internal.pageSize.getHeight() - 20) {
						doc.addPage();
						yPosition = 20;
					}

					// Adicionar imagem ao PDF usando base64
					doc.addImage(base64, 'JPEG', xPosition, yPosition, imgWidth, imgHeight);
					yPosition += imgHeight + 10;
				} catch (error) {
					console.warn('Erro ao adicionar imagem ao PDF:', error);
					doc.setFontSize(10);
					doc.text('Foto não disponível para impressão', 105, yPosition, { align: 'center' });
					yPosition += 6;
				}
			}

			// Rodapé
			const pageCount = doc.getNumberOfPages();
			for (let i = 1; i <= pageCount; i++) {
				doc.setPage(i);
				doc.setFontSize(8);
				doc.setTextColor(128, 128, 128);
				doc.text(
					`SGSE - Sistema de Gerenciamento de Secretaria | Página ${i} de ${pageCount}`,
					doc.internal.pageSize.getWidth() / 2,
					doc.internal.pageSize.getHeight() - 10,
					{ align: 'center' }
				);
			}

			// Salvar
			const nomeArquivo = `comprovante-ponto-${registro.data}-${registro.hora}${registro.minuto.toString().padStart(2, '0')}.pdf`;
			doc.save(nomeArquivo);
		} catch (error) {
			console.error('Erro ao gerar PDF:', error);
			alert('Erro ao gerar comprovante PDF. Tente novamente.');
		} finally {
			gerando = false;
		}
	}
</script>

<div
	class="pointer-events-none fixed inset-0 z-50"
	style="animation: fadeIn 0.2s ease-out;"
	onkeydown={(e) => e.key === 'Escape' && onClose()}
	role="dialog"
	aria-modal="true"
	aria-labelledby="modal-comprovante-title"
>
	<!-- Backdrop leve -->
	<div
		class="pointer-events-auto absolute inset-0 bg-black/20 transition-opacity duration-200"
		onclick={onClose}
	></div>

	<!-- Modal Box -->
	<div
		class="from-base-100 via-base-100 to-primary/5 border-primary/20 pointer-events-auto absolute z-10 flex max-h-[90vh] w-full max-w-2xl transform flex-col overflow-hidden rounded-2xl border-2 bg-gradient-to-br shadow-2xl transition-all duration-300"
		style="animation: slideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); {getModalStyle()}"
		onclick={(e) => e.stopPropagation()}
	>
		<!-- Header Premium com gradiente -->
		<div
			class="from-primary/10 via-primary/5 border-primary/20 flex flex-shrink-0 items-center justify-between border-b-2 bg-gradient-to-r to-transparent px-6 py-5"
		>
			<div class="flex items-center gap-3">
				<div class="bg-primary/20 rounded-xl p-2.5 shadow-lg">
					<Clock class="text-primary h-6 w-6" strokeWidth={2.5} />
				</div>
				<div>
					<h3 id="modal-comprovante-title" class="text-base-content text-xl font-bold">
						Comprovante de Registro de Ponto
					</h3>
					<p class="text-base-content/70 mt-0.5 text-sm">Detalhes do registro realizado</p>
				</div>
			</div>
			<button
				class="btn btn-sm btn-circle btn-ghost hover:bg-base-300 transition-all"
				onclick={onClose}
			>
				<X class="h-5 w-5" />
			</button>
		</div>

		<!-- Conteúdo com rolagem -->
		<div class="modal-scroll flex-1 overflow-y-auto px-6 py-6">
			{#if registroQuery === undefined}
				<div class="flex items-center justify-center py-12">
					<span class="loading loading-spinner loading-lg text-primary"></span>
				</div>
			{:else if !registroQuery?.data}
				<div class="alert alert-error shadow-lg">
					<XCircle class="h-5 w-5" />
					<span class="font-semibold">Erro ao carregar registro</span>
				</div>
			{:else}
				{@const registro = registroQuery.data}
				<div class="space-y-6">
					<!-- Informações do Funcionário -->
					<div
						class="card from-base-100 to-base-200 border-primary/10 border-2 bg-gradient-to-br shadow-lg transition-all hover:shadow-xl"
					>
						<div class="card-body p-6">
							<div class="mb-4 flex items-center gap-3">
								<div class="bg-primary/10 rounded-lg p-2">
									<User class="text-primary h-5 w-5" strokeWidth={2} />
								</div>
								<h4 class="text-base-content text-lg font-bold">Dados do Funcionário</h4>
							</div>
							{#if registro.funcionario}
								<div class="space-y-3">
									{#if registro.funcionario.matricula}
										<div
											class="bg-base-100 border-base-300 flex items-start gap-3 rounded-lg border p-3"
										>
											<div class="flex-1">
												<span
													class="text-base-content/60 text-xs font-semibold tracking-wide uppercase"
													>Matrícula</span
												>
												<p class="text-base-content mt-1 text-base font-semibold">
													{registro.funcionario.matricula}
												</p>
											</div>
										</div>
									{/if}
									<div
										class="bg-base-100 border-base-300 flex items-start gap-3 rounded-lg border p-3"
									>
										<div class="flex-1">
											<span
												class="text-base-content/60 text-xs font-semibold tracking-wide uppercase"
												>Nome</span
											>
											<p class="text-base-content mt-1 text-base font-semibold">
												{registro.funcionario.nome}
											</p>
										</div>
									</div>
									{#if registro.funcionario.descricaoCargo}
										<div
											class="bg-base-100 border-base-300 flex items-start gap-3 rounded-lg border p-3"
										>
											<div class="flex-1">
												<span
													class="text-base-content/60 text-xs font-semibold tracking-wide uppercase"
													>Cargo/Função</span
												>
												<p class="text-base-content mt-1 text-base font-semibold">
													{registro.funcionario.descricaoCargo}
												</p>
											</div>
										</div>
									{/if}
								</div>
							{/if}
						</div>
					</div>

					<!-- Informações do Registro -->
					<div
						class="card from-primary/5 to-primary/10 border-primary/20 border-2 bg-gradient-to-br shadow-lg transition-all hover:shadow-xl"
					>
						<div class="card-body p-6">
							<div class="mb-4 flex items-center gap-3">
								<div class="bg-primary/20 rounded-lg p-2">
									<Clock class="text-primary h-5 w-5" strokeWidth={2} />
								</div>
								<h4 class="text-base-content text-lg font-bold">Dados do Registro</h4>
							</div>
							<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
								<!-- Tipo -->
								<div class="bg-base-100 border-base-300 rounded-lg border p-4 shadow-sm">
									<span class="text-base-content/60 text-xs font-semibold tracking-wide uppercase"
										>Tipo</span
									>
									<p class="text-primary mt-1 text-lg font-bold">
										{configQuery?.data
											? getTipoRegistroLabel(registro.tipo, {
													nomeEntrada: configQuery.data.nomeEntrada,
													nomeSaidaAlmoco: configQuery.data.nomeSaidaAlmoco,
													nomeRetornoAlmoco: configQuery.data.nomeRetornoAlmoco,
													nomeSaida: configQuery.data.nomeSaida
												})
											: getTipoRegistroLabel(registro.tipo)}
									</p>
								</div>

								<!-- Data e Hora -->
								<div class="bg-base-100 border-base-300 rounded-lg border p-4 shadow-sm">
									<span class="text-base-content/60 text-xs font-semibold tracking-wide uppercase"
										>Data e Hora</span
									>
									<p class="text-base-content mt-1 text-lg font-bold">
										{formatarDataHoraCompleta(
											registro.data,
											registro.hora,
											registro.minuto,
											registro.segundo
										)}
									</p>
								</div>

								<!-- Status -->
								<div class="bg-base-100 border-base-300 rounded-lg border p-4 shadow-sm">
									<span class="text-base-content/60 text-xs font-semibold tracking-wide uppercase"
										>Status</span
									>
									<div class="mt-2">
										<span
											class="badge badge-lg gap-2 {registro.dentroDoPrazo
												? 'badge-success'
												: 'badge-error'}"
										>
											{#if registro.dentroDoPrazo}
												<CheckCircle2 class="h-4 w-4" />
											{:else}
												<XCircle class="h-4 w-4" />
											{/if}
											{registro.dentroDoPrazo ? 'Dentro do Prazo' : 'Fora do Prazo'}
										</span>
									</div>
								</div>

								<!-- Tolerância -->
								<div class="bg-base-100 border-base-300 rounded-lg border p-4 shadow-sm">
									<span class="text-base-content/60 text-xs font-semibold tracking-wide uppercase"
										>Tolerância</span
									>
									<p class="text-base-content mt-1 text-lg font-bold">
										{registro.toleranciaMinutos} minutos
									</p>
								</div>
							</div>
						</div>
					</div>

					<!-- Imagem Capturada -->
					{#if registro.imagemUrl}
						<div
							class="card from-base-100 to-base-200 border-primary/10 border-2 bg-gradient-to-br shadow-lg transition-all hover:shadow-xl"
						>
							<div class="card-body p-6">
								<div class="mb-4 flex items-center gap-3">
									<div class="bg-primary/10 rounded-lg p-2">
										<svg
											xmlns="http://www.w3.org/2000/svg"
											class="text-primary h-5 w-5"
											fill="none"
											viewBox="0 0 24 24"
											stroke="currentColor"
										>
											<path
												stroke-linecap="round"
												stroke-linejoin="round"
												stroke-width="2"
												d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
											/>
										</svg>
									</div>
									<h4 class="text-base-content text-lg font-bold">Foto Capturada</h4>
								</div>
								<div
									class="bg-base-100 border-primary/20 flex justify-center rounded-xl border-2 p-4"
								>
									<img
										src={registro.imagemUrl}
										alt="Foto do registro de ponto"
										class="max-h-[300px] max-w-full rounded-lg object-contain shadow-md"
										onerror={(e) => {
											console.error('Erro ao carregar imagem:', e);
											(e.target as HTMLImageElement).style.display = 'none';
										}}
									/>
								</div>
							</div>
						</div>
					{/if}
				</div>
			{/if}
		</div>

		<!-- Footer fixo com botões -->
		<div
			class="border-primary/20 bg-base-100/50 flex flex-shrink-0 justify-end gap-3 border-t-2 px-6 py-4 backdrop-blur-sm"
		>
			<button class="btn btn-outline gap-2" onclick={onClose}>
				<X class="h-4 w-4" />
				Fechar
			</button>
			<button
				class="btn btn-primary gap-2 shadow-lg transition-all hover:shadow-xl"
				onclick={gerarPDF}
				disabled={gerando}
			>
				{#if gerando}
					<span class="loading loading-spinner loading-sm"></span>
					Gerando...
				{:else}
					<Printer class="h-5 w-5" />
					Imprimir Comprovante
				{/if}
			</button>
		</div>
	</div>
</div>

<style>
	@keyframes fadeIn {
		from {
			opacity: 0;
		}
		to {
			opacity: 1;
		}
	}

	@keyframes slideUp {
		from {
			opacity: 0;
			transform: translateY(20px) scale(0.95);
		}
		to {
			opacity: 1;
			transform: translateY(0) scale(1);
		}
	}

	/* Scrollbar customizada para os modais */
	:global(.modal-scroll) {
		scrollbar-width: thin;
		scrollbar-color: hsl(var(--bc) / 0.3) transparent;
		scroll-behavior: smooth;
		-webkit-overflow-scrolling: touch;
	}

	:global(.modal-scroll::-webkit-scrollbar) {
		width: 8px;
	}

	:global(.modal-scroll::-webkit-scrollbar-track) {
		background: transparent;
		border-radius: 4px;
	}

	:global(.modal-scroll::-webkit-scrollbar-thumb) {
		background-color: hsl(var(--bc) / 0.3);
		border-radius: 4px;
		transition: background-color 0.2s ease;
	}

	:global(.modal-scroll::-webkit-scrollbar-thumb:hover) {
		background-color: hsl(var(--bc) / 0.5);
	}
</style>
