import { defineTable } from 'convex/server';
import { Infer, v } from 'convex/values';

export const ataqueCiberneticoTipo = v.union(
	v.literal('phishing'),
	v.literal('malware'),
	v.literal('ransomware'),
	v.literal('brute_force'),
	v.literal('credential_stuffing'),
	v.literal('sql_injection'),
	v.literal('xss'),
	v.literal('path_traversal'),
	v.literal('command_injection'),
	v.literal('nosql_injection'),
	v.literal('xxe'),
	v.literal('man_in_the_middle'),
	v.literal('ddos'),
	v.literal('engenharia_social'),
	v.literal('cve_exploit'),
	v.literal('apt'),
	v.literal('zero_day'),
	v.literal('supply_chain'),
	v.literal('fileless_malware'),
	v.literal('polymorphic_malware'),
	v.literal('ransomware_lateral'),
	v.literal('deepfake_phishing'),
	v.literal('adversarial_ai'),
	v.literal('side_channel'),
	v.literal('firmware_bootloader'),
	v.literal('bec'),
	v.literal('botnet'),
	v.literal('ot_ics'),
	v.literal('quantum_attack')
);
export type AtaqueCiberneticoTipo = Infer<typeof ataqueCiberneticoTipo>;

export const severidadeSeguranca = v.union(
	v.literal('informativo'),
	v.literal('baixo'),
	v.literal('moderado'),
	v.literal('alto'),
	v.literal('critico')
);
export type SeveridadeSeguranca = Infer<typeof severidadeSeguranca>;

export const statusEventoSeguranca = v.union(
	v.literal('detectado'),
	v.literal('investigando'),
	v.literal('contido'),
	v.literal('falso_positivo'),
	v.literal('escalado'),
	v.literal('resolvido')
);
export type StatusEventoSeguranca = Infer<typeof statusEventoSeguranca>;

export const sensorSegurancaTipo = v.union(
	v.literal('network'),
	v.literal('endpoint'),
	v.literal('application'),
	v.literal('gateway'),
	v.literal('ot'),
	v.literal('honeypot')
);
export type SensorSegurancaTipo = Infer<typeof sensorSegurancaTipo>;

export const sensorSegurancaStatus = v.union(
	v.literal('ativo'),
	v.literal('inativo'),
	v.literal('degradado'),
	v.literal('manutencao')
);
export type SensorSegurancaStatus = Infer<typeof sensorSegurancaStatus>;

export const threatIntelTipo = v.union(
	v.literal('open_source'),
	v.literal('commercial'),
	v.literal('internal'),
	v.literal('gov'),
	v.literal('research')
);

export const threatIntelFormato = v.union(
	v.literal('json'),
	v.literal('stix'),
	v.literal('csv'),
	v.literal('text'),
	v.literal('custom')
);

export const acaoIncidenteTipo = v.union(
	v.literal('block_ip'),
	v.literal('unblock_ip'),
	v.literal('block_port'),
	v.literal('liberar_porta'),
	v.literal('notificar'),
	v.literal('isolar_host'),
	v.literal('gerar_relatorio'),
	v.literal('criar_ticket'),
	v.literal('ajuste_regra'),
	v.literal('custom')
);

export const acaoIncidenteStatus = v.union(
	v.literal('pendente'),
	v.literal('executando'),
	v.literal('concluido'),
	v.literal('falhou')
);

export const reportStatus = v.union(
	v.literal('pendente'),
	v.literal('processando'),
	v.literal('concluido'),
	v.literal('falhou')
);

export const securityTables = {
	// Sistema de Segurança Cibernética
	networkSensors: defineTable({
		nome: v.string(),
		tipo: sensorSegurancaTipo,
		status: sensorSegurancaStatus,
		escopo: v.optional(v.string()),
		ipMonitorado: v.optional(v.string()),
		hostname: v.optional(v.string()),
		regioes: v.optional(v.array(v.string())),
		portasMonitoradas: v.optional(v.array(v.number())),
		protocolos: v.optional(v.array(v.string())),
		capacidades: v.optional(v.array(v.string())),
		ultimaSincronizacao: v.number(),
		ultimoHeartbeat: v.optional(v.number()),
		latenciaMs: v.optional(v.number()),
		errosConsecutivos: v.optional(v.number()),
		agenteVersao: v.optional(v.string()),
		notas: v.optional(v.string())
	})
		.index('by_tipo', ['tipo'])
		.index('by_status', ['status'])
		.index('by_hostname', ['hostname']),

	ipReputation: defineTable({
		indicador: v.string(),
		categoria: v.union(
			v.literal('ip'),
			v.literal('dominio'),
			v.literal('hash'),
			v.literal('email')
		),
		reputacao: v.number(), // -100 (malicioso) até 100 (confiável)
		severidadeMax: severidadeSeguranca,
		whitelist: v.boolean(),
		blacklist: v.boolean(),
		ocorrencias: v.number(),
		primeiroRegistro: v.number(),
		ultimoRegistro: v.number(),
		bloqueadoAte: v.optional(v.number()),
		origem: v.optional(v.string()),
		comentarios: v.optional(v.string()),
		classificacoes: v.optional(v.array(v.string())),
		ultimaAcaoId: v.optional(v.id('incidentActions'))
	})
		.index('by_indicador', ['indicador'])
		.index('by_reputacao', ['reputacao'])
		.index('by_blacklist', ['blacklist'])
		.index('by_whitelist', ['whitelist']),

	portRules: defineTable({
		porta: v.number(),
		protocolo: v.union(
			v.literal('tcp'),
			v.literal('udp'),
			v.literal('icmp'),
			v.literal('quic'),
			v.literal('any')
		),
		acao: v.union(
			v.literal('permitir'),
			v.literal('bloquear'),
			v.literal('monitorar'),
			v.literal('rate_limit')
		),
		temporario: v.boolean(),
		severidadeMin: severidadeSeguranca,
		duracaoSegundos: v.optional(v.number()),
		expiraEm: v.optional(v.number()),
		criadoPor: v.id('usuarios'),
		atualizadoPor: v.optional(v.id('usuarios')),
		criadoEm: v.number(),
		atualizadoEm: v.number(),
		notas: v.optional(v.string()),
		tags: v.optional(v.array(v.string())),
		listaReferencia: v.optional(v.id('ipReputation'))
	})
		.index('by_porta_protocolo', ['porta', 'protocolo'])
		.index('by_acao', ['acao'])
		.index('by_expiracao', ['expiraEm']),

	threatIntelFeeds: defineTable({
		nomeFonte: v.string(),
		tipo: threatIntelTipo,
		formato: threatIntelFormato,
		url: v.optional(v.string()),
		ativo: v.boolean(),
		prioridade: v.union(
			v.literal('baixa'),
			v.literal('media'),
			v.literal('alta'),
			v.literal('critica')
		),
		ultimaSincronizacao: v.optional(v.number()),
		entradasProcessadas: v.optional(v.number()),
		errosConsecutivos: v.optional(v.number()),
		autenticacaoNecessaria: v.optional(v.boolean()),
		configuracao: v.optional(
			v.object({
				tokenId: v.optional(v.id('_storage')),
				escopo: v.optional(v.string())
			})
		),
		criadoPor: v.id('usuarios'),
		atualizadoPor: v.optional(v.id('usuarios')),
		criadoEm: v.number(),
		atualizadoEm: v.number()
	})
		.index('by_tipo', ['tipo'])
		.index('by_ativo', ['ativo'])
		.index('by_prioridade', ['prioridade']),

	securityEvents: defineTable({
		referencia: v.string(),
		timestamp: v.number(),
		tipoAtaque: ataqueCiberneticoTipo,
		severidade: severidadeSeguranca,
		status: statusEventoSeguranca,
		descricao: v.string(),
		origemIp: v.optional(v.string()),
		origemRegiao: v.optional(v.string()),
		origemAsn: v.optional(v.string()),
		destinoIp: v.optional(v.string()),
		destinoPorta: v.optional(v.number()),
		protocolo: v.optional(v.string()),
		transporte: v.optional(v.string()),
		sensorId: v.optional(v.id('networkSensors')),
		detectadoPor: v.optional(v.string()),
		mitreTechnique: v.optional(v.string()),
		geolocalizacao: v.optional(
			v.object({
				pais: v.optional(v.string()),
				regiao: v.optional(v.string()),
				cidade: v.optional(v.string()),
				latitude: v.optional(v.number()),
				longitude: v.optional(v.number())
			})
		),
		fingerprint: v.optional(
			v.object({
				userAgent: v.optional(v.string()),
				deviceId: v.optional(v.string()),
				ja3: v.optional(v.string()),
				tlsVersion: v.optional(v.string())
			})
		),
		indicadores: v.optional(
			v.array(
				v.object({
					tipo: v.string(),
					valor: v.string(),
					confianca: v.optional(v.number())
				})
			)
		),
		metricas: v.optional(
			v.object({
				pps: v.optional(v.number()),
				bps: v.optional(v.number()),
				rpm: v.optional(v.number()),
				errosPorSegundo: v.optional(v.number()),
				hostsAfetados: v.optional(v.number())
			})
		),
		correlacoes: v.optional(v.array(v.id('securityEvents'))),
		referenciasExternas: v.optional(v.array(v.string())),
		tags: v.optional(v.array(v.string())),
		criadoPor: v.optional(v.id('usuarios')),
		atualizadoEm: v.number()
	})
		.index('by_referencia', ['referencia'])
		.index('by_timestamp', ['timestamp'])
		.index('by_tipo', ['tipoAtaque', 'timestamp'])
		.index('by_severidade', ['severidade', 'timestamp'])
		.index('by_status', ['status', 'timestamp']),

	incidentActions: defineTable({
		eventoId: v.id('securityEvents'),
		tipo: acaoIncidenteTipo,
		origem: v.union(v.literal('automatico'), v.literal('manual')),
		status: acaoIncidenteStatus,
		executadoPor: v.optional(v.id('usuarios')),
		detalhes: v.optional(v.string()),
		resultado: v.optional(v.string()),
		relacionadoA: v.optional(v.id('ipReputation')),
		criadoEm: v.number(),
		atualizadoEm: v.number()
	})
		.index('by_evento', ['eventoId', 'status'])
		.index('by_tipo', ['tipo', 'status']),

	reportRequests: defineTable({
		solicitanteId: v.id('usuarios'),
		filtros: v.object({
			dataInicio: v.number(),
			dataFim: v.number(),
			severidades: v.optional(v.array(severidadeSeguranca)),
			tiposAtaque: v.optional(v.array(ataqueCiberneticoTipo)),
			incluirIndicadores: v.optional(v.boolean()),
			incluirMetricas: v.optional(v.boolean()),
			incluirAcoes: v.optional(v.boolean())
		}),
		status: reportStatus,
		resultadoId: v.optional(v.id('_storage')),
		observacoes: v.optional(v.string()),
		criadoEm: v.number(),
		atualizadoEm: v.number(),
		concluidoEm: v.optional(v.number()),
		erro: v.optional(v.string())
	})
		.index('by_status', ['status'])
		.index('by_solicitante', ['solicitanteId', 'status'])
		.index('by_criado_em', ['criadoEm'])
};
