<script lang="ts">
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import type { Doc, Id } from '@sgse-app/backend/convex/_generated/dataModel';
	import { useConvexClient, useQuery } from 'convex-svelte';
	import { Pencil, Plus, Trash2, X, Search, Check, FileText } from 'lucide-svelte';
	import { resolve } from '$app/paths';
	import { formatarDataBR } from '$lib/utils/datas';

	const client = useConvexClient();

	// Reactive queries
	// Filtros (listagem)
	let filtroPeriodoInicio = $state('');
	let filtroPeriodoFim = $state('');
	let filtroNumero = $state('');
	let filtroNumeroSei = $state('');

	const atasTotalQuery = useQuery(api.atas.list, {});
	let atasTotal = $derived(atasTotalQuery.data || []);

	const atasQuery = useQuery(api.atas.list, () => ({
		periodoInicio: filtroPeriodoInicio || undefined,
		periodoFim: filtroPeriodoFim || undefined,
		numero: filtroNumero.trim() || undefined,
		numeroSei: filtroNumeroSei.trim() || undefined
	}));
	let atas = $derived(atasQuery.data || []);
	let loadingAtas = $derived(atasQuery.isLoading);
	let errorAtas = $derived(atasQuery.error?.message || null);

	const empresasQuery = useQuery(api.empresas.list, {});
	let empresas = $derived(empresasQuery.data || []);

	const objetosQuery = useQuery(api.objetos.list, {});
	let objetos = $derived(objetosQuery.data || []);

	// Modal state
	let showModal = $state(false);
	let editingId: string | null = $state(null);
	let formData = $state({
		numero: '',
		numeroSei: '',
		empresaId: '' as Id<'empresas'> | '',
		dataInicio: '',
		dataFim: '',
		dataProrrogacao: ''
	});
	let selectedObjetos = $state<Id<'objetos'>[]>([]);
	type ObjetoAtaConfig = {
		quantidadeTotal: number | undefined;
		limitePercentual: number | undefined;
	};
	let objetosConfig = $state<Record<string, ObjetoAtaConfig>>({});
	let searchObjeto = $state('');
	let saving = $state(false);

	// Derived state for filtered objects
	let filteredObjetos = $derived(
		objetos.filter((obj) => obj.nome.toLowerCase().includes(searchObjeto.toLowerCase()))
	);

	// Document state
	let attachmentFiles: File[] = $state([]);
	let attachments = $state<Array<{ _id: Id<'atasDocumentos'>; nome: string; url: string | null }>>(
		[]
	);
	let uploading = $state(false);

	async function openModal(ata?: Doc<'atas'>) {
		if (ata) {
			editingId = ata._id;
			formData = {
				numero: ata.numero,
				numeroSei: ata.numeroSei,
				empresaId: ata.empresaId,
				dataInicio: ata.dataInicio || '',
				dataFim: ata.dataFim || '',
				dataProrrogacao: ata.dataProrrogacao || ''
			};
			// Fetch linked objects
			const linkedObjetos = await client.query(api.atas.getObjetos, { id: ata._id });
			selectedObjetos = linkedObjetos.map((o) => o._id);

			const linkedConfigs = await client.query(api.atas.getObjetosConfig, { id: ata._id });
			objetosConfig = {};
			for (const cfg of linkedConfigs) {
				objetosConfig[String(cfg.objetoId)] = {
					quantidadeTotal: cfg.quantidadeTotal ?? undefined,
					limitePercentual: cfg.limitePercentual ?? 50
				};
			}

			// Fetch attachments
			attachments = await client.query(api.atas.getDocumentos, { ataId: ata._id });
		} else {
			editingId = null;
			formData = {
				numero: '',
				numeroSei: '',
				empresaId: '',
				dataInicio: '',
				dataFim: '',
				dataProrrogacao: ''
			};
			selectedObjetos = [];
			objetosConfig = {};
			attachments = [];
		}
		attachmentFiles = [];
		searchObjeto = '';
		showModal = true;
	}

	function closeModal() {
		showModal = false;
		editingId = null;
	}

	function getObjetoConfig(id: Id<'objetos'>): ObjetoAtaConfig {
		const key = String(id);
		if (!objetosConfig[key]) {
			objetosConfig[key] = { quantidadeTotal: 1, limitePercentual: 50 };
		}
		return objetosConfig[key];
	}

	function toggleObjeto(id: Id<'objetos'>) {
		const key = String(id);
		if (selectedObjetos.includes(id)) {
			selectedObjetos = selectedObjetos.filter((oid) => oid !== id);
			delete objetosConfig[key];
		} else {
			selectedObjetos = [...selectedObjetos, id];
			objetosConfig[key] = { quantidadeTotal: 1, limitePercentual: 50 };
		}
	}

	async function uploadFile(file: File) {
		const uploadUrl = await client.mutation(api.atas.generateUploadUrl, {});
		const result = await fetch(uploadUrl, {
			method: 'POST',
			headers: { 'Content-Type': file.type },
			body: file
		});
		const { storageId } = await result.json();
		return storageId;
	}

	async function handleSubmit(e: Event) {
		e.preventDefault();
		if (!formData.empresaId) {
			alert('Selecione uma empresa.');
			return;
		}
		saving = true;
		try {
			const objetos = selectedObjetos.map((objetoId) => {
				const cfg = objetosConfig[String(objetoId)];
				if (
					!cfg ||
					cfg.quantidadeTotal === undefined ||
					!Number.isFinite(cfg.quantidadeTotal) ||
					cfg.quantidadeTotal <= 0
				) {
					throw new Error(
						'Informe a quantidade (maior que zero) para todos os objetos vinculados.'
					);
				}
				const limitePercentual =
					cfg.limitePercentual === undefined || !Number.isFinite(cfg.limitePercentual)
						? 50
						: cfg.limitePercentual;

				return {
					objetoId,
					quantidadeTotal: cfg.quantidadeTotal,
					limitePercentual
				};
			});

			const payload = {
				numero: formData.numero,
				numeroSei: formData.numeroSei,
				empresaId: formData.empresaId as Id<'empresas'>,
				dataInicio: formData.dataInicio || undefined,
				dataFim: formData.dataFim || undefined,
				dataProrrogacao: formData.dataProrrogacao || undefined,
				objetos
			};

			let ataId: Id<'atas'>;
			if (editingId) {
				await client.mutation(api.atas.update, {
					id: editingId as Id<'atas'>,
					...payload
				});
				ataId = editingId as Id<'atas'>;
			} else {
				ataId = await client.mutation(api.atas.create, payload);
			}

			// Upload attachments
			if (attachmentFiles.length > 0) {
				uploading = true;
				for (const file of attachmentFiles) {
					const storageId = await uploadFile(file);
					await client.mutation(api.atas.saveDocumento, {
						ataId,
						nome: file.name,
						storageId,
						tipo: file.type,
						tamanho: file.size
					});
				}
			}

			closeModal();
		} catch (e) {
			alert('Erro ao salvar: ' + (e as Error).message);
		} finally {
			saving = false;
			uploading = false;
		}
	}

	async function handleDelete(id: Id<'atas'>) {
		if (!confirm('Tem certeza que deseja excluir esta ata?')) return;
		try {
			await client.mutation(api.atas.remove, { id });
		} catch (e) {
			alert('Erro ao excluir: ' + (e as Error).message);
		}
	}

	async function handleDeleteAttachment(docId: Id<'atasDocumentos'>) {
		if (!confirm('Tem certeza que deseja excluir este anexo?')) return;
		try {
			await client.mutation(api.atas.removeDocumento, { id: docId });
			// Refresh attachments list
			if (editingId) {
				attachments = await client.query(api.atas.getDocumentos, {
					ataId: editingId as Id<'atas'>
				});
			}
		} catch (e) {
			alert('Erro ao excluir anexo: ' + (e as Error).message);
		}
	}

	function getEmpresaNome(id: Id<'empresas'>) {
		return empresas.find((e) => e._id === id)?.razao_social || 'Empresa não encontrada';
	}

	function handleAttachmentsSelect(e: Event) {
		const input = e.target as HTMLInputElement;
		if (input.files && input.files.length > 0) {
			attachmentFiles = Array.from(input.files);
		}
	}

	function limparFiltros() {
		filtroPeriodoInicio = '';
		filtroPeriodoFim = '';
		filtroNumero = '';
		filtroNumeroSei = '';
	}
</script>

<main class="container mx-auto flex max-w-7xl flex-col px-4 py-4">
	<div class="breadcrumbs mb-4 text-sm">
		<ul>
			<li><a href={resolve('/')} class="text-primary hover:underline">Dashboard</a></li>
			<li><a href={resolve('/compras')} class="text-primary hover:underline">Compras</a></li>
			<li>Atas</li>
		</ul>
	</div>

	<div class="mb-6">
		<div class="flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center">
			<div class="flex items-center gap-4">
				<div class="bg-accent/10 rounded-xl p-3">
					<FileText class="text-accent h-8 w-8" strokeWidth={2} />
				</div>
				<div>
					<h1 class="text-primary text-3xl font-bold">Atas de Registro de Preços</h1>
					<p class="text-base-content/70">Gerencie atas, vigência, empresa e anexos</p>
				</div>
			</div>
			<button
				class="btn btn-primary gap-2 shadow-md transition-all hover:shadow-lg"
				onclick={() => openModal()}
			>
				<Plus class="h-5 w-5" strokeWidth={2} />
				Nova Ata
			</button>
		</div>
	</div>

	<div class="card bg-base-100/90 border-base-300 mb-6 border shadow-xl backdrop-blur-sm">
		<div class="card-body">
			<div class="grid gap-4 sm:grid-cols-[1fr_auto] sm:items-end">
				<div class="grid grid-cols-1 gap-4 md:grid-cols-4">
					<div class="form-control w-full">
						<label class="label" for="filtro_numero">
							<span class="label-text font-semibold">Número</span>
						</label>
						<input
							id="filtro_numero"
							class="input input-bordered focus:input-primary w-full"
							type="text"
							placeholder="Ex.: 12/2025"
							bind:value={filtroNumero}
						/>
					</div>

					<div class="form-control w-full">
						<label class="label" for="filtro_numeroSei">
							<span class="label-text font-semibold">Número SEI</span>
						</label>
						<input
							id="filtro_numeroSei"
							class="input input-bordered focus:input-primary w-full"
							type="text"
							placeholder="Ex.: 12345.000000/2025-00"
							bind:value={filtroNumeroSei}
						/>
					</div>

					<div class="form-control w-full">
						<label class="label" for="filtro_inicio">
							<span class="label-text font-semibold">Período (início)</span>
						</label>
						<input
							id="filtro_inicio"
							class="input input-bordered focus:input-primary w-full"
							type="date"
							bind:value={filtroPeriodoInicio}
						/>
					</div>

					<div class="form-control w-full">
						<label class="label" for="filtro_fim">
							<span class="label-text font-semibold">Período (fim)</span>
						</label>
						<input
							id="filtro_fim"
							class="input input-bordered focus:input-primary w-full"
							type="date"
							bind:value={filtroPeriodoFim}
						/>
					</div>
				</div>

				<div class="flex items-center justify-between gap-3 sm:min-w-max sm:justify-end">
					<div class="text-base-content/70 text-sm">
						{atas.length} de {atasTotal.length}
					</div>
					<button type="button" class="btn btn-ghost" onclick={limparFiltros}>Limpar</button>
				</div>
			</div>
		</div>
	</div>

	{#if loadingAtas}
		<div class="flex items-center justify-center py-10">
			<span class="loading loading-spinner loading-lg"></span>
		</div>
	{:else if errorAtas}
		<div class="alert alert-error">
			<span>{errorAtas}</span>
		</div>
	{:else}
		<div class="card bg-base-100/90 border-base-300 border shadow-xl backdrop-blur-sm">
			<div class="card-body p-0">
				<div class="overflow-x-auto">
					<table class="table-zebra table w-full">
						<thead>
							<tr>
								<th class="text-base-content border-base-400 border-b font-bold whitespace-nowrap"
									>Número</th
								>
								<th class="text-base-content border-base-400 border-b font-bold whitespace-nowrap"
									>SEI</th
								>
								<th class="text-base-content border-base-400 border-b font-bold whitespace-nowrap"
									>Empresa</th
								>
								<th class="text-base-content border-base-400 border-b font-bold whitespace-nowrap"
									>Vigência</th
								>
								<th
									class="text-base-content border-base-400 border-b text-right font-bold whitespace-nowrap"
									>Ações</th
								>
							</tr>
						</thead>
						<tbody>
							{#if atas.length === 0}
								<tr>
									<td colspan="5" class="py-12 text-center">
										<div class="text-base-content/60 flex flex-col items-center gap-2">
											{#if atasTotal.length === 0}
												<p class="text-lg font-semibold">Nenhuma ata cadastrada</p>
												<p class="text-sm">Clique em “Nova Ata” para cadastrar.</p>
											{:else}
												<p class="text-lg font-semibold">Nenhum resultado encontrado</p>
												<p class="text-sm">Ajuste ou limpe os filtros para ver resultados.</p>
											{/if}
										</div>
									</td>
								</tr>
							{:else}
								{#each atas as ata (ata._id)}
									<tr class="hover:bg-base-200/50 transition-colors">
										<td class="font-medium whitespace-nowrap">{ata.numero}</td>
										<td class="whitespace-nowrap">{ata.numeroSei}</td>
										<td
											class="max-w-md truncate whitespace-nowrap"
											title={getEmpresaNome(ata.empresaId)}
										>
											{getEmpresaNome(ata.empresaId)}
										</td>
										<td class="text-base-content/70 whitespace-nowrap">
											{ata.dataInicio ? formatarDataBR(ata.dataInicio) : '-'} a
											{ata.dataFim ? formatarDataBR(ata.dataFim) : '-'}
											{#if ata.dataProrrogacao}
												<span class="text-base-content/50">
													(prorrogação: {formatarDataBR(ata.dataProrrogacao)})</span
												>
											{/if}
										</td>
										<td class="text-right whitespace-nowrap">
											<div class="flex items-center justify-end gap-1">
												<button
													type="button"
													class="btn btn-ghost btn-sm"
													aria-label="Editar ata"
													onclick={() => openModal(ata)}
												>
													<Pencil size={18} />
												</button>
												<button
													type="button"
													class="btn btn-ghost btn-sm text-error"
													aria-label="Excluir ata"
													onclick={() => handleDelete(ata._id)}
												>
													<Trash2 size={18} />
												</button>
											</div>
										</td>
									</tr>
								{/each}
							{/if}
						</tbody>
					</table>
				</div>
			</div>
		</div>
	{/if}

	{#if showModal}
		<div class="modal modal-open">
			<div class="modal-box max-w-4xl">
				<button
					type="button"
					class="btn btn-sm btn-circle absolute top-2 right-2"
					onclick={closeModal}
					aria-label="Fechar modal"
				>
					<X class="h-5 w-5" />
				</button>

				<h3 class="text-lg font-bold">{editingId ? 'Editar' : 'Nova'} Ata</h3>

				<form class="mt-6 space-y-6" onsubmit={handleSubmit}>
					<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
						<div class="space-y-4">
							<div class="form-control w-full">
								<label class="label" for="numero">
									<span class="label-text font-semibold">Número da Ata</span>
								</label>
								<input
									id="numero"
									class="input input-bordered focus:input-primary w-full"
									type="text"
									bind:value={formData.numero}
									required
								/>
							</div>

							<div class="form-control w-full">
								<label class="label" for="numeroSei">
									<span class="label-text font-semibold">Número SEI</span>
								</label>
								<input
									id="numeroSei"
									class="input input-bordered focus:input-primary w-full"
									type="text"
									bind:value={formData.numeroSei}
									required
								/>
							</div>

							<div class="form-control w-full">
								<label class="label" for="empresa">
									<span class="label-text font-semibold">Empresa</span>
								</label>
								<select
									id="empresa"
									class="select select-bordered focus:select-primary w-full"
									bind:value={formData.empresaId}
									required
								>
									<option value="">Selecione uma empresa...</option>
									{#each empresas as empresa (empresa._id)}
										<option value={empresa._id}>{empresa.razao_social}</option>
									{/each}
								</select>
							</div>

							<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
								<div class="form-control w-full">
									<label class="label" for="dataInicio">
										<span class="label-text font-semibold">Data Início</span>
									</label>
									<input
										id="dataInicio"
										class="input input-bordered focus:input-primary w-full"
										type="date"
										bind:value={formData.dataInicio}
									/>
								</div>
								<div class="form-control w-full">
									<label class="label" for="dataFim">
										<span class="label-text font-semibold">Data Fim</span>
									</label>
									<input
										id="dataFim"
										class="input input-bordered focus:input-primary w-full"
										type="date"
										bind:value={formData.dataFim}
									/>
								</div>
								<div class="form-control w-full">
									<label class="label" for="dataProrrogacao">
										<span class="label-text font-semibold">Data Prorrogação</span>
									</label>
									<input
										id="dataProrrogacao"
										class="input input-bordered focus:input-primary w-full"
										type="date"
										bind:value={formData.dataProrrogacao}
									/>
								</div>
							</div>
						</div>

						<div class="space-y-4">
							<div class="flex items-center justify-between">
								<div class="font-semibold">Objetos Vinculados</div>
								<span class="badge badge-outline">{selectedObjetos.length}</span>
							</div>

							<div class="form-control w-full">
								<label class="label" for="buscar_objeto">
									<span class="label-text font-semibold">Buscar objetos</span>
								</label>
								<div class="relative">
									<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
										<Search size={16} class="text-base-content/40" />
									</div>
									<input
										id="buscar_objeto"
										type="text"
										placeholder="Digite para filtrar..."
										class="input input-bordered focus:input-primary w-full pl-10"
										bind:value={searchObjeto}
									/>
								</div>
							</div>

							<div class="border-base-300 max-h-52 overflow-y-auto rounded-lg border p-2">
								{#if filteredObjetos.length === 0}
									<p class="text-base-content/60 px-2 py-3 text-center text-sm">
										Nenhum objeto encontrado.
									</p>
								{:else}
									{#each filteredObjetos as objeto (objeto._id)}
										{@const isSelected = selectedObjetos.includes(objeto._id)}
										<label
											class="hover:bg-base-200/50 flex cursor-pointer items-center gap-3 rounded-md px-2 py-2 {isSelected
												? 'bg-primary/5'
												: ''}"
										>
											<input
												type="checkbox"
												class="checkbox checkbox-primary checkbox-sm"
												checked={isSelected}
												onchange={() => toggleObjeto(objeto._id)}
												aria-label="Vincular objeto {objeto.nome}"
											/>
											<span class="flex-1 truncate text-sm">{objeto.nome}</span>
											{#if isSelected}
												<Check size={16} class="text-primary" />
											{/if}
										</label>
									{/each}
								{/if}
							</div>

							{#if selectedObjetos.length > 0}
								<div class="border-base-300 border-t pt-4">
									<div class="font-semibold">Configuração por objeto</div>
									<p class="text-base-content/60 mt-1 text-xs">
										Defina a quantidade total do objeto na ata e o limite de uso em % (padrão 50%).
									</p>
									<div class="mt-3 max-h-52 space-y-3 overflow-y-auto">
										{#each selectedObjetos as objetoId (objetoId)}
											{@const obj = objetos.find((o) => o._id === objetoId)}
											{@const cfg = getObjetoConfig(objetoId)}
											<div class="border-base-300 rounded-lg border p-3">
												<div class="text-sm font-semibold">{obj?.nome || 'Objeto'}</div>
												<div class="mt-3 grid grid-cols-1 gap-3 md:grid-cols-2">
													<div class="form-control w-full">
														<label class="label" for={`qtd_${objetoId}`}>
															<span class="label-text text-xs font-semibold">Quantidade na ata</span
															>
														</label>
														<input
															id={`qtd_${objetoId}`}
															class="input input-bordered input-sm focus:input-primary w-full"
															type="number"
															min="1"
															required
															bind:value={cfg.quantidadeTotal}
														/>
													</div>
													<div class="form-control w-full">
														<label class="label" for={`limite_${objetoId}`}>
															<span class="label-text text-xs font-semibold">Limite (%)</span>
														</label>
														<input
															id={`limite_${objetoId}`}
															class="input input-bordered input-sm focus:input-primary w-full"
															type="number"
															min="0"
															max="100"
															placeholder="50"
															bind:value={cfg.limitePercentual}
														/>
													</div>
												</div>
											</div>
										{/each}
									</div>
								</div>
							{/if}

							<div class="border-base-300 border-t pt-4">
								<div class="font-semibold">Anexos</div>
								<div class="mt-2 space-y-2">
									<input
										id="anexos"
										type="file"
										multiple
										class="file-input file-input-bordered w-full"
										onchange={handleAttachmentsSelect}
									/>

									{#if attachments.length > 0}
										<div
											class="border-base-300 max-h-40 space-y-2 overflow-y-auto rounded-lg border p-2"
										>
											{#each attachments as doc (doc._id)}
												<div class="flex items-center justify-between gap-2 text-sm">
													<a
														href={doc.url}
														target="_blank"
														rel="noopener noreferrer"
														class="link link-primary max-w-[260px] truncate"
													>
														{doc.nome}
													</a>
													<button
														type="button"
														class="btn btn-ghost btn-xs text-error"
														onclick={() => handleDeleteAttachment(doc._id)}
														aria-label="Excluir anexo"
													>
														<X size={16} />
													</button>
												</div>
											{/each}
										</div>
									{/if}
								</div>
							</div>
						</div>
					</div>

					<div class="modal-action">
						<button type="button" class="btn" onclick={closeModal} disabled={saving || uploading}>
							Cancelar
						</button>
						<button type="submit" class="btn btn-primary" disabled={saving || uploading}>
							{#if saving || uploading}
								<span class="loading loading-spinner loading-sm"></span>
							{/if}
							{saving || uploading ? 'Salvando...' : 'Salvar'}
						</button>
					</div>
				</form>
			</div>
			<button type="button" class="modal-backdrop" onclick={closeModal} aria-label="Fechar modal"
			></button>
		</div>
	{/if}
</main>
