<script lang="ts">
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
	import { useConvexClient, useQuery } from 'convex-svelte';
	import {
		AlertTriangle,
		CheckCircle,
		Clock,
		Edit,
		Plus,
		Save,
		Send,
		Trash2,
		X,
		XCircle
	} from 'lucide-svelte';
	import { page } from '$app/stores';
	import { maskCurrencyBRL } from '$lib/utils/masks';

	const pedidoId = $page.params.id as Id<'pedidos'>;
	const client = useConvexClient();

	// Reactive queries
	const pedidoQuery = useQuery(api.pedidos.get, { id: pedidoId });
	const itemsQuery = useQuery(api.pedidos.getItems, { pedidoId });
	const historyQuery = useQuery(api.pedidos.getHistory, { pedidoId });
	const objetosQuery = useQuery(api.objetos.list, {});
	const acoesQuery = useQuery(api.acoes.list, {});

	// Derived state
	let pedido = $derived(pedidoQuery.data);
	let items = $derived(itemsQuery.data || []);
	let history = $derived(historyQuery.data || []);
	let objetos = $derived(objetosQuery.data || []);
	let acoes = $derived(acoesQuery.data || []);

	// Group items by user
	let groupedItems = $derived.by(() => {
		const groups: Record<string, { name: string; items: typeof items }> = {};
		for (const item of items) {
			const userId = item.adicionadoPor;
			if (!groups[userId]) {
				groups[userId] = {
					name: item.adicionadoPorNome,
					items: []
				};
			}
			groups[userId].items.push(item);
		}
		return Object.values(groups);
	});

	let loading = $derived(
		pedidoQuery.isLoading ||
			itemsQuery.isLoading ||
			historyQuery.isLoading ||
			objetosQuery.isLoading ||
			acoesQuery.isLoading
	);

	let error = $derived(
		pedidoQuery.error?.message ||
			itemsQuery.error?.message ||
			historyQuery.error?.message ||
			objetosQuery.error?.message ||
			acoesQuery.error?.message ||
			null
	);

	// Add Item State
	let showAddItem = $state(false);
	let newItem = $state({
		objetoId: '' as string,
		valorEstimado: '',
		quantidade: 1,
		modalidade: 'consumo' as 'dispensa' | 'inexgibilidade' | 'adesao' | 'consumo',
		acaoId: '' as string
	});
	let addingItem = $state(false);

	// Edit SEI State
	let editingSei = $state(false);
	let seiValue = $state('');
	let updatingSei = $state(false);

	async function handleAddItem() {
		if (!newItem.objetoId || !newItem.valorEstimado) return;
		addingItem = true;
		try {
			await client.mutation(api.pedidos.addItem, {
				pedidoId,
				objetoId: newItem.objetoId as Id<'objetos'>,
				valorEstimado: newItem.valorEstimado,
				quantidade: newItem.quantidade,
				modalidade: newItem.modalidade,
				acaoId: newItem.acaoId ? (newItem.acaoId as Id<'acoes'>) : undefined
			});
			newItem = {
				objetoId: '',
				valorEstimado: '',
				quantidade: 1,
				modalidade: 'consumo',
				acaoId: ''
			};
			showAddItem = false;
		} catch (e) {
			alert('Erro ao adicionar item: ' + (e as Error).message);
		} finally {
			addingItem = false;
		}
	}

	async function handleUpdateQuantity(itemId: Id<'objetoItems'>, novaQuantidade: number) {
		if (novaQuantidade < 1) {
			alert('Quantidade deve ser pelo menos 1.');
			return;
		}
		try {
			await client.mutation(api.pedidos.updateItemQuantity, {
				itemId,
				novaQuantidade
			});
		} catch (e) {
			alert('Erro ao atualizar quantidade: ' + (e as Error).message);
		}
	}

	async function handleRemoveItem(itemId: Id<'objetoItems'>) {
		if (!confirm('Remover este item?')) return;
		try {
			await client.mutation(api.pedidos.removeItem, { itemId });
		} catch (e) {
			alert('Erro ao remover item: ' + (e as Error).message);
		}
	}

	async function updateStatus(
		novoStatus:
			| 'cancelado'
			| 'concluido'
			| 'em_rascunho'
			| 'aguardando_aceite'
			| 'em_analise'
			| 'precisa_ajustes'
	) {
		if (!confirm(`Confirmar alteração de status para: ${novoStatus}?`)) return;
		try {
			await client.mutation(api.pedidos.updateStatus, {
				pedidoId,
				novoStatus
			});
		} catch (e) {
			alert('Erro ao atualizar status: ' + (e as Error).message);
		}
	}

	function getObjetoName(id: string) {
		return objetos.find((o) => o._id === id)?.nome || 'Objeto desconhecido';
	}

	function getAcaoName(id: string | undefined) {
		if (!id) return '-';
		return acoes.find((a) => a._id === id)?.nome || '-';
	}

	function handleObjetoChange(id: string) {
		newItem.objetoId = id;
		const objeto = objetos.find((o) => o._id === id);
		if (objeto) {
			newItem.valorEstimado = maskCurrencyBRL(objeto.valorEstimado || '');
		} else {
			newItem.valorEstimado = '';
		}
	}

	function parseMoneyToNumber(value: string): number {
		const cleanValue = value.replace(/[^0-9,]/g, '').replace(',', '.');
		return parseFloat(cleanValue) || 0;
	}

	function calculateItemTotal(valorEstimado: string, quantidade: number): number {
		const unitValue = parseMoneyToNumber(valorEstimado);
		return unitValue * quantidade;
	}

	let totalGeral = $derived(
		items.reduce((sum, item) => sum + calculateItemTotal(item.valorEstimado, item.quantidade), 0)
	);

	function formatStatus(status: string) {
		switch (status) {
			case 'em_rascunho':
				return 'Rascunho';
			case 'aguardando_aceite':
				return 'Aguardando Aceite';
			case 'em_analise':
				return 'Em Análise';
			case 'precisa_ajustes':
				return 'Precisa de Ajustes';
			case 'concluido':
				return 'Concluído';
			case 'cancelado':
				return 'Cancelado';
			default:
				return status;
		}
	}

	async function handleUpdateSei() {
		if (!seiValue.trim()) {
			alert('O número SEI não pode estar vazio.');
			return;
		}
		updatingSei = true;
		try {
			await client.mutation(api.pedidos.updateSeiNumber, {
				pedidoId,
				numeroSei: seiValue.trim()
			});
			editingSei = false;
		} catch (e) {
			alert('Erro ao atualizar número SEI: ' + (e as Error).message);
		} finally {
			updatingSei = false;
		}
	}

	function startEditingSei() {
		seiValue = pedido?.numeroSei || '';
		editingSei = true;
	}

	function cancelEditingSei() {
		editingSei = false;
		seiValue = '';
	}

	function getStatusColor(status: string) {
		switch (status) {
			case 'em_rascunho':
				return 'bg-gray-100 text-gray-800';
			case 'aguardando_aceite':
				return 'bg-yellow-100 text-yellow-800';
			case 'em_analise':
				return 'bg-blue-100 text-blue-800';
			case 'precisa_ajustes':
				return 'bg-orange-100 text-orange-800';
			case 'concluido':
				return 'bg-green-100 text-green-800';
			case 'cancelado':
				return 'bg-red-100 text-red-800';
			default:
				return 'bg-gray-100 text-gray-800';
		}
	}

	function getHistoryIcon(acao: string) {
		switch (acao) {
			case 'criacao_pedido':
				return '📝';
			case 'adicao_item':
				return '➕';
			case 'remocao_item':
				return '🗑️';
			case 'alteracao_quantidade':
				return '🔢';
			case 'alteracao_status':
				return '🔄';
			case 'atualizacao_sei':
				return '📋';
			default:
				return '•';
		}
	}

	function formatHistoryEntry(entry: {
		acao: string;
		detalhes: string | undefined;
		usuarioNome: string;
	}): string {
		try {
			const detalhes = entry.detalhes ? JSON.parse(entry.detalhes) : {};

			switch (entry.acao) {
				case 'criacao_pedido':
					return `${entry.usuarioNome} criou o pedido ${detalhes.numeroSei || ''}`;

				case 'adicao_item': {
					const objeto = objetos.find((o) => o._id === detalhes.objetoId);
					const nomeObjeto = objeto?.nome || 'Objeto desconhecido';
					const quantidade = detalhes.quantidade || 1;
					return `${entry.usuarioNome} adicionou ${quantidade}x ${nomeObjeto} (${detalhes.valor})`;
				}

				case 'remocao_item': {
					const objeto = objetos.find((o) => o._id === detalhes.objetoId);
					const nomeObjeto = objeto?.nome || 'Objeto desconhecido';
					return `${entry.usuarioNome} removeu ${nomeObjeto}`;
				}

				case 'alteracao_quantidade': {
					const objeto = objetos.find((o) => o._id === detalhes.objetoId);
					const nomeObjeto = objeto?.nome || 'Objeto desconhecido';
					return `${entry.usuarioNome} alterou a quantidade de ${nomeObjeto} de ${detalhes.quantidadeAnterior} para ${detalhes.novaQuantidade}`;
				}

				case 'alteracao_status':
					return `${entry.usuarioNome} alterou o status para "${formatStatus(detalhes.novoStatus)}"`;
				case 'atualizacao_sei':
					return `${entry.usuarioNome} atualizou o número SEI para "${detalhes.numeroSei}"`;

				default:
					return `${entry.usuarioNome} realizou: ${entry.acao}`;
			}
		} catch {
			return `${entry.usuarioNome} - ${entry.acao}`;
		}
	}
</script>

<div class="container mx-auto p-6">
	{#if loading}
		<p>Carregando...</p>
	{:else if error}
		<p class="text-red-600">{error}</p>
	{:else if pedido}
		<div class="mb-6 flex items-start justify-between">
			<div>
				<h1 class="flex items-center gap-3 text-2xl font-bold">
					{#if editingSei}
						<div class="flex items-center gap-2">
							<input
								type="text"
								bind:value={seiValue}
								class="rounded border px-2 py-1 text-sm"
								placeholder="Número SEI"
								disabled={updatingSei}
							/>
							<button
								onclick={handleUpdateSei}
								disabled={updatingSei}
								class="rounded bg-green-600 p-1 text-white hover:bg-green-700 disabled:opacity-50"
								title="Salvar"
							>
								<Save size={16} />
							</button>
							<button
								onclick={cancelEditingSei}
								disabled={updatingSei}
								class="rounded bg-gray-400 p-1 text-white hover:bg-gray-500 disabled:opacity-50"
								title="Cancelar"
							>
								<X size={16} />
							</button>
						</div>
					{:else}
						<div class="flex items-center gap-2">
							<span>Pedido {pedido.numeroSei || 'sem número SEI'}</span>
							{#if pedido.status === 'em_rascunho' || pedido.status === 'precisa_ajustes'}
								<button
									onclick={startEditingSei}
									class="rounded bg-blue-100 p-1 text-blue-600 hover:bg-blue-200"
									title="Editar número SEI"
								>
									<Edit size={16} />
								</button>
							{/if}
						</div>
					{/if}
					<span class="rounded-full px-3 py-1 text-sm font-medium {getStatusColor(pedido.status)}">
						{formatStatus(pedido.status)}
					</span>
				</h1>
				{#if !pedido.numeroSei}
					<p class="mt-1 text-sm text-amber-600">
						⚠️ Este pedido não possui número SEI. Adicione um número SEI quando disponível.
					</p>
				{/if}
			</div>

			<div class="flex gap-2">
				{#if pedido.status === 'em_rascunho' || pedido.status === 'precisa_ajustes'}
					<button
						onclick={() => updateStatus('aguardando_aceite')}
						class="flex items-center gap-2 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
					>
						<Send size={18} /> Enviar para Aceite
					</button>
				{/if}

				{#if pedido.status === 'aguardando_aceite'}
					<button
						onclick={() => updateStatus('em_analise')}
						class="flex items-center gap-2 rounded bg-indigo-600 px-4 py-2 text-white hover:bg-indigo-700"
					>
						<Clock size={18} /> Iniciar Análise
					</button>
				{/if}

				{#if pedido.status === 'em_analise'}
					<button
						onclick={() => updateStatus('concluido')}
						class="flex items-center gap-2 rounded bg-green-600 px-4 py-2 text-white hover:bg-green-700"
					>
						<CheckCircle size={18} /> Concluir
					</button>
					<button
						onclick={() => updateStatus('precisa_ajustes')}
						class="flex items-center gap-2 rounded bg-orange-500 px-4 py-2 text-white hover:bg-orange-600"
					>
						<AlertTriangle size={18} /> Solicitar Ajustes
					</button>
				{/if}

				{#if pedido.status !== 'cancelado' && pedido.status !== 'concluido'}
					<button
						onclick={() => updateStatus('cancelado')}
						class="flex items-center gap-2 rounded bg-red-100 px-4 py-2 text-red-700 hover:bg-red-200"
					>
						<XCircle size={18} /> Cancelar
					</button>
				{/if}
			</div>
		</div>

		<!-- Items Section -->
		<div class="mb-6 overflow-hidden rounded-lg bg-white shadow-md">
			<div class="flex items-center justify-between border-b border-gray-200 px-6 py-4">
				<h2 class="text-lg font-semibold">Itens do Pedido</h2>
				{#if pedido.status === 'em_rascunho' || pedido.status === 'precisa_ajustes'}
					<button
						onclick={() => (showAddItem = true)}
						class="flex items-center gap-1 text-sm font-medium text-blue-600 hover:text-blue-800"
					>
						<Plus size={16} /> Adicionar Item
					</button>
				{/if}
			</div>

			{#if showAddItem}
				<div class="border-b border-gray-200 bg-gray-50 px-6 py-4">
					<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
						<div class="col-span-1 md:col-span-2 lg:col-span-1">
							<label for="objeto-select" class="mb-1 block text-xs font-medium text-gray-500"
								>Objeto</label
							>
							<select
								id="objeto-select"
								bind:value={newItem.objetoId}
								onchange={(e) => handleObjetoChange(e.currentTarget.value)}
								class="w-full rounded-md border-gray-300 text-sm shadow-sm"
							>
								<option value="">Selecione...</option>
								{#each objetos as o (o._id)}
									<option value={o._id}>{o.nome} ({o.unidade})</option>
								{/each}
							</select>
						</div>
						<div>
							<label for="quantidade-input" class="mb-1 block text-xs font-medium text-gray-500"
								>Quantidade</label
							>
							<input
								id="quantidade-input"
								type="number"
								min="1"
								bind:value={newItem.quantidade}
								class="w-full rounded-md border-gray-300 text-sm shadow-sm"
								placeholder="1"
							/>
						</div>
						<div>
							<label for="valor-input" class="mb-1 block text-xs font-medium text-gray-500"
								>Valor Estimado</label
							>
							<input
								id="valor-input"
								type="text"
								bind:value={newItem.valorEstimado}
								oninput={(e) => (newItem.valorEstimado = maskCurrencyBRL(e.currentTarget.value))}
								class="w-full rounded-md border-gray-300 text-sm shadow-sm"
								placeholder="R$ 0,00"
							/>
						</div>
						<div>
							<label for="modalidade-select" class="mb-1 block text-xs font-medium text-gray-500"
								>Modalidade</label
							>
							<select
								id="modalidade-select"
								bind:value={newItem.modalidade}
								class="w-full rounded-md border-gray-300 text-sm shadow-sm"
							>
								<option value="consumo">Consumo</option>
								<option value="dispensa">Dispensa</option>
								<option value="inexgibilidade">Inexigibilidade</option>
								<option value="adesao">Adesão</option>
							</select>
						</div>
						<div>
							<label for="acao-select" class="mb-1 block text-xs font-medium text-gray-500"
								>Ação (Opcional)</label
							>
							<select
								id="acao-select"
								bind:value={newItem.acaoId}
								class="w-full rounded-md border-gray-300 text-sm shadow-sm"
							>
								<option value="">Selecione...</option>
								{#each acoes as a (a._id)}
									<option value={a._id}>{a.nome}</option>
								{/each}
							</select>
						</div>
					</div>
					<div class="mt-4 flex justify-end gap-2">
						<button
							onclick={() => (showAddItem = false)}
							class="rounded bg-gray-200 px-3 py-2 text-sm text-gray-700 hover:bg-gray-300"
						>
							Cancelar
						</button>
						<button
							onclick={handleAddItem}
							disabled={addingItem}
							class="rounded bg-blue-600 px-3 py-2 text-sm text-white hover:bg-blue-700"
						>
							Adicionar
						</button>
					</div>
				</div>
			{/if}

			<div class="flex flex-col">
				{#each groupedItems as group (group.name)}
					<div class="border-b border-gray-200 bg-gray-100 px-6 py-2 font-medium text-gray-700">
						Adicionado por: {group.name}
					</div>
					<table class="min-w-full divide-y divide-gray-200">
						<thead class="bg-gray-50">
							<tr>
								<th
									class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
									>Objeto</th
								>
								<th
									class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
									>Qtd</th
								>
								<th
									class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
									>Valor Est.</th
								>
								<th
									class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
									>Modalidade</th
								>
								<th
									class="px-6 py-3 text-left text-xs font-medium tracking-wider text-gray-500 uppercase"
									>Ação</th
								>
								<th
									class="px-6 py-3 text-right text-xs font-medium tracking-wider text-gray-500 uppercase"
									>Total</th
								>
								<th
									class="px-6 py-3 text-right text-xs font-medium tracking-wider text-gray-500 uppercase"
									>Ações</th
								>
							</tr>
						</thead>
						<tbody class="divide-y divide-gray-200 bg-white">
							{#each group.items as item (item._id)}
								<tr>
									<td class="px-6 py-4 whitespace-nowrap">{getObjetoName(item.objetoId)}</td>
									<td class="px-6 py-4 whitespace-nowrap">
										{#if pedido.status === 'em_rascunho' || pedido.status === 'precisa_ajustes'}
											<input
												type="number"
												min="1"
												value={item.quantidade}
												onchange={(e) =>
													handleUpdateQuantity(item._id, parseInt(e.currentTarget.value) || 1)}
												class="w-20 rounded border px-2 py-1 text-sm"
											/>
										{:else}
											{item.quantidade}
										{/if}
									</td>
									<td class="px-6 py-4 whitespace-nowrap">
										{maskCurrencyBRL(item.valorEstimado) || 'R$ 0,00'}
									</td>
									<td class="px-6 py-4 text-sm whitespace-nowrap text-gray-600">
										{item.modalidade}
									</td>
									<td class="px-6 py-4 text-sm whitespace-nowrap text-gray-600">
										{getAcaoName(item.acaoId)}
									</td>
									<td class="px-6 py-4 text-right font-medium whitespace-nowrap">
										R$ {calculateItemTotal(item.valorEstimado, item.quantidade)
											.toFixed(2)
											.replace('.', ',')}
									</td>
									<td class="px-6 py-4 text-right text-sm font-medium whitespace-nowrap">
										{#if pedido.status === 'em_rascunho' || pedido.status === 'precisa_ajustes'}
											<button
												onclick={() => handleRemoveItem(item._id)}
												class="text-red-600 hover:text-red-900"
											>
												<Trash2 size={16} />
											</button>
										{/if}
									</td>
								</tr>
							{/each}
						</tbody>
					</table>
				{/each}

				{#if items.length === 0}
					<div class="px-6 py-4 text-center text-gray-500">Nenhum item adicionado.</div>
				{:else}
					<div class="flex justify-end bg-gray-50 px-6 py-4">
						<div class="text-base font-bold text-gray-900">
							Total Geral: R$ {totalGeral.toFixed(2).replace('.', ',')}
						</div>
					</div>
				{/if}
			</div>
		</div>

		<!-- Histórico -->
		<div class="rounded-lg bg-white p-6 shadow">
			<h2 class="mb-4 text-lg font-semibold text-gray-900">Histórico</h2>
			<div class="space-y-3">
				{#if history.length === 0}
					<p class="text-sm text-gray-500">Nenhum histórico disponível.</p>
				{:else}
					{#each history as entry (entry._id)}
						<div
							class="flex items-start gap-3 rounded-lg border border-gray-200 p-3 hover:bg-gray-50"
						>
							<div class="flex-shrink-0 text-2xl">
								{getHistoryIcon(entry.acao)}
							</div>
							<div class="min-w-0 flex-1">
								<p class="text-sm text-gray-900">
									{formatHistoryEntry(entry)}
								</p>
								<p class="mt-1 text-xs text-gray-500">
									{new Date(entry.data).toLocaleString('pt-BR', {
										day: '2-digit',
										month: '2-digit',
										year: 'numeric',
										hour: '2-digit',
										minute: '2-digit'
									})}
								</p>
							</div>
						</div>
					{/each}
				{/if}
			</div>
		</div>
	{/if}
</div>
