<script lang="ts">
	import { browser } from '$app/environment';
	import { useQuery, useConvexClient } from 'convex-svelte';
	import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
	import { api } from '@sgse-app/backend/convex/_generated/api';
	import type { AtaqueCiberneticoTipo, SeveridadeSeguranca } from '@sgse-app/backend/convex/schema';
	import { authStore } from '$lib/stores/auth.svelte';
	import jsPDF from 'jspdf';
	import autoTable from 'jspdf-autotable';

	const client = useConvexClient();
	const visaoCamadas = useQuery(api.security.obterVisaoCamadas, { periodoHoras: 6, buckets: 28 });
	const eventos = useQuery(api.security.listarEventosSeguranca, { limit: 120 });
	const reputacoes = useQuery(api.security.listarReputacoes, { limit: 60, lista: 'blacklist' });
	const regrasPorta = useQuery(api.security.listarRegrasPorta, {});
	const configsRateLimit = useQuery(api.security.listarConfigsRateLimit, {
		ativo: true,
		limit: 50
	});
	const meuPerfil = useQuery(api.usuarios.obterPerfil, {});
	const usuariosQuery = useQuery(api.usuarios.listar, {});
	const usuariosParaChat = useQuery(api.usuarios.listarParaChat, {});
	const relatoriosRecentes = useQuery(api.security.listarRelatoriosRecentes, { limit: 10 });
	const health = useQuery(api.security.healthStatus, {});
	const alertConfigs = useQuery(api.security.listarAlertConfigs, { limit: 100 });

	// Estado local para preferências de alertas
	let alertNomeConfig = $state('');
	let alertEmails = $state('');
	let alertSeveridadeMin = $state<SeveridadeSeguranca>('alto');
	let alertTiposAtaque = $state<string[]>([]);
	let alertReenvioMin = $state(15);
	let alertTemplate = $state('incidente_critico');
	let alertUsersChat = $state('');
	let chatSeveridadeMin = $state<SeveridadeSeguranca>('alto');
	let chatTiposAtaque = $state<string[]>([]);
	let chatReenvioMin = $state(10);
	let enviarPorEmail = $state(true);
	let enviarPorChat = $state(false);
	let editarAlertConfigId = $state<Id<'alertConfigs'> | null>(null);

	// Sugestões a partir de configs salvas (podem ser usadas no futuro para autocomplete)
	// const sugestoesEmails = $derived.by(() => {
	// 	const emails: string[] = [];
	// 	for (const cfg of alertConfigs?.data ?? []) {
	// 		for (const e of cfg.emails ?? []) {
	// 			if (!emails.includes(e)) emails.push(e);
	// 		}
	// 	}
	// 	for (const u of usuariosQuery?.data ?? []) {
	// 		if (u?.email && !emails.includes(u.email)) emails.push(u.email);
	// 	}
	// 	return emails.slice(0, 16);
	// });
	// const sugestoesChatUsers = $derived.by(() => {
	// 	const emails: string[] = [];
	// 	for (const cfg of alertConfigs?.data ?? []) {
	// 		for (const u of cfg.chatUsers ?? []) {
	// 			if (!emails.includes(u)) emails.push(u);
	// 		}
	// 	}
	// 	for (const u of usuariosQuery?.data ?? []) {
	// 		if (u?.email && !emails.includes(u.email)) emails.push(u.email);
	// 	}
	// 	return emails.slice(0, 16);
	// });
	function adicionarEmailSugestao(email: string) {
		const linhas = alertEmails
			.split('\n')
			.map((s) => s.trim())
			.filter(Boolean);
		if (!linhas.includes(email)) {
			linhas.push(email);
			alertEmails = linhas.join('\n');
		}
	}
	function adicionarChatSugestao(user: string) {
		const linhas = alertUsersChat
			.split('\n')
			.map((s) => s.trim())
			.filter(Boolean);
		if (!linhas.includes(user)) {
			linhas.push(user);
			alertUsersChat = linhas.join('\n');
		}
	}

	function parseLinhasParaArray(valor: string): string[] {
		return valor
			.split('\n')
			.map((s) => s.trim())
			.filter((s) => s.length > 0);
	}
	function limparFormularioAlertas() {
		alertNomeConfig = '';
		alertEmails = '';
		alertSeveridadeMin = 'alto';
		alertTiposAtaque = [];
		alertReenvioMin = 15;
		alertTemplate = 'incidente_critico';
		alertUsersChat = '';
		chatSeveridadeMin = 'alto';
		chatTiposAtaque = [];
		chatReenvioMin = 10;
		enviarPorEmail = true;
		enviarPorChat = false;
		editarAlertConfigId = null;
	}
	async function salvarPreferenciasAlertas(configId?: string) {
		try {
			if (!alertNomeConfig.trim()) {
				feedback = { tipo: 'error', mensagem: 'Por favor, informe um nome para a configuração.' };
				return;
			}
			const canais = { email: enviarPorEmail, chat: enviarPorChat };
			const resp = await client.mutation(api.security.salvarAlertConfig, {
				configId: configId as Id<'alertConfigs'> | undefined,
				nome: alertNomeConfig.trim(),
				canais,
				emails: parseLinhasParaArray(alertEmails),
				chatUsers: parseLinhasParaArray(alertUsersChat),
				severidadeMin: alertSeveridadeMin,
				tiposAtaque: alertTiposAtaque as AtaqueCiberneticoTipo[],
				reenvioMin: alertReenvioMin,
				criadoPor: obterUsuarioId()
			});
			feedback = {
				tipo: 'success',
				mensagem: editarAlertConfigId ? 'Configuração atualizada.' : 'Nova configuração salva.'
			};
			editarAlertConfigId = resp._id as Id<'alertConfigs'>;
			// Não limpar o formulário após salvar, permitindo edição contínua
			return resp._id;
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}
	async function excluirPreferenciasAlertas(configId: Id<'alertConfigs'>) {
		try {
			await client.mutation(api.security.deletarAlertConfig, { configId });
			feedback = { tipo: 'success', mensagem: 'Configuração removida.' };
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}
	function carregarParaEdicao(config: {
		_id: Id<'alertConfigs'>;
		nome: string;
		canais: { email: boolean; chat: boolean };
		emails: string[];
		chatUsers: string[];
		severidadeMin: SeveridadeSeguranca;
		tiposAtaque?: AtaqueCiberneticoTipo[];
		reenvioMin: number;
	}) {
		alertNomeConfig = config.nome ?? '';
		alertTemplate = 'incidente_critico'; // Mantém o template padrão
		enviarPorEmail = config.canais?.email ?? true;
		enviarPorChat = config.canais?.chat ?? false;
		alertEmails = (config.emails ?? []).join('\n');
		alertUsersChat = (config.chatUsers ?? []).join('\n');
		alertSeveridadeMin = config.severidadeMin ?? 'alto';
		alertTiposAtaque = (config.tiposAtaque ?? []) as string[];
		alertReenvioMin = config.reenvioMin ?? 15;
		chatSeveridadeMin = config.severidadeMin ?? 'alto';
		chatTiposAtaque = (config.tiposAtaque ?? []) as string[];
		chatReenvioMin = config.reenvioMin ?? 10;
		editarAlertConfigId = config._id;
		// Scroll suave até o formulário
		setTimeout(() => {
			const formSection = document.querySelector('[data-alert-form]');
			formSection?.scrollIntoView({ behavior: 'smooth', block: 'start' });
		}, 100);
	}
	const severidadesDisponiveis: SeveridadeSeguranca[] = [
		'informativo',
		'baixo',
		'moderado',
		'alto',
		'critico'
	];

	const severityLabels: Record<SeveridadeSeguranca, string> = {
		informativo: 'Informativo',
		baixo: 'Baixo',
		moderado: 'Moderado',
		alto: 'Alto',
		critico: 'Crítico'
	};

	const severityStyles: Record<SeveridadeSeguranca, string> = {
		informativo: 'badge badge-ghost',
		baixo: 'badge badge-success',
		moderado: 'badge badge-info',
		alto: 'badge badge-warning',
		critico: 'badge badge-error'
	};

	const attackLabels: Record<AtaqueCiberneticoTipo, string> = {
		phishing: 'Phishing',
		malware: 'Malware',
		ransomware: 'Ransomware',
		brute_force: 'Brute Force',
		credential_stuffing: 'Credential Stuffing',
		sql_injection: 'SQL Injection',
		xss: 'XSS',
		path_traversal: 'Path Traversal',
		command_injection: 'Command Injection',
		nosql_injection: 'NoSQL Injection',
		xxe: 'XXE',
		man_in_the_middle: 'MITM',
		ddos: 'DDoS',
		engenharia_social: 'Engenharia Social',
		cve_exploit: 'Exploração de CVE',
		apt: 'APT',
		zero_day: 'Zero-Day',
		supply_chain: 'Supply Chain',
		fileless_malware: 'Fileless Malware',
		polymorphic_malware: 'Polymorphic',
		ransomware_lateral: 'Ransomware Lateral',
		deepfake_phishing: 'Deepfake Phishing',
		adversarial_ai: 'Ataque IA',
		side_channel: 'Side-Channel',
		firmware_bootloader: 'Firmware/Bootloader',
		bec: 'BEC',
		botnet: 'Botnet',
		ot_ics: 'OT/ICS',
		quantum_attack: 'Quantum'
	};

	const statusStyles: Record<string, string> = {
		detectado: 'badge badge-outline border-info/60 text-info',
		investigando: 'badge badge-secondary',
		contido: 'badge badge-success',
		falso_positivo: 'badge badge-ghost',
		escalado: 'badge badge-error animate-pulse',
		resolvido: 'badge badge-neutral'
	};

	let filtroSeveridades = $state<SeveridadeSeguranca[]>([]); // Vazio = mostrar todos
	let filtroTipos = $state<AtaqueCiberneticoTipo[]>([]);
	let alertaSonoroAtivo = $state(true);
	let alertaVisualAtivo = $state(true);
	// Contagem de novos eventos detectados em tempo real (sem recarregar)
	let novosEventos = $state(0);
	// Timestamp do último evento observado no feed para cálculo de "novos"
	let ultimoTsVisto = $state<number>(Date.now());
	let ipManual = $state('');
	let comentarioManual = $state('');
	let porta = $state(443);
	let protocolo = $state<'tcp' | 'udp' | 'icmp' | 'quic' | 'any'>('tcp');
	let acao = $state<'permitir' | 'bloquear' | 'monitorar' | 'rate_limit'>('monitorar');
	let temporario = $state(true);
	let duracao = $state(900);
	let severidadeMin = $state<SeveridadeSeguranca>('moderado');
	let relatorioInicio = $state(new Date(Date.now() - 60 * 60 * 1000).toISOString().slice(0, 16));
	let relatorioFim = $state(new Date().toISOString().slice(0, 16));
	let incluirMetricas = $state(true);
	let incluirAcoes = $state(true);
	let feedback = $state<{ tipo: 'success' | 'error'; mensagem: string } | null>(null);
	let ultimaReferenciaCritica: Id<'securityEvents'> | null = null;
	let audioCtx: AudioContext | null = null;

	// Rate Limiting
	let mostrarRateLimitConfig = $state(false);
	let rateLimitNome = $state('');
	let rateLimitTipo = $state<'ip' | 'usuario' | 'endpoint' | 'global'>('ip');
	let rateLimitIdentificador = $state('');
	let rateLimitLimite = $state(100);
	let rateLimitJanelaSegundos = $state(60);
	let rateLimitEstrategia = $state<'fixed_window' | 'sliding_window' | 'token_bucket'>(
		'fixed_window'
	);
	let rateLimitAcaoExcedido = $state<'bloquear' | 'throttle' | 'alertar'>('bloquear');
	let rateLimitBloqueioTemporarioSegundos = $state<number | undefined>(undefined);
	let rateLimitPrioridade = $state(0);
	let rateLimitNotas = $state('');
	let rateLimitEditando = $state<Id<'rateLimitConfig'> | null>(null);

	const series = $derived.by(() => visaoCamadas?.data?.series ?? []);
	const totais = $derived.by(() => visaoCamadas?.data?.totais ?? null);
	const eventosFiltrados = $derived.by(() => {
		const lista = eventos?.data ?? [];
		return lista
			.filter((evento) => {
				if (filtroSeveridades.length && !filtroSeveridades.includes(evento.severidade)) {
					return false;
				}
				if (filtroTipos.length && !filtroTipos.includes(evento.tipoAtaque)) {
					return false;
				}
				return true;
			})
			.slice(0, 50);
	});
	const ipCriticos = $derived.by(() => (reputacoes?.data ?? []).slice(0, 10));
	const regras = $derived.by(() => regrasPorta?.data ?? []);

	const eventoCriticoAtual = $derived.by(
		() => (eventos?.data ?? []).find((evento) => evento.severidade === 'critico') ?? null
	);

	// Efeito: observar chegada de novos eventos e acionar toast/contador
	$effect(() => {
		const lista = eventos?.data ?? [];
		if (!lista.length) return;
		// conta apenas eventos com timestamp maior que o último visto
		const novos = lista.filter((e) => e.timestamp > ultimoTsVisto).length;
		if (novos > 0) {
			novosEventos += novos;
			ultimoTsVisto = Math.max(ultimoTsVisto, ...lista.map((e) => e.timestamp));
			if (alertaVisualAtivo) {
				feedback = {
					tipo: 'success',
					mensagem: `🔔 ${novos} novo(s) evento(s) de segurança detectado(s)`
				};
			}
		}
	});

	// Dados para gráfico “Realtime por tipo” (últimos 60 min em buckets de 5 min)
	const janelaMs = 60 * 60 * 1000;
	const bucketMs = 5 * 60 * 1000;
	const coresTipo: Record<string, string> = {
		ddos: 'rgba(248,113,113,0.9)',
		sql_injection: 'rgba(59,130,246,0.9)',
		xss: 'rgba(234,179,8,0.9)',
		brute_force: 'rgba(99,102,241,0.9)',
		path_traversal: 'rgba(34,197,94,0.9)',
		command_injection: 'rgba(236,72,153,0.9)',
		nosql_injection: 'rgba(20,184,166,0.9)'
	};
	const tiposParaChart = Object.keys(coresTipo);
	const timelineBuckets = $derived.by(() => {
		const agora = Date.now();
		const inicio = agora - janelaMs;
		const lista = (eventos?.data ?? []).filter((e) => e.timestamp >= inicio);
		const numBuckets = Math.floor(janelaMs / bucketMs);
		const buckets: Array<{
			inicio: number;
			fim: number;
			counts: Record<string, number>;
			topDestinos: Record<string, number>;
		}> = [];
		for (let i = 0; i < numBuckets; i++) {
			const bIni = inicio + i * bucketMs;
			const bFim = bIni + bucketMs;
			const counts: Record<string, number> = {};
			const topDestinos: Record<string, number> = {};
			for (const tipo of tiposParaChart) counts[tipo] = 0;
			for (const ev of lista) {
				if (ev.timestamp >= bIni && ev.timestamp < bFim) {
					const t = ev.tipoAtaque as string;
					if (t in counts) counts[t] += 1;
					const key = `${ev.destinoIp ?? 'app'}|${ev.protocolo ?? 'http'}`;
					topDestinos[key] = (topDestinos[key] ?? 0) + 1;
				}
			}
			buckets.push({ inicio: bIni, fim: bFim, counts, topDestinos });
		}
		return buckets;
	});
	// const maxBucketTotal = $derived.by(() =>
	// 	Math.max(1, ...timelineBuckets.map((b) => Object.values(b.counts).reduce((a, n) => a + n, 0)))
	// );

	function maxSeriesValue(dataset: Array<Array<number>>): number {
		let max = 1;
		for (const serie of dataset) {
			for (const valor of serie) {
				if (valor > max) max = valor;
			}
		}
		return max;
	}

	function construirLayer(
		valores: number[],
		largura: number,
		altura: number,
		maxValor: number
	): string {
		if (!valores.length) {
			return '';
		}
		const passo = valores.length > 1 ? largura / (valores.length - 1) : largura;
		const pontos = valores.map((valor, indice) => {
			const x = indice * passo;
			const proporcao = maxValor === 0 ? 0 : valor / maxValor;
			const y = altura - proporcao * altura;
			return `${x},${Number.isFinite(y) ? y : altura}`;
		});
		return `M0,${altura} ${pontos.map((ponto) => `L${ponto}`).join(' ')} L${largura},${altura} Z`;
	}

	const chartPaths = $derived.by(() => {
		if (!series.length) {
			return { ddos: '', sql: '', avancados: '' };
		}
		const largura = 880;
		const altura = 220;
		const ddos = series.map((bucket) => bucket.ddos);
		const sql = series.map((bucket) => bucket.sqlInjection);
		const avancados = series.map((bucket) => bucket.avancados);
		const maxValor = maxSeriesValue([ddos, sql, avancados]);
		return {
			ddos: construirLayer(ddos, largura, altura, maxValor),
			sql: construirLayer(sql, largura, altura, maxValor),
			avancados: construirLayer(avancados, largura, altura, maxValor)
		};
	});

	function toggleFiltroSeveridade(item: SeveridadeSeguranca) {
		if (filtroSeveridades.includes(item)) {
			filtroSeveridades = filtroSeveridades.filter((valor) => valor !== item);
		} else {
			filtroSeveridades = [...filtroSeveridades, item];
		}
	}

	function toggleFiltroTipo(item: AtaqueCiberneticoTipo) {
		if (filtroTipos.includes(item)) {
			filtroTipos = filtroTipos.filter((valor) => valor !== item);
		} else {
			filtroTipos = [...filtroTipos, item];
		}
	}

	$effect(() => {
		if (!eventoCriticoAtual || !alertaSonoroAtivo) {
			return;
		}
		if (ultimaReferenciaCritica === eventoCriticoAtual._id) {
			return;
		}
		ultimaReferenciaCritica = eventoCriticoAtual._id;
		if (!browser) {
			return;
		}
		if (!audioCtx) {
			audioCtx = new AudioContext();
		}
		const oscillator = audioCtx.createOscillator();
		const gain = audioCtx.createGain();
		oscillator.type = 'triangle';
		oscillator.frequency.value = 880;
		gain.gain.value = 0.08;
		oscillator.connect(gain).connect(audioCtx.destination);
		oscillator.start();
		setTimeout(() => {
			oscillator.stop();
		}, 300);
	});

	function mensagemErro(erro: unknown): string {
		if (erro instanceof Error) return erro.message;
		return 'Operação não concluída.';
	}

	function obterUsuarioId(): Id<'usuarios'> {
		// Prioridade: usar query do Convex (mais confiável) > authStore
		// Se a query retornou dados, usar o ID do Convex
		if (meuPerfil?.data?._id) {
			return meuPerfil.data._id;
		}
		// Se a query ainda está carregando (undefined) ou retornou null, tentar authStore
		if (authStore.autenticado && authStore.usuario?._id) {
			return authStore.usuario._id as Id<'usuarios'>;
		}
		// Se nenhum dos dois funcionou, lançar erro
		throw new Error('Usuário não autenticado. Por favor, faça login no sistema.');
	}

	async function aplicarMedidaIp(
		acaoSelecionada: 'forcar_blacklist' | 'remover_blacklist',
		ipAlvo: string,
		eventoId?: Id<'securityEvents'>
	) {
		if (!ipAlvo) {
			feedback = { tipo: 'error', mensagem: 'Informe o IP alvo.' };
			return;
		}
		try {
			await client.mutation(api.security.atualizarReputacaoIndicador, {
				usuarioId: obterUsuarioId(),
				indicador: ipAlvo,
				categoria: 'ip',
				acao: acaoSelecionada,
				delta: acaoSelecionada === 'forcar_blacklist' ? -30 : 10,
				comentario: comentarioManual || `Ação manual em ${new Date().toLocaleString()}`,
				duracaoSegundos: acaoSelecionada === 'forcar_blacklist' ? 3600 : undefined
			});

			if (eventoId) {
				await client.mutation(api.security.registrarAcaoIncidente, {
					eventoId,
					tipo: acaoSelecionada === 'forcar_blacklist' ? 'block_ip' : 'unblock_ip',
					origem: 'manual',
					executadoPor: obterUsuarioId(),
					detalhes: comentarioManual || 'Ação executada via Wizcard',
					resultado: 'registrado',
					relacionadoA: undefined
				});
			}

			feedback = {
				tipo: 'success',
				mensagem:
					acaoSelecionada === 'forcar_blacklist'
						? `IP ${ipAlvo} bloqueado e registrado na blacklist.`
						: `IP ${ipAlvo} liberado e removido da blacklist.`
			};
			ipManual = '';
			comentarioManual = '';
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}

	async function salvarRegraPorta(e: SubmitEvent) {
		e.preventDefault();
		try {
			await client.mutation(api.security.configurarRegraPorta, {
				usuarioId: obterUsuarioId(),
				porta,
				protocolo,
				acao,
				temporario,
				duracaoSegundos: temporario ? duracao : undefined,
				severidadeMin,
				notas: `Regra criada via Wizcard em ${new Date().toLocaleString()}`,
				tags: ['cibersecurity', acao],
				listaReferencia: undefined
			});
			feedback = {
				tipo: 'success',
				mensagem: `Regra para porta ${porta}/${protocolo.toUpperCase()} registrada.`
			};
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}

	function parseDatetime(valor: string): number {
		if (!valor) return Date.now();
		const data = new Date(valor);
		return Number.isNaN(data.getTime()) ? Date.now() : data.getTime();
	}
	// Gerar PDF do relatório com detalhes completos
	async function imprimirRelatorio(r: {
		_id: Id<'reportRequests'>;
		status: 'pendente' | 'processando' | 'concluido' | 'falhou';
		criadoEm: number;
		concluidoEm?: number;
		observacoes?: string;
	}) {
		if (typeof window === 'undefined') return;

		try {
			// Buscar eventos de segurança para incluir detalhes
			const eventosDetalhados = await client.query(api.security.listarEventosSeguranca, {
				limit: 500
			});

			// Buscar IPs bloqueados
			const ipsBloqueados = await client.query(api.security.listarReputacoes, {
				limit: 100,
				lista: 'blacklist'
			});

			const doc = new jsPDF();
			let yPosition = 20;

			// Cabeçalho
			doc.setFontSize(20);
			doc.setFont('helvetica', 'bold');
			doc.text('Relatório de Segurança Detalhado', 105, yPosition, { align: 'center' });
			yPosition += 10;

			// Informações do relatório
			doc.setFontSize(10);
			doc.setFont('helvetica', 'normal');
			const criadoStr = new Date(r.criadoEm).toLocaleString('pt-BR', { hour12: false });
			const concluidoStr = r.concluidoEm
				? new Date(r.concluidoEm).toLocaleString('pt-BR', { hour12: false })
				: '—';
			const agoraStr = new Date().toLocaleString('pt-BR', { hour12: false });

			doc.setFontSize(9);
			doc.setTextColor(100, 100, 100);
			doc.text(`Status: ${r.status}`, 20, yPosition);
			doc.text(`Criado: ${criadoStr}`, 105, yPosition, { align: 'center' });
			doc.text(`Concluído: ${concluidoStr}`, 190, yPosition, { align: 'right' });
			yPosition += 10;

			// Parse dos dados
			type RelatorioData = {
				total?: number | string;
				porSeveridade?: Record<string, number>;
				porAtaque?: Record<string, number>;
				incluiuIndicadores?: boolean;
				incluiuMetricas?: boolean;
				incluiuAcoes?: boolean;
			};
			let data: RelatorioData | null = null;
			try {
				data = r.observacoes ? (JSON.parse(r.observacoes) as RelatorioData) : null;
			} catch {
				// Se não conseguir parsear, exibe como texto simples
				doc.setFontSize(12);
				doc.setTextColor(0, 0, 0);
				doc.text('Conteúdo do Relatório:', 20, yPosition);
				yPosition += 8;
				doc.setFontSize(9);
				const lines = doc.splitTextToSize(r.observacoes ?? 'Sem observações', 170);
				doc.text(lines, 20, yPosition);
				doc.save(`Relatorio_Seguranca_${new Date().getTime()}.pdf`);
				return;
			}

			// Resumo Executivo
			doc.setFontSize(14);
			doc.setTextColor(0, 0, 0);
			doc.setFont('helvetica', 'bold');
			doc.text('Resumo Executivo', 20, yPosition);
			yPosition += 10;

			doc.setFontSize(10);
			doc.setFont('helvetica', 'normal');
			const total = data?.total ?? '—';
			doc.text(`Total de eventos no período: ${total}`, 20, yPosition);
			yPosition += 7;
			doc.text(`IPs bloqueados: ${ipsBloqueados?.length ?? 0}`, 20, yPosition);
			yPosition += 7;
			doc.text(`Eventos detalhados analisados: ${eventosDetalhados?.length ?? 0}`, 20, yPosition);
			yPosition += 12;

			// Tabela por Severidade
			const porSeveridade = data?.porSeveridade ?? {};
			const dadosSeveridade = Object.entries(porSeveridade).map(([k, v]) => [
				k.charAt(0).toUpperCase() + k.slice(1),
				String(v as number)
			]);

			if (dadosSeveridade.length > 0) {
				doc.setFontSize(12);
				doc.setFont('helvetica', 'bold');
				doc.text('Distribuição por Severidade', 20, yPosition);
				yPosition += 8;

				autoTable(doc, {
					startY: yPosition,
					head: [['Severidade', 'Quantidade', '% do Total']],
					body: dadosSeveridade.map(([sev, qtd]) => {
						const totalNum = typeof total === 'number' ? total : parseInt(String(total)) || 1;
						const percentual = ((parseInt(String(qtd)) / totalNum) * 100).toFixed(1);
						return [sev, String(qtd), `${percentual}%`];
					}),
					theme: 'grid',
					headStyles: { fillColor: [41, 128, 185], fontStyle: 'bold', textColor: [255, 255, 255] },
					styles: { fontSize: 9 },
					margin: { left: 20, right: 20 }
				});
				// eslint-disable-next-line @typescript-eslint/no-explicit-any
				yPosition = (doc as any).lastAutoTable.finalY + 10;
			}

			// Nova página se necessário
			if (yPosition > 250) {
				doc.addPage();
				yPosition = 20;
			}

			// Tabela por Tipo de Ataque
			const porAtaque = data?.porAtaque ?? {};
			const dadosAtaque = Object.entries(porAtaque)
				.sort(([, a], [, b]) => (b as number) - (a as number))
				.map(([k, v]) => [k, String(v as number)]);

			if (dadosAtaque.length > 0) {
				doc.setFontSize(12);
				doc.setFont('helvetica', 'bold');
				doc.text('Distribuição por Tipo de Ataque', 20, yPosition);
				yPosition += 8;

				const totalNum = typeof total === 'number' ? total : parseInt(String(total)) || 1;
				autoTable(doc, {
					startY: yPosition,
					head: [['Tipo de Ataque', 'Quantidade', '% do Total']],
					body: dadosAtaque.map(([tipo, qtd]) => {
						const percentual = ((parseInt(String(qtd)) / totalNum) * 100).toFixed(1);
						return [tipo, String(qtd), `${percentual}%`];
					}),
					theme: 'grid',
					headStyles: { fillColor: [192, 57, 43], fontStyle: 'bold', textColor: [255, 255, 255] },
					styles: { fontSize: 9 },
					margin: { left: 20, right: 20 }
				});
				// eslint-disable-next-line @typescript-eslint/no-explicit-any
				yPosition = (doc as any).lastAutoTable.finalY + 10;
			}

			// Nova página se necessário
			if (yPosition > 240) {
				doc.addPage();
				yPosition = 20;
			}

			// IPs Bloqueados
			if (ipsBloqueados && ipsBloqueados.length > 0) {
				doc.setFontSize(12);
				doc.setFont('helvetica', 'bold');
				doc.text('IPs Bloqueados (Blacklist)', 20, yPosition);
				yPosition += 8;

				const ipsData = ipsBloqueados
					.slice(0, 50)
					.map((ip) => [
						ip.indicador ?? 'N/A',
						String(ip.reputacao ?? 'N/A'),
						ip.ultimoRegistro
							? new Date(ip.ultimoRegistro).toLocaleString('pt-BR', { hour12: false })
							: 'N/A'
					]);

				autoTable(doc, {
					startY: yPosition,
					head: [['Endereço IP', 'Reputação', 'Última Atualização']],
					body: ipsData,
					theme: 'grid',
					headStyles: { fillColor: [142, 68, 173], fontStyle: 'bold', textColor: [255, 255, 255] },
					styles: { fontSize: 8 },
					margin: { left: 20, right: 20 }
				});
				// eslint-disable-next-line @typescript-eslint/no-explicit-any
				yPosition = (doc as any).lastAutoTable.finalY + 10;
			}

			// Nova página se necessário
			if (yPosition > 240) {
				doc.addPage();
				yPosition = 20;
			}

			// Eventos Detalhados
			if (eventosDetalhados && eventosDetalhados.length > 0) {
				doc.setFontSize(12);
				doc.setFont('helvetica', 'bold');
				doc.text('Eventos de Segurança Detalhados', 20, yPosition);
				yPosition += 8;

				// Limitar a 100 eventos mais recentes para não sobrecarregar o PDF
				const eventosOrdenados = eventosDetalhados
					.sort((a, b) => b.timestamp - a.timestamp)
					.slice(0, 100);

				const eventosData = eventosOrdenados.map((evento) => [
					new Date(evento.timestamp).toLocaleString('pt-BR', { hour12: false }),
					evento.tipoAtaque,
					evento.severidade,
					evento.status,
					evento.origemIp ?? 'N/A',
					evento.destinoIp ?? 'N/A',
					evento.destinoPorta ? String(evento.destinoPorta) : 'N/A',
					evento.protocolo ?? 'N/A',
					evento.descricao.length > 50
						? evento.descricao.substring(0, 47) + '...'
						: evento.descricao
				]);

				autoTable(doc, {
					startY: yPosition,
					head: [
						[
							'Data/Hora',
							'Tipo',
							'Severidade',
							'Status',
							'IP Origem',
							'IP Destino',
							'Porta',
							'Protocolo',
							'Descrição'
						]
					],
					body: eventosData,
					theme: 'grid',
					headStyles: {
						fillColor: [39, 174, 96],
						fontStyle: 'bold',
						textColor: [255, 255, 255],
						fontSize: 7
					},
					styles: { fontSize: 7, cellPadding: 2 },
					margin: { left: 10, right: 10 },
					columnStyles: {
						0: { cellWidth: 30 },
						1: { cellWidth: 25 },
						2: { cellWidth: 20 },
						3: { cellWidth: 20 },
						4: { cellWidth: 25 },
						5: { cellWidth: 25 },
						6: { cellWidth: 15 },
						7: { cellWidth: 15 },
						8: { cellWidth: 40 }
					}
				});
				// eslint-disable-next-line @typescript-eslint/no-explicit-any
				yPosition = (doc as any).lastAutoTable.finalY + 10;

				if (eventosDetalhados.length > 100) {
					doc.setFontSize(8);
					doc.setTextColor(100, 100, 100);
					doc.text(
						`Nota: Exibindo apenas os 100 eventos mais recentes de um total de ${eventosDetalhados.length} eventos.`,
						20,
						yPosition
					);
					yPosition += 8;
				}
			}

			// Nova página se necessário
			if (yPosition > 240) {
				doc.addPage();
				yPosition = 20;
			}

			// Estatísticas Adicionais
			if (eventosDetalhados && eventosDetalhados.length > 0) {
				doc.setFontSize(12);
				doc.setFont('helvetica', 'bold');
				doc.text('Estatísticas Adicionais', 20, yPosition);
				yPosition += 10;

				// IPs únicos
				const ipsUnicos = new Set(
					eventosDetalhados.filter((e) => e.origemIp).map((e) => e.origemIp)
				).size;
				const portasUnicas = new Set(
					eventosDetalhados.filter((e) => e.destinoPorta).map((e) => e.destinoPorta)
				).size;
				const protocolosUnicos = new Set(
					eventosDetalhados.filter((e) => e.protocolo).map((e) => e.protocolo)
				).size;

				// Status dos eventos
				const porStatus = eventosDetalhados.reduce(
					(acc, evento) => {
						acc[evento.status] = (acc[evento.status] || 0) + 1;
						return acc;
					},
					{} as Record<string, number>
				);

				doc.setFontSize(10);
				doc.setFont('helvetica', 'normal');
				doc.text(`IPs únicos envolvidos: ${ipsUnicos}`, 20, yPosition);
				yPosition += 7;
				doc.text(`Portas únicas alvo: ${portasUnicas}`, 20, yPosition);
				yPosition += 7;
				doc.text(`Protocolos diferentes: ${protocolosUnicos}`, 20, yPosition);
				yPosition += 10;

				// Tabela de status
				if (Object.keys(porStatus).length > 0) {
					doc.setFontSize(11);
					doc.setFont('helvetica', 'bold');
					doc.text('Distribuição por Status', 20, yPosition);
					yPosition += 8;

					const statusData = Object.entries(porStatus).map(([status, qtd]) => [
						status,
						String(qtd)
					]);

					autoTable(doc, {
						startY: yPosition,
						head: [['Status', 'Quantidade']],
						body: statusData,
						theme: 'grid',
						headStyles: { fillColor: [52, 73, 94], fontStyle: 'bold', textColor: [255, 255, 255] },
						styles: { fontSize: 9 },
						margin: { left: 20, right: 20 }
					});
					// eslint-disable-next-line @typescript-eslint/no-explicit-any
					yPosition = (doc as any).lastAutoTable.finalY + 10;
				}
			}

			// Rodapé em todas as páginas
			// eslint-disable-next-line @typescript-eslint/no-explicit-any
			const pageCount = (doc as any).internal.getNumberOfPages();
			for (let i = 1; i <= pageCount; i++) {
				doc.setPage(i);
				doc.setFontSize(8);
				doc.setFont('helvetica', 'normal');
				doc.setTextColor(128, 128, 128);
				doc.text('SGSE - Sistema de Gerenciamento de Secretaria', 105, 285, {
					align: 'center'
				});
				doc.text(`Gerado em: ${agoraStr}`, 105, 290, { align: 'center' });
				doc.text(`Página ${i} de ${pageCount}`, 195, 290, { align: 'right' });
			}

			// Salvar PDF
			const nomeArquivo = `Relatorio_Seguranca_Detalhado_${new Date(r.criadoEm).toISOString().split('T')[0]}_${new Date().getTime()}.pdf`;
			doc.save(nomeArquivo);
		} catch (error) {
			console.error('Erro ao gerar PDF:', error);
			alert('Erro ao gerar PDF do relatório. Tente novamente.');
		}
	}
	async function excluirRelatorio(relatorioId: Id<'reportRequests'>) {
		if (!confirm('Excluir este relatório? Esta ação não pode ser desfeita.')) return;
		try {
			const resp = await client.mutation(api.security.deletarRelatorio, { relatorioId });
			if (resp?.success) {
				feedback = { tipo: 'success', mensagem: 'Relatório excluído.' };
			} else {
				feedback = { tipo: 'error', mensagem: 'Não foi possível excluir o relatório.' };
			}
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}

	async function gerarRelatorioAvancado(e: SubmitEvent) {
		e.preventDefault();
		try {
			await client.mutation(api.security.solicitarRelatorioSeguranca, {
				solicitanteId: obterUsuarioId(),
				filtros: {
					dataInicio: parseDatetime(relatorioInicio),
					dataFim: parseDatetime(relatorioFim),
					severidades: filtroSeveridades.length ? filtroSeveridades : undefined,
					tiposAtaque: filtroTipos.length ? filtroTipos : undefined,
					incluirIndicadores: true,
					incluirMetricas,
					incluirAcoes
				}
			});
			feedback = {
				tipo: 'success',
				mensagem: 'Relatório refinado em processamento. Você será notificado em instantes.'
			};
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}

	function resetarFormRateLimit() {
		rateLimitNome = '';
		rateLimitTipo = 'ip';
		rateLimitIdentificador = '';
		rateLimitLimite = 100;
		rateLimitJanelaSegundos = 60;
		rateLimitEstrategia = 'fixed_window';
		rateLimitAcaoExcedido = 'bloquear';
		rateLimitBloqueioTemporarioSegundos = undefined;
		rateLimitPrioridade = 0;
		rateLimitNotas = '';
		rateLimitEditando = null;
	}

	function editarConfigRateLimit(configId: Id<'rateLimitConfig'>) {
		const config = configsRateLimit?.data?.find((c) => c._id === configId);
		if (!config) return;

		rateLimitNome = config.nome;
		rateLimitTipo = config.tipo;
		rateLimitIdentificador = config.identificador ?? '';
		rateLimitLimite = config.limite;
		rateLimitJanelaSegundos = config.janelaSegundos;
		rateLimitEstrategia = config.estrategia;
		rateLimitAcaoExcedido = config.acaoExcedido;
		rateLimitBloqueioTemporarioSegundos = config.bloqueioTemporarioSegundos;
		rateLimitPrioridade = config.prioridade;
		rateLimitNotas = config.notas ?? '';
		rateLimitEditando = configId;
		mostrarRateLimitConfig = true;
	}

	async function salvarConfigRateLimit(e: SubmitEvent) {
		e.preventDefault();
		try {
			if (rateLimitEditando) {
				await client.mutation(api.security.atualizarConfigRateLimit, {
					configId: rateLimitEditando,
					usuarioId: obterUsuarioId(),
					nome: rateLimitNome,
					limite: rateLimitLimite,
					janelaSegundos: rateLimitJanelaSegundos,
					estrategia: rateLimitEstrategia,
					acaoExcedido: rateLimitAcaoExcedido,
					bloqueioTemporarioSegundos: rateLimitBloqueioTemporarioSegundos,
					prioridade: rateLimitPrioridade,
					notas: rateLimitNotas || undefined
				});
				feedback = {
					tipo: 'success',
					mensagem: 'Configuração de rate limit atualizada com sucesso.'
				};
			} else {
				await client.mutation(api.security.criarConfigRateLimit, {
					usuarioId: obterUsuarioId(),
					nome: rateLimitNome,
					tipo: rateLimitTipo,
					identificador:
						rateLimitTipo === 'global' ? undefined : rateLimitIdentificador || undefined,
					limite: rateLimitLimite,
					janelaSegundos: rateLimitJanelaSegundos,
					estrategia: rateLimitEstrategia,
					acaoExcedido: rateLimitAcaoExcedido,
					bloqueioTemporarioSegundos: rateLimitBloqueioTemporarioSegundos,
					prioridade: rateLimitPrioridade,
					notas: rateLimitNotas || undefined
				});
				feedback = { tipo: 'success', mensagem: 'Configuração de rate limit criada com sucesso.' };
			}
			resetarFormRateLimit();
			mostrarRateLimitConfig = false;
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}

	async function deletarConfigRateLimit(configId: Id<'rateLimitConfig'>) {
		if (!confirm('Tem certeza que deseja deletar esta configuração de rate limit?')) return;
		try {
			await client.mutation(api.security.deletarConfigRateLimit, {
				configId,
				usuarioId: obterUsuarioId()
			});
			feedback = { tipo: 'success', mensagem: 'Configuração de rate limit deletada com sucesso.' };
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}

	async function toggleAtivoRateLimit(configId: Id<'rateLimitConfig'>, ativo: boolean) {
		try {
			await client.mutation(api.security.atualizarConfigRateLimit, {
				configId,
				usuarioId: obterUsuarioId(),
				ativo: !ativo
			});
			feedback = {
				tipo: 'success',
				mensagem: `Configuração ${!ativo ? 'ativada' : 'desativada'} com sucesso.`
			};
		} catch (erro: unknown) {
			feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
		}
	}

	function classeEventoCritico(severidade: SeveridadeSeguranca): string {
		if (!alertaVisualAtivo) return '';
		return severidade === 'critico' ? 'ring-2 ring-error animate-pulse' : '';
	}

	function formatarData(timestamp: number): string {
		const data = new Date(timestamp);
		return data.toLocaleString('pt-BR', {
			hour12: false
		});
	}
</script>

<div class="space-y-6">
	{#if feedback}
		<div class="alert shadow-lg {feedback.tipo === 'success' ? 'alert-success' : 'alert-error'}">
			<div>
				<span>{feedback.mensagem}</span>
			</div>
			<button type="button" class="btn btn-sm btn-ghost" onclick={() => (feedback = null)}
				>Fechar</button
			>
		</div>
	{/if}

	<section class="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
		<div class="stat bg-base-100 border-primary/20 rounded-2xl border shadow-xl">
			<div class="stat-title text-primary font-semibold">Eventos monitorados</div>
			<div class="stat-value text-primary text-4xl">{totais?.eventos ?? 0}</div>
			<div class="stat-desc">Últimas 6h</div>
		</div>
		<div class="stat bg-base-100 border-error/20 rounded-2xl border shadow-xl">
			<div class="stat-title text-error font-semibold">Críticos</div>
			<div class="stat-value text-error text-4xl">{totais?.criticos ?? 0}</div>
			<div class="stat-desc">Escalonados imediatamente</div>
		</div>
		<div class="stat bg-base-100 border-warning/20 rounded-2xl border shadow-xl">
			<div class="stat-title text-warning font-semibold">Bloqueios ativos</div>
			<div class="stat-value text-warning text-4xl">{totais?.bloqueiosAtivos ?? 0}</div>
			<div class="stat-desc">IPs e domínios isolados</div>
		</div>
		<div class="stat bg-base-100 border-success/20 rounded-2xl border shadow-xl">
			<div class="stat-title text-success font-semibold">Sensores ativos</div>
			<div class="stat-value text-success text-4xl">{totais?.sensoresAtivos ?? 0}</div>
			<div class="stat-desc">Edge, OT e honeypots</div>
		</div>
	</section>

	<!-- (Seção Alertas e Notificações movida para depois de Rate Limiting Avançado) -->
	<section class="grid gap-6 lg:grid-cols-3">
		<div class="border-primary/20 bg-base-100/80 rounded-3xl border p-6 shadow-2xl lg:col-span-2">
			<div class="flex flex-wrap items-center justify-between gap-3">
				<div>
					<h2 class="text-primary text-2xl font-bold">Threat Matrix</h2>
					<p class="text-base-content/70 text-sm">
						Correlação temporal entre DDoS, SQLi, ataques avançados e bloqueios automáticos.
					</p>
				</div>
				{#if health?.data}
					<div class="badge badge-outline">
						<span class="mr-2 h-2 w-2 rounded-full {health.data.ok ? 'bg-success' : 'bg-error'}"
						></span>
						{health.data.ok ? 'Saúde OK' : 'Instável'} · Pendentes: {health.data.pendingReports}
					</div>
				{/if}
				<div class="flex gap-2">
					<label class="label cursor-pointer gap-2">
						<span class="label-text">Alerta Sonoro</span>
						<input type="checkbox" class="toggle toggle-primary" bind:checked={alertaSonoroAtivo} />
					</label>
					<label class="label cursor-pointer gap-2">
						<span class="label-text">Flash Visual</span>
						<input
							type="checkbox"
							class="toggle toggle-secondary"
							bind:checked={alertaVisualAtivo}
						/>
					</label>
				</div>
			</div>

			<div class="bg-base-200/40 mt-4 overflow-x-auto rounded-2xl p-4">
				<svg viewBox="0 0 880 220" class="w-full">
					<defs>
						<linearGradient id="grad-ddos" x1="0%" y1="0%" x2="0%" y2="100%">
							<stop offset="0%" stop-color="rgba(255, 76, 76, 0.8)" />
							<stop offset="100%" stop-color="rgba(255, 76, 76, 0.1)" />
						</linearGradient>
						<linearGradient id="grad-sql" x1="0%" y1="0%" x2="0%" y2="100%">
							<stop offset="0%" stop-color="rgba(59, 130, 246, 0.8)" />
							<stop offset="100%" stop-color="rgba(59, 130, 246, 0.1)" />
						</linearGradient>
						<linearGradient id="grad-adv" x1="0%" y1="0%" x2="0%" y2="100%">
							<stop offset="0%" stop-color="rgba(236, 72, 153, 0.8)" />
							<stop offset="100%" stop-color="rgba(236, 72, 153, 0.1)" />
						</linearGradient>
					</defs>
					<path
						d={chartPaths.avancados}
						fill="url(#grad-adv)"
						stroke="rgba(236, 72, 153, 0.6)"
						stroke-width="2"
					/>
					<path
						d={chartPaths.sql}
						fill="url(#grad-sql)"
						stroke="rgba(59, 130, 246, 0.6)"
						stroke-width="2"
					/>
					<path
						d={chartPaths.ddos}
						fill="url(#grad-ddos)"
						stroke="rgba(248, 113, 113, 0.8)"
						stroke-width="2"
					/>
				</svg>
				<div class="mt-4 flex flex-wrap gap-3 text-sm font-semibold">
					<span class="badge badge-error gap-2">
						<span class="bg-error h-2 w-2 rounded-full"></span>DDoS
					</span>
					<span class="badge badge-info gap-2">
						<span class="bg-info h-2 w-2 rounded-full"></span>SQL Injection
					</span>
					<span class="badge badge-secondary gap-2">
						<span class="bg-secondary h-2 w-2 rounded-full"></span>ATA Advanced
					</span>
				</div>
			</div>

			<!-- Novo gráfico: Realtime por Tipo (últimos 60min, buckets 5min) -->
			<div class="bg-base-200/40 mt-6 rounded-2xl p-4">
				<h3 class="text-base-content text-lg font-semibold">Realtime por tipo (60 min)</h3>
				<div class="mt-3 grid grid-cols-12 gap-2">
					{#each timelineBuckets as b (b.inicio)}
						<div class="col-span-1">
							<div class="bg-base-300 h-24 w-full overflow-hidden rounded">
								{#each tiposParaChart as t (t)}
									{#if b.counts[t] > 0}
										<div
											class="w-full"
											style={`height:${
												(b.counts[t] /
													Math.max(
														1,
														Object.values(b.counts).reduce((a, n) => a + n, 0)
													)) *
												100
											}%; background:${coresTipo[t]}`}
											title={`${t}: ${b.counts[t]}`}
										></div>
									{/if}
								{/each}
							</div>
							<div class="mt-1 text-center text-[10px] leading-tight">
								{new Date(b.inicio).toLocaleTimeString('pt-BR', {
									hour12: false,
									hour: '2-digit',
									minute: '2-digit'
								})}
							</div>
						</div>
					{/each}
				</div>
				<div class="mt-3 flex flex-wrap gap-2 text-xs">
					{#each tiposParaChart as t (t)}
						<span class="badge" style={`background:${coresTipo[t]}`}>{t.replace('_', ' ')}</span>
					{/each}
				</div>
				<!-- Top destinos (IP/protocolo) no período -->
				<div class="mt-4">
					<h4 class="text-sm font-semibold">Top destinos (IP · protocolo)</h4>
					<table class="table-zebra mt-2 table w-full text-xs">
						<thead>
							<tr>
								<th>Destino</th>
								<th>Protocolo</th>
								<th>Ocorrências</th>
							</tr>
						</thead>
						<tbody>
							{#each [...new Map(timelineBuckets
										.map((b) => Object.entries(b.topDestinos))
										.flat()
										.reduce((acc, [k, v]) => acc.set(k, (acc.get(k) ?? 0) + (v as number)), new Map()))].slice(0, 8) as item (item[0])}
								{@const partes = item[0].split('|')}
								<tr>
									<td>{partes[0]}</td>
									<td>{partes[1]}</td>
									<td>{item[1] as number}</td>
								</tr>
							{/each}
						</tbody>
					</table>
				</div>
			</div>

			<div class="mt-6 flex flex-wrap gap-2">
				{#each severidadesDisponiveis as severidade (severidade)}
					<button
						type="button"
						class={`btn btn-xs ${filtroSeveridades.includes(severidade) ? 'btn-primary' : 'btn-outline btn-primary'}`}
						onclick={() => toggleFiltroSeveridade(severidade)}
					>
						{severityLabels[severidade]}
					</button>
				{/each}
			</div>
		</div>

		<div class="border-secondary/20 bg-base-100/80 rounded-3xl border p-6 shadow-2xl">
			<h3 class="text-secondary text-xl font-bold">Ações rápidas</h3>
			<form
				class="mt-4 space-y-3"
				onsubmit={(event) => {
					event.preventDefault();
					aplicarMedidaIp('forcar_blacklist', ipManual);
				}}
			>
				<label class="form-control w-full">
					<div class="label">
						<span class="label-text">IP / Host</span>
					</div>
					<input
						type="text"
						class="input input-bordered w-full"
						placeholder="Ex: 177.24.10.90"
						bind:value={ipManual}
					/>
				</label>
				<label class="form-control w-full">
					<div class="label">
						<span class="label-text">Comentário técnico</span>
					</div>
					<textarea
						class="textarea textarea-bordered w-full"
						rows="2"
						placeholder="Ex: Bloqueio após heurística MITM no JA3."
						bind:value={comentarioManual}
					></textarea>
				</label>
				<div class="flex gap-2">
					<button type="submit" class="btn btn-error flex-1">Bloquear IP</button>
					<button
						type="button"
						class="btn btn-success flex-1"
						onclick={() => aplicarMedidaIp('remover_blacklist', ipManual)}
					>
						Liberar
					</button>
				</div>
			</form>

			<div class="divider my-6">Regras de Porta</div>
			<form class="space-y-3" onsubmit={salvarRegraPorta}>
				<div class="grid grid-cols-2 gap-2">
					<label class="form-control">
						<div class="label">
							<span class="label-text">Porta</span>
						</div>
						<input
							type="number"
							class="input input-bordered"
							min="1"
							max="65535"
							bind:value={porta}
						/>
					</label>
					<label class="form-control">
						<div class="label">
							<span class="label-text">Protocolo</span>
						</div>
						<select class="select select-bordered" bind:value={protocolo}>
							<option value="tcp">TCP</option>
							<option value="udp">UDP</option>
							<option value="icmp">ICMP</option>
							<option value="quic">QUIC</option>
							<option value="any">ANY</option>
						</select>
					</label>
				</div>
				<label class="form-control">
					<div class="label">
						<span class="label-text">Ação</span>
					</div>
					<select class="select select-bordered" bind:value={acao}>
						<option value="permitir">Permitir</option>
						<option value="bloquear">Bloquear</option>
						<option value="monitorar">Monitorar</option>
						<option value="rate_limit">Rate Limit</option>
					</select>
				</label>
				<div class="flex items-center gap-2">
					<input type="checkbox" class="toggle toggle-info" bind:checked={temporario} />
					<span class="label-text">Bloqueio temporário?</span>
					{#if temporario}
						<input
							type="number"
							class="input input-bordered ml-auto w-32"
							min="60"
							step="60"
							placeholder="Segundos"
							bind:value={duracao}
						/>
					{/if}
				</div>
				<label class="form-control">
					<div class="label">
						<span class="label-text">Severidade mínima</span>
					</div>
					<select class="select select-bordered" bind:value={severidadeMin}>
						{#each severidadesDisponiveis as severidade (severidade)}
							<option value={severidade}>{severityLabels[severidade]}</option>
						{/each}
					</select>
				</label>
				<button type="submit" class="btn btn-secondary w-full">Salvar Regra</button>
			</form>
		</div>
	</section>

	<section class="grid gap-6 lg:grid-cols-3">
		<div class="border-base-300 bg-base-100 rounded-3xl border p-6 shadow-2xl lg:col-span-2">
			<div class="flex flex-wrap items-center justify-between gap-3">
				<h3 class="text-base-content text-2xl font-semibold">Feed de eventos e ameaças</h3>
				<div class="flex flex-wrap gap-2">
					{#if novosEventos > 0}
						<button
							type="button"
							class="btn btn-xs btn-primary"
							title="Novos eventos detectados"
							onclick={() => (novosEventos = 0)}
						>
							🔔 Novos: <span class="ml-1 font-bold">{novosEventos}</span>
						</button>
					{/if}
					<button
						type="button"
						class="btn btn-xs btn-warning"
						onclick={async () => {
							try {
								const resultado = await client.mutation(api.security.criarEventosTeste, {
									quantidade: 10
								});
								feedback = {
									tipo: 'success',
									mensagem: `✅ ${resultado.eventosCriados} eventos de teste criados com sucesso!`
								};
							} catch (error) {
								feedback = {
									tipo: 'error',
									mensagem: `❌ Erro ao criar eventos de teste: ${error}`
								};
							}
						}}
					>
						🧪 Criar Eventos Teste
					</button>
					<button
						type="button"
						class="btn btn-xs btn-outline"
						onclick={async () => {
							try {
								const resultado = await client.mutation(api.security.limparEventosTeste, {});
								feedback = {
									tipo: 'success',
									mensagem: `🧹 ${resultado.removidos} eventos de teste removidos`
								};
								novosEventos = 0;
							} catch (error) {
								feedback = {
									tipo: 'error',
									mensagem: `❌ Erro ao limpar eventos de teste: ${error}`
								};
							}
						}}
					>
						🧹 Limpar Eventos Teste
					</button>
					{#each Object.entries(attackLabels).slice(0, 8) as [tipo, label] (tipo)}
						<button
							type="button"
							class={`btn btn-xs ${filtroTipos.includes(tipo as AtaqueCiberneticoTipo) ? 'btn-accent' : 'btn-outline btn-accent'}`}
							onclick={() => toggleFiltroTipo(tipo as AtaqueCiberneticoTipo)}
						>
							{label}
						</button>
					{/each}
				</div>
			</div>
			<div
				class={`mt-4 space-y-4 ${eventosFiltrados.length > 6 ? 'max-h-[28rem] overflow-auto pr-2' : ''}`}
			>
				{#if eventosFiltrados.length === 0}
					<p class="text-base-content/60 text-sm">Nenhum evento correspondente aos filtros.</p>
				{:else}
					{#each eventosFiltrados as evento (evento._id)}
						<div
							class={`card border-base-200 bg-base-100 border shadow-lg ${classeEventoCritico(evento.severidade)}`}
						>
							<div class="card-body gap-3">
								<div class="flex flex-wrap items-center justify-between gap-3">
									<div class="flex flex-wrap items-center gap-2">
										<span class={severityStyles[evento.severidade]}
											>{severityLabels[evento.severidade]}</span
										>
										<span class="badge badge-outline">{attackLabels[evento.tipoAtaque]}</span>
										<span class={statusStyles[evento.status] ?? 'badge badge-ghost'}
											>{evento.status}</span
										>
									</div>
									<span class="text-base-content/60 text-xs">{formatarData(evento.timestamp)}</span>
								</div>
								<p class="text-base-content/80 text-sm">{evento.descricao}</p>
								<div class="grid gap-2 text-xs md:grid-cols-2">
									<div class="space-y-1">
										{#if evento.origemIp}
											<div class="flex items-center gap-2">
												<span class="font-semibold">Origem:</span>
												<span>{evento.origemIp}</span>
											</div>
										{/if}
										<div class="flex items-center gap-2">
											<span class="font-semibold">Destino:</span>
											<span>{evento.destinoIp ?? 'n/d'}:{evento.destinoPorta ?? '--'}</span>
										</div>
									</div>
									<div class="space-y-1">
										<div class="flex items-center gap-2">
											<span class="font-semibold">Protocolo:</span>
											<span>{evento.protocolo ?? 'n/d'}</span>
										</div>
										<div class="flex items-center gap-2">
											<span class="font-semibold">Tags:</span>
											<span>{evento.tags?.join(', ') ?? '—'}</span>
										</div>
									</div>
								</div>
								<div class="flex flex-wrap gap-2">
									<button
										type="button"
										class="btn btn-error btn-sm"
										onclick={() =>
											aplicarMedidaIp('forcar_blacklist', evento.origemIp ?? '', evento._id)}
									>
										Bloquear origem
									</button>
									<button
										type="button"
										class="btn btn-outline btn-sm"
										onclick={async () => {
											try {
												await client.mutation(api.security.solicitarRelatorioSeguranca, {
													solicitanteId: obterUsuarioId(),
													filtros: {
														dataInicio: evento.timestamp - 15 * 60 * 1000,
														dataFim: evento.timestamp + 15 * 60 * 1000,
														severidades: [evento.severidade],
														tiposAtaque: [evento.tipoAtaque],
														incluirIndicadores: true,
														incluirMetricas: true,
														incluirAcoes: true
													}
												});
												feedback = {
													tipo: 'success',
													mensagem: 'Mini relatório solicitado para o evento selecionado.'
												};
											} catch (erro: unknown) {
												feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
											}
										}}
									>
										Relatório 30min
									</button>
								</div>
							</div>
						</div>
					{/each}
				{/if}
			</div>
		</div>

		<div class="border-accent/20 bg-base-100 space-y-6 rounded-3xl border p-6 shadow-2xl">
			<div>
				<h4 class="text-accent text-lg font-bold">Lista Negra Inteligente</h4>
				<ul
					class="mt-4 space-y-3 text-sm {ipCriticos.length >= 10
						? 'max-h-64 overflow-auto pr-2'
						: ''}"
				>
					{#if ipCriticos.length === 0}
						<li class="text-base-content/60">Nenhum IP crítico listado.</li>
					{:else}
						{#each ipCriticos as registro (registro.indicador)}
							<li class="bg-base-200/40 flex items-center justify-between gap-2 rounded-xl p-3">
								<div>
									<p class="font-semibold">{registro.indicador}</p>
									<p class="text-base-content/60 text-xs">
										Score: {registro.reputacao} • Ocorrências: {registro.ocorrencias}
									</p>
								</div>
								<button
									type="button"
									class="btn btn-xs btn-outline"
									onclick={() => aplicarMedidaIp('remover_blacklist', registro.indicador)}
								>
									Liberar
								</button>
							</li>
						{/each}
					{/if}
				</ul>
			</div>

			<!-- Bloco separado: Regras de Portas -->
			<div class="border-base-300 rounded-2xl border p-4">
				<h4 class="text-info text-lg font-bold">Regras de Portas Monitoradas</h4>
				<div
					class="mt-4 space-y-2 text-xs {regras.length >= 6 ? 'max-h-64 overflow-auto pr-2' : ''}"
				>
					{#if regras.length === 0}
						<p class="text-base-content/60">Nenhuma regra cadastrada.</p>
					{:else}
						{#each regras as regra (regra._id)}
							<div class="border-base-200 rounded-xl border p-3">
								<div class="flex items-center justify-between">
									<span class="font-semibold">
										{regra.porta}/{regra.protocolo.toUpperCase()}
									</span>
									<span class="badge badge-outline">{regra.acao}</span>
								</div>
								<p class="text-base-content/70 mt-1">
									Severidade mínima: {severityLabels[regra.severidadeMin]}
								</p>
								{#if regra.expiraEm}
									<p class="text-base-content/50">
										Expira em: {new Date(regra.expiraEm).toString().slice(0, 21)}
									</p>
								{/if}
								<div class="mt-2 flex gap-2">
									<button
										type="button"
										class="btn btn-xs btn-outline"
										onclick={async () => {
											try {
												await client.mutation(api.security.configurarRegraPorta, {
													usuarioId: obterUsuarioId(),
													regraId: regra._id,
													porta: regra.porta,
													protocolo: regra.protocolo,
													acao: regra.acao,
													temporario: false,
													severidadeMin: regra.severidadeMin
												});
												feedback = { tipo: 'success', mensagem: 'Regra atualizada.' };
											} catch (erro: unknown) {
												feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
											}
										}}
									>
										Editar
									</button>
									<button
										type="button"
										class="btn btn-xs btn-error"
										onclick={async () => {
											if (!confirm('Tem certeza que deseja excluir esta regra?')) return;
											try {
												await client.mutation(api.security.deletarRegraPorta, {
													regraId: regra._id,
													usuarioId: obterUsuarioId()
												});
												feedback = { tipo: 'success', mensagem: 'Regra excluída.' };
											} catch (erro: unknown) {
												feedback = { tipo: 'error', mensagem: mensagemErro(erro) };
											}
										}}
									>
										Excluir
									</button>
								</div>
							</div>
						{/each}
					{/if}
				</div>
			</div>

			<!-- Bloco separado: Relatórios -->
			<div class="border-base-300 rounded-2xl border p-4">
				<h4 class="text-primary text-lg font-bold">Relatórios refinados</h4>
				<form class="mt-3 space-y-2" onsubmit={gerarRelatorioAvancado}>
					<label class="form-control">
						<div class="label">
							<span class="label-text text-xs">Início</span>
						</div>
						<input
							type="datetime-local"
							class="input input-bordered input-sm"
							bind:value={relatorioInicio}
						/>
					</label>
					<label class="form-control">
						<div class="label">
							<span class="label-text text-xs">Fim</span>
						</div>
						<input
							type="datetime-local"
							class="input input-bordered input-sm"
							bind:value={relatorioFim}
						/>
					</label>
					<label class="flex items-center gap-2 text-xs">
						<input type="checkbox" class="checkbox checkbox-xs" bind:checked={incluirMetricas} />
						<span>Incluir métricas e payload hash</span>
					</label>
					<label class="flex items-center gap-2 text-xs">
						<input type="checkbox" class="checkbox checkbox-xs" bind:checked={incluirAcoes} />
						<span>Incluir histórico de ações</span>
					</label>
					<button type="submit" class="btn btn-primary btn-sm w-full">Gerar Relatório</button>
				</form>
				<!-- Grade de relatórios recentes -->
				<div class="divider my-4"></div>
				<h5 class="text-base-content text-sm font-semibold">Relatórios recentes</h5>
				{#if relatoriosRecentes?.data?.length}
					<div class="mt-2 overflow-x-auto">
						<table class="table-sm table">
							<thead>
								<tr>
									<th>Status</th>
									<th>Criado</th>
									<th>Concluído</th>
									<th>Observações</th>
									<th class="w-40">Ações</th>
								</tr>
							</thead>
							<tbody>
								{#each relatoriosRecentes.data as r (r._id)}
									<tr>
										<td>
											<span class="badge badge-outline">{r.status}</span>
										</td>
										<td>{new Date(r.criadoEm).toLocaleString('pt-BR', { hour12: false })}</td>
										<td
											>{r.concluidoEm
												? new Date(r.concluidoEm).toLocaleString('pt-BR', { hour12: false })
												: '-'}</td
										>
										<td class="max-w-xs truncate">{r.observacoes ?? '-'}</td>
										<td>
											<div class="flex gap-2">
												<button
													type="button"
													class="btn btn-xs btn-outline"
													disabled={r.status !== 'concluido'}
													title={r.status !== 'concluido' ? 'Aguarde concluir' : 'Imprimir'}
													onclick={() => imprimirRelatorio(r)}
												>
													Imprimir
												</button>
												<button
													type="button"
													class="btn btn-xs btn-error"
													onclick={() => excluirRelatorio(r._id)}
												>
													Excluir
												</button>
											</div>
										</td>
									</tr>
								{/each}
							</tbody>
						</table>
					</div>
				{:else}
					<p class="text-base-content/60 mt-2 text-xs">Nenhum relatório recente.</p>
				{/if}
			</div>
		</div>
	</section>

	<!-- Seção de Rate Limiting -->
	<section class="border-warning/20 bg-base-100/80 rounded-3xl border p-6 shadow-2xl">
		<div class="mb-4 flex items-center justify-between">
			<div>
				<h3 class="text-warning text-2xl font-bold">Rate Limiting Avançado</h3>
				<p class="text-base-content/70 text-sm">
					Configure limites de requisições por IP, usuário, endpoint ou globalmente para proteger o
					sistema.
				</p>
			</div>
			<button
				type="button"
				class="btn btn-warning btn-sm"
				onclick={() => {
					resetarFormRateLimit();
					mostrarRateLimitConfig = !mostrarRateLimitConfig;
				}}
			>
				{mostrarRateLimitConfig ? 'Cancelar' : '+ Nova Configuração'}
			</button>
		</div>

		{#if mostrarRateLimitConfig}
			<form
				class="border-warning/30 bg-base-200/40 mb-6 space-y-4 rounded-xl border p-4"
				onsubmit={salvarConfigRateLimit}
			>
				<div class="grid gap-4 md:grid-cols-2">
					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Nome da Configuração</span>
						</div>
						<input
							type="text"
							class="input input-bordered"
							placeholder="Ex: Limite IPs suspeitos"
							bind:value={rateLimitNome}
							required
						/>
					</label>

					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Tipo</span>
						</div>
						<select class="select select-bordered" bind:value={rateLimitTipo}>
							<option value="ip">Por IP</option>
							<option value="usuario">Por Usuário</option>
							<option value="endpoint">Por Endpoint</option>
							<option value="global">Global</option>
						</select>
					</label>

					{#if rateLimitTipo !== 'global'}
						<label class="form-control">
							<div class="label">
								<span class="label-text font-semibold">
									Identificador ({rateLimitTipo === 'ip'
										? 'IP'
										: rateLimitTipo === 'usuario'
											? 'ID do Usuário'
											: 'Caminho do Endpoint'})
								</span>
							</div>
							<input
								type="text"
								class="input input-bordered"
								placeholder={rateLimitTipo === 'ip'
									? 'Ex: 192.168.1.1'
									: rateLimitTipo === 'usuario'
										? 'ID do usuário'
										: '/api/security/registrar'}
								bind:value={rateLimitIdentificador}
								required
							/>
						</label>
					{/if}

					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Limite de Requisições</span>
						</div>
						<input
							type="number"
							class="input input-bordered"
							min="1"
							max="10000"
							bind:value={rateLimitLimite}
							required
						/>
					</label>

					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Janela de Tempo (segundos)</span>
						</div>
						<input
							type="number"
							class="input input-bordered"
							min="1"
							max="86400"
							bind:value={rateLimitJanelaSegundos}
							required
						/>
					</label>

					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Estratégia</span>
						</div>
						<select class="select select-bordered" bind:value={rateLimitEstrategia}>
							<option value="fixed_window">Fixed Window</option>
							<option value="sliding_window">Sliding Window</option>
							<option value="token_bucket">Token Bucket</option>
						</select>
					</label>

					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Ação ao Exceder</span>
						</div>
						<select class="select select-bordered" bind:value={rateLimitAcaoExcedido}>
							<option value="bloquear">Bloquear</option>
							<option value="throttle">Throttle (Atrasar)</option>
							<option value="alertar">Apenas Alertar</option>
						</select>
					</label>

					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Bloqueio Temporário (segundos, opcional)</span>
						</div>
						<input
							type="number"
							class="input input-bordered"
							min="0"
							placeholder="Deixe vazio para sem bloqueio temporário"
							bind:value={rateLimitBloqueioTemporarioSegundos}
						/>
					</label>

					<label class="form-control">
						<div class="label">
							<span class="label-text font-semibold">Prioridade</span>
						</div>
						<input
							type="number"
							class="input input-bordered"
							min="0"
							max="100"
							bind:value={rateLimitPrioridade}
						/>
						<div class="label">
							<span class="label-text-alt">Maior prioridade = aplicado primeiro</span>
						</div>
					</label>
				</div>

				<label class="form-control">
					<div class="label">
						<span class="label-text font-semibold">Notas</span>
					</div>
					<textarea
						class="textarea textarea-bordered"
						placeholder="Observações sobre esta configuração..."
						bind:value={rateLimitNotas}
					></textarea>
				</label>

				<div class="flex gap-2">
					<button type="submit" class="btn btn-warning flex-1">
						{rateLimitEditando ? 'Atualizar Configuração' : 'Criar Configuração'}
					</button>
					{#if rateLimitEditando}
						<button
							type="button"
							class="btn btn-ghost"
							onclick={() => {
								resetarFormRateLimit();
								mostrarRateLimitConfig = false;
							}}
						>
							Cancelar
						</button>
					{/if}
				</div>
			</form>
		{/if}

		<div class="space-y-3">
			<h4 class="text-warning text-lg font-bold">Configurações Ativas</h4>
			{#if configsRateLimit?.data && configsRateLimit.data.length > 0}
				<div class="space-y-2">
					{#each configsRateLimit.data as config (config._id)}
						<div class="border-warning/30 bg-base-200/40 rounded-xl border p-4">
							<div class="flex items-start justify-between">
								<div class="flex-1">
									<div class="flex items-center gap-2">
										<h5 class="font-bold">{config.nome}</h5>
										<span class="badge badge-warning badge-sm">{config.tipo}</span>
										{#if config.ativo}
											<span class="badge badge-success badge-sm">Ativo</span>
										{:else}
											<span class="badge badge-ghost badge-sm">Inativo</span>
										{/if}
									</div>
									<div class="mt-2 grid gap-1 text-sm">
										<p>
											<span class="font-semibold">Limite:</span>
											{config.limite} requisições em {config.janelaSegundos}s
										</p>
										<p>
											<span class="font-semibold">Estratégia:</span>
											{config.estrategia.replace('_', ' ')}
										</p>
										<p>
											<span class="font-semibold">Ação:</span>
											{config.acaoExcedido}
										</p>
										{#if config.identificador}
											<p>
												<span class="font-semibold">Identificador:</span>
												{config.identificador}
											</p>
										{/if}
										<p>
											<span class="font-semibold">Prioridade:</span>
											{config.prioridade}
										</p>
										{#if config.notas}
											<p class="text-base-content/70">
												<span class="font-semibold">Notas:</span>
												{config.notas}
											</p>
										{/if}
									</div>
								</div>
								<div class="flex flex-col gap-2">
									<button
										type="button"
										class="btn btn-xs btn-outline"
										onclick={() => toggleAtivoRateLimit(config._id, config.ativo)}
									>
										{config.ativo ? 'Desativar' : 'Ativar'}
									</button>
									<button
										type="button"
										class="btn btn-xs btn-outline"
										onclick={() => editarConfigRateLimit(config._id)}
									>
										Editar
									</button>
									<button
										type="button"
										class="btn btn-xs btn-error btn-outline"
										onclick={() => deletarConfigRateLimit(config._id)}
									>
										Deletar
									</button>
								</div>
							</div>
						</div>
					{/each}
				</div>
			{:else}
				<p class="text-base-content/60 text-sm">Nenhuma configuração de rate limit cadastrada.</p>
			{/if}
		</div>
	</section>

	<!-- Alertas e Notificações -->
	<section
		class="border-info/20 bg-base-100/80 mt-6 rounded-3xl border p-6 shadow-2xl"
		data-alert-form
	>
		<div class="mb-6 flex items-center justify-between">
			<div>
				<h3 class="text-info text-2xl font-bold">Alertas e Notificações</h3>
				<p class="text-base-content/70 mt-1 text-sm">
					Configure múltiplas configurações de alertas. Cada configuração pode ter diferentes
					destinatários, níveis e tipos de alarme.
				</p>
			</div>
			<button
				type="button"
				class="btn btn-primary btn-sm gap-2"
				onclick={() => limparFormularioAlertas()}
			>
				<svg
					xmlns="http://www.w3.org/2000/svg"
					class="h-4 w-4"
					fill="none"
					viewBox="0 0 24 24"
					stroke="currentColor"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M12 4v16m8-8H4"
					/>
				</svg>
				Nova Configuração
			</button>
		</div>

		<!-- Nome da Configuração -->
		<div class="border-base-300 bg-base-100/50 mb-6 rounded-xl border p-4">
			<div class="form-control">
				<label class="label py-1">
					<span class="label-text text-sm font-semibold">Nome da Configuração</span>
					<span class="label-text-alt text-base-content/50 text-xs"
						>{editarAlertConfigId
							? 'Editando configuração existente'
							: 'Criando nova configuração'}</span
					>
				</label>
				<input
					type="text"
					class="input input-bordered input-primary w-full"
					bind:value={alertNomeConfig}
					placeholder="Ex: Alertas Críticos - Equipe TI"
				/>
			</div>
		</div>

		<!-- Configurações de Notificação -->
		<div class="mb-6 grid gap-6 lg:grid-cols-2">
			<!-- Configurações de Email -->
			<div class="border-base-300 bg-base-200/30 rounded-2xl border p-5">
				<div class="border-base-300 mb-5 flex items-center justify-between border-b pb-3">
					<div class="flex items-center gap-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="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
							/>
						</svg>
						<h4 class="text-base-content text-lg font-semibold">Notificações por Email</h4>
					</div>
					<label class="label cursor-pointer gap-2">
						<input
							type="checkbox"
							class="checkbox checkbox-primary checkbox-sm"
							bind:checked={enviarPorEmail}
						/>
						<span class="label-text text-xs font-medium">Ativar</span>
					</label>
				</div>

				<div class="space-y-5">
					<!-- Emails de Destino -->
					<div class="border-base-300 bg-base-100/50 rounded-xl border p-4">
						<h5 class="text-base-content mb-3 text-sm font-semibold">Emails de Destino</h5>
						<div class="space-y-4">
							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Lista de Emails</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Endereços de email (um por linha)</span
									>
								</label>
								<textarea
									class="textarea textarea-bordered textarea-primary w-full"
									rows="3"
									bind:value={alertEmails}
									placeholder="exemplo@email.com&#10;outro@email.com"
								></textarea>
							</div>

							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Selecionar Usuários</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Selecione múltiplos usuários (Ctrl + Clique)</span
									>
								</label>
								<div class="border-base-300 bg-base-100 rounded-lg border p-2">
									<select
										class="select select-bordered select-sm w-full"
										multiple
										size="6"
										onchange={(e) => {
											const options = Array.from(
												(e.target as HTMLSelectElement).selectedOptions
											).map((o) => o.value);
											for (const val of options) adicionarEmailSugestao(val);
										}}
									>
										{#each usuariosQuery?.data ?? [] as u (u._id)}
											<option value={u.email}>{u.nome} ({u.email})</option>
										{/each}
									</select>
								</div>
								{#if alertEmails.trim()}
									{@const emailsAdicionados = alertEmails
										.split('\n')
										.map((s) => s.trim())
										.filter(Boolean)}
									{#if emailsAdicionados.length > 0}
										<div class="mt-2">
											<p class="text-base-content/70 mb-2 text-xs font-medium">
												Emails adicionados ({emailsAdicionados.length}):
											</p>
											<div class="flex flex-wrap gap-1.5">
												{#each emailsAdicionados as email (email)}
													<span class="badge badge-primary badge-sm gap-1">
														{email}
														<button
															type="button"
															class="hover:text-error"
															aria-label="Remover email"
															onclick={() => {
																// Remover do textarea
																const linhas = alertEmails
																	.split('\n')
																	.filter((l) => l.trim() !== email.trim());
																alertEmails = linhas.join('\n');
															}}
														>
															<svg
																xmlns="http://www.w3.org/2000/svg"
																class="h-3 w-3"
																fill="none"
																viewBox="0 0 24 24"
																stroke="currentColor"
															>
																<path
																	stroke-linecap="round"
																	stroke-linejoin="round"
																	stroke-width="2"
																	d="M6 18L18 6M6 6l12 12"
																/>
															</svg>
														</button>
													</span>
												{/each}
											</div>
										</div>
									{/if}
								{/if}
							</div>
						</div>
					</div>

					<!-- Filtros de Severidade e Ataques -->
					<div class="border-base-300 bg-base-100/50 rounded-xl border p-4">
						<h5 class="text-base-content mb-3 text-sm font-semibold">Filtros de Alertas</h5>
						<div class="space-y-4">
							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Severidade Mínima</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Alertas a partir deste nível</span
									>
								</label>
								<select
									class="select select-bordered select-sm w-full"
									bind:value={alertSeveridadeMin}
								>
									{#each severidadesDisponiveis as s (s)}
										<option value={s}>{severityLabels[s]}</option>
									{/each}
								</select>
							</div>

							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Tipos de Ataque</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Selecione múltiplos tipos (Ctrl + Clique)</span
									>
								</label>
								<div class="border-base-300 bg-base-100 rounded-lg border p-2">
									<select
										class="select select-bordered select-sm w-full"
										multiple
										size="6"
										bind:value={alertTiposAtaque}
									>
										{#each Object.keys(attackLabels) as t (t)}
											<option value={t}>{attackLabels[t as AtaqueCiberneticoTipo]}</option>
										{/each}
									</select>
								</div>
								{#if alertTiposAtaque.length > 0}
									<div class="mt-2 flex flex-wrap gap-1.5">
										{#each alertTiposAtaque as tipo (tipo)}
											<span class="badge badge-primary badge-sm gap-1">
												{attackLabels[tipo as AtaqueCiberneticoTipo]}
												<button
													type="button"
													class="hover:text-error"
													aria-label="Remover tipo de ataque"
													onclick={() => {
														alertTiposAtaque = alertTiposAtaque.filter((t) => t !== tipo);
													}}
												>
													<svg
														xmlns="http://www.w3.org/2000/svg"
														class="h-3 w-3"
														fill="none"
														viewBox="0 0 24 24"
														stroke="currentColor"
													>
														<path
															stroke-linecap="round"
															stroke-linejoin="round"
															stroke-width="2"
															d="M6 18L18 6M6 6l12 12"
														/>
													</svg>
												</button>
											</span>
										{/each}
									</div>
								{/if}
							</div>
						</div>
					</div>

					<!-- Configurações de Envio -->
					<div class="border-base-300 bg-base-100/50 rounded-xl border p-4">
						<h5 class="text-base-content mb-3 text-sm font-semibold">Configurações de Envio</h5>
						<div class="space-y-4">
							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Tempo de Reenvio</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Intervalo entre notificações</span
									>
								</label>
								<div class="flex items-center gap-2">
									<input
										type="number"
										min="1"
										max="1440"
										class="input input-bordered input-sm flex-1"
										bind:value={alertReenvioMin}
										placeholder="15"
									/>
									<span class="text-base-content/60 text-xs">minutos</span>
								</div>
							</div>

							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Template de Email</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Formato da mensagem</span
									>
								</label>
								<select class="select select-bordered select-sm w-full" bind:value={alertTemplate}>
									<option value="incidente_critico">Incidente Crítico - Ação Imediata</option>
									<option value="bloqueio_automatico">Bloqueio Automático</option>
									<option value="sumario_30min">Sumário 30 Min</option>
									<option value="anormalidade">Anomalia Detectada</option>
								</select>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- Configurações de Chat -->
			<div class="border-base-300 bg-base-200/30 rounded-2xl border p-5">
				<div class="border-base-300 mb-5 flex items-center justify-between border-b pb-3">
					<div class="flex items-center gap-2">
						<svg
							xmlns="http://www.w3.org/2000/svg"
							class="text-secondary h-5 w-5"
							fill="none"
							viewBox="0 0 24 24"
							stroke="currentColor"
						>
							<path
								stroke-linecap="round"
								stroke-linejoin="round"
								stroke-width="2"
								d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
							/>
						</svg>
						<h4 class="text-base-content text-lg font-semibold">Notificações por Chat</h4>
					</div>
					<label class="label cursor-pointer gap-2">
						<input
							type="checkbox"
							class="checkbox checkbox-secondary checkbox-sm"
							bind:checked={enviarPorChat}
						/>
						<span class="label-text text-xs font-medium">Ativar</span>
					</label>
				</div>

				<div class="space-y-5">
					<!-- Usuários do Chat -->
					<div class="border-base-300 bg-base-100/50 rounded-xl border p-4">
						<h5 class="text-base-content mb-3 text-sm font-semibold">Usuários do Chat</h5>
						<div class="space-y-4">
							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Lista de Usuários</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>IDs de usuários (um por linha)</span
									>
								</label>
								<textarea
									class="textarea textarea-bordered textarea-secondary w-full"
									rows="3"
									bind:value={alertUsersChat}
									placeholder="usuario1@email.com&#10;usuario2@email.com"
								></textarea>
							</div>

							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Selecionar Usuários</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Selecione múltiplos usuários (Ctrl + Clique)</span
									>
								</label>
								<div class="border-base-300 bg-base-100 rounded-lg border p-2">
									<select
										class="select select-bordered select-sm w-full"
										multiple
										size="6"
										onchange={(e) => {
											const options = Array.from(
												(e.target as HTMLSelectElement).selectedOptions
											).map((o) => o.value);
											for (const val of options) adicionarChatSugestao(val);
										}}
									>
										{#each usuariosParaChat?.data ?? [] as u (u._id)}
											<option value={u.email}>{u.nome} ({u.email})</option>
										{/each}
									</select>
								</div>
								{#if alertUsersChat.trim()}
									{@const usuariosAdicionados = alertUsersChat
										.split('\n')
										.map((s) => s.trim())
										.filter(Boolean)}
									{#if usuariosAdicionados.length > 0}
										<div class="mt-2">
											<p class="text-base-content/70 mb-2 text-xs font-medium">
												Usuários adicionados ({usuariosAdicionados.length}):
											</p>
											<div class="flex flex-wrap gap-1.5">
												{#each usuariosAdicionados as usuario (usuario)}
													<span class="badge badge-secondary badge-sm gap-1">
														{usuario}
														<button
															type="button"
															class="hover:text-error"
															aria-label="Remover usuário"
															onclick={() => {
																// Remover do textarea
																const linhas = alertUsersChat
																	.split('\n')
																	.filter((l) => l.trim() !== usuario.trim());
																alertUsersChat = linhas.join('\n');
															}}
														>
															<svg
																xmlns="http://www.w3.org/2000/svg"
																class="h-3 w-3"
																fill="none"
																viewBox="0 0 24 24"
																stroke="currentColor"
															>
																<path
																	stroke-linecap="round"
																	stroke-linejoin="round"
																	stroke-width="2"
																	d="M6 18L18 6M6 6l12 12"
																/>
															</svg>
														</button>
													</span>
												{/each}
											</div>
										</div>
									{/if}
								{/if}
							</div>
						</div>
					</div>

					<!-- Filtros de Alertas -->
					<div class="border-base-300 bg-base-100/50 rounded-xl border p-4">
						<h5 class="text-base-content mb-3 text-sm font-semibold">Filtros de Alertas</h5>
						<div class="space-y-4">
							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Severidade Mínima</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Alertas a partir deste nível</span
									>
								</label>
								<select
									class="select select-bordered select-sm w-full"
									bind:value={chatSeveridadeMin}
								>
									{#each severidadesDisponiveis as s (s)}
										<option value={s}>{severityLabels[s]}</option>
									{/each}
								</select>
							</div>

							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Tipos de Ataque</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Selecione múltiplos tipos (Ctrl + Clique)</span
									>
								</label>
								<div class="border-base-300 bg-base-100 rounded-lg border p-2">
									<select
										class="select select-bordered select-sm w-full"
										multiple
										size="6"
										bind:value={chatTiposAtaque}
									>
										{#each Object.keys(attackLabels) as t (t)}
											<option value={t}>{attackLabels[t as AtaqueCiberneticoTipo]}</option>
										{/each}
									</select>
								</div>
								{#if chatTiposAtaque.length > 0}
									<div class="mt-2 flex flex-wrap gap-1.5">
										{#each chatTiposAtaque as tipo (tipo)}
											<span class="badge badge-secondary badge-sm gap-1">
												{attackLabels[tipo as AtaqueCiberneticoTipo]}
												<button
													type="button"
													class="hover:text-error"
													aria-label="Remover tipo de ataque"
													onclick={() => {
														chatTiposAtaque = chatTiposAtaque.filter((t) => t !== tipo);
													}}
												>
													<svg
														xmlns="http://www.w3.org/2000/svg"
														class="h-3 w-3"
														fill="none"
														viewBox="0 0 24 24"
														stroke="currentColor"
													>
														<path
															stroke-linecap="round"
															stroke-linejoin="round"
															stroke-width="2"
															d="M6 18L18 6M6 6l12 12"
														/>
													</svg>
												</button>
											</span>
										{/each}
									</div>
								{/if}
							</div>
						</div>
					</div>

					<!-- Configurações de Envio -->
					<div class="border-base-300 bg-base-100/50 rounded-xl border p-4">
						<h5 class="text-base-content mb-3 text-sm font-semibold">Configurações de Envio</h5>
						<div class="space-y-4">
							<div class="form-control">
								<label class="label py-1">
									<span class="label-text text-xs font-medium">Tempo de Reenvio</span>
									<span class="label-text-alt text-base-content/50 text-xs"
										>Intervalo entre notificações</span
									>
								</label>
								<div class="flex items-center gap-2">
									<input
										type="number"
										min="1"
										max="1440"
										class="input input-bordered input-sm flex-1"
										bind:value={chatReenvioMin}
										placeholder="10"
									/>
									<span class="text-base-content/60 text-xs">minutos</span>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<!-- Botões de Ação -->
		<div class="mb-6 flex justify-end gap-3">
			{#if editarAlertConfigId}
				<button
					type="button"
					class="btn btn-ghost btn-lg"
					onclick={() => limparFormularioAlertas()}
				>
					Cancelar Edição
				</button>
			{/if}
			<button
				type="button"
				class="btn btn-info btn-lg gap-2"
				onclick={() => salvarPreferenciasAlertas(editarAlertConfigId ?? undefined)}
			>
				<svg
					xmlns="http://www.w3.org/2000/svg"
					class="h-5 w-5"
					fill="none"
					viewBox="0 0 24 24"
					stroke="currentColor"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M5 13l4 4L19 7"
					/>
				</svg>
				{editarAlertConfigId ? 'Atualizar Configuração' : 'Salvar Nova Configuração'}
			</button>
		</div>

		<!-- Divisor -->
		<div class="divider my-6">
			<span class="text-base-content/60 text-sm font-medium">Configurações Salvas</span>
		</div>

		<!-- Configurações Salvas -->
		{#if alertConfigs?.data?.length}
			<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
				{#each alertConfigs.data as cfg (cfg._id)}
					<div
						class="group border-base-300 bg-base-200/50 hover:border-info/50 rounded-xl border p-4 transition-all hover:shadow-md"
					>
						<div class="mb-3 flex items-start justify-between">
							<div class="flex-1">
								<h5 class="text-base-content mb-2 text-base font-bold">{cfg.nome}</h5>
								<div class="mb-2 flex flex-wrap gap-2">
									{#if cfg.canais.email}
										<span class="badge badge-info badge-sm gap-1">
											<svg
												xmlns="http://www.w3.org/2000/svg"
												class="h-3 w-3"
												fill="none"
												viewBox="0 0 24 24"
												stroke="currentColor"
											>
												<path
													stroke-linecap="round"
													stroke-linejoin="round"
													stroke-width="2"
													d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
												/>
											</svg>
											Email
										</span>
									{/if}
									{#if cfg.canais.chat}
										<span class="badge badge-secondary badge-sm gap-1">
											<svg
												xmlns="http://www.w3.org/2000/svg"
												class="h-3 w-3"
												fill="none"
												viewBox="0 0 24 24"
												stroke="currentColor"
											>
												<path
													stroke-linecap="round"
													stroke-linejoin="round"
													stroke-width="2"
													d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
												/>
											</svg>
											Chat
										</span>
									{/if}
								</div>
							</div>
						</div>
						<div class="text-base-content/70 mb-3 space-y-1.5 text-xs">
							<div class="flex items-center gap-2">
								<span class="font-medium">Severidade:</span>
								<span class="badge badge-outline badge-xs">{severityLabels[cfg.severidadeMin]}</span
								>
							</div>
							<div class="flex items-center gap-2">
								<span class="font-medium">Reenvio:</span>
								<span>{cfg.reenvioMin} minutos</span>
							</div>
							{#if cfg.emails.length}
								<div class="mt-2">
									<span class="font-medium">Emails ({cfg.emails.length}):</span>
									<div class="mt-1 flex flex-wrap gap-1">
										{#each cfg.emails.slice(0, 3) as email (email)}
											<span class="badge badge-ghost badge-xs">{email}</span>
										{/each}
										{#if cfg.emails.length > 3}
											<span class="badge badge-ghost badge-xs">+{cfg.emails.length - 3}</span>
										{/if}
									</div>
								</div>
							{/if}
							{#if cfg.chatUsers.length}
								<div class="mt-2">
									<span class="font-medium">Usuários Chat ({cfg.chatUsers.length}):</span>
									<div class="mt-1 flex flex-wrap gap-1">
										{#each cfg.chatUsers.slice(0, 2) as user (user)}
											<span class="badge badge-ghost badge-xs">{user}</span>
										{/each}
										{#if cfg.chatUsers.length > 2}
											<span class="badge badge-ghost badge-xs">+{cfg.chatUsers.length - 2}</span>
										{/if}
									</div>
								</div>
							{/if}
						</div>
						<div class="mt-4 flex gap-2">
							<button
								class="btn btn-xs btn-ghost hover:btn-info flex-1"
								type="button"
								onclick={() => carregarParaEdicao(cfg)}
							>
								<svg
									xmlns="http://www.w3.org/2000/svg"
									class="h-4 w-4"
									fill="none"
									viewBox="0 0 24 24"
									stroke="currentColor"
								>
									<path
										stroke-linecap="round"
										stroke-linejoin="round"
										stroke-width="2"
										d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
									/>
								</svg>
								Editar
							</button>
							<button
								class="btn btn-xs btn-ghost hover:btn-error"
								type="button"
								onclick={() => excluirPreferenciasAlertas(cfg._id)}
							>
								<svg
									xmlns="http://www.w3.org/2000/svg"
									class="h-4 w-4"
									fill="none"
									viewBox="0 0 24 24"
									stroke="currentColor"
								>
									<path
										stroke-linecap="round"
										stroke-linejoin="round"
										stroke-width="2"
										d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
									/>
								</svg>
								Excluir
							</button>
						</div>
					</div>
				{/each}
			</div>
		{:else}
			<div class="border-base-300 bg-base-200/30 rounded-xl border p-8 text-center">
				<svg
					xmlns="http://www.w3.org/2000/svg"
					class="text-base-content/40 mx-auto mb-3 h-12 w-12"
					fill="none"
					viewBox="0 0 24 24"
					stroke="currentColor"
				>
					<path
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
					/>
				</svg>
				<p class="text-base-content/60 text-sm font-medium">Nenhuma configuração salva</p>
				<p class="text-base-content/40 mt-1 text-xs">
					Configure e salve suas preferências de alertas acima
				</p>
			</div>
		{/if}
	</section>
</div>

<style>
	.card::-webkit-scrollbar {
		display: none;
	}
</style>
