import { v } from 'convex/values';
import { mutation, query } from './_generated/server';
import { registrarAtividade } from './logsAtividades';
import { Id, Doc } from './_generated/dataModel';
import type { QueryCtx } from './_generated/server';
import { createAuthUser, getCurrentUserFunction } from './auth';

/**
 * Helper para obter a matrícula do usuário (do funcionário se houver)
 */
async function obterMatriculaUsuario(
	ctx: QueryCtx,
	usuario: Doc<'usuarios'>
): Promise<string | undefined> {
	if (usuario.funcionarioId) {
		const funcionario = await ctx.db.get(usuario.funcionarioId);
		return funcionario?.matricula;
	}
	return undefined;
}

/**
 * Associar funcionário a um usuário
 */
export const associarFuncionario = mutation({
	args: {
		usuarioId: v.id('usuarios'),
		funcionarioId: v.id('funcionarios')
	},
	returns: v.object({ sucesso: v.boolean() }),
	handler: async (ctx, args) => {
		// Verificar se o funcionário existe
		const funcionario = await ctx.db.get(args.funcionarioId);
		if (!funcionario) {
			throw new Error('Funcionário não encontrado');
		}

		// Verificar se o funcionário já está associado a outro usuário
		const usuarioExistente = await ctx.db
			.query('usuarios')
			.withIndex('by_funcionarioId', (q) => q.eq('funcionarioId', args.funcionarioId))
			.first();

		if (usuarioExistente && usuarioExistente._id !== args.usuarioId) {
			const matricula = await obterMatriculaUsuario(ctx, usuarioExistente);
			throw new Error(
				`Este funcionário já está associado ao usuário: ${
					usuarioExistente.nome
				}${matricula ? ` (${matricula})` : ''}`
			);
		}

		// Associar funcionário ao usuário
		await ctx.db.patch(args.usuarioId, {
			funcionarioId: args.funcionarioId
		});

		return { sucesso: true };
	}
});

/**
 * Desassociar funcionário de um usuário
 */
export const desassociarFuncionario = mutation({
	args: {
		usuarioId: v.id('usuarios')
	},
	returns: v.object({ sucesso: v.boolean() }),
	handler: async (ctx, args) => {
		await ctx.db.patch(args.usuarioId, {
			funcionarioId: undefined
		});

		return { sucesso: true };
	}
});

/**
 * Criar novo usuário (apenas TI)
 */
export const criar = mutation({
	args: {
		nome: v.string(),
		email: v.string(),
		roleId: v.id('roles'),
		funcionarioId: v.optional(v.id('funcionarios')),
		senhaInicial: v.string()
	},
	returns: v.union(
		v.object({ sucesso: v.literal(true), usuarioId: v.id('usuarios') }),
		v.object({ sucesso: v.literal(false), erro: v.string() })
	),
	handler: async (ctx, args) => {
		// Verificar se email já existe
		const emailExistente = await ctx.db
			.query('usuarios')
			.withIndex('by_email', (q) => q.eq('email', args.email))
			.first();

		if (emailExistente) {
			return { sucesso: false as const, erro: 'E-mail já cadastrado' };
		}

		const senhaTemporaria = args.senhaInicial;

		const authUserId = await createAuthUser(ctx, {
			nome: args.nome,
			email: args.email,
			password: senhaTemporaria
		});

		// Criar usuário
		const usuarioId = await ctx.db.insert('usuarios', {
			authId: authUserId,
			nome: args.nome,
			email: args.email,
			funcionarioId: args.funcionarioId,
			roleId: args.roleId,
			ativo: true,
			primeiroAcesso: true,
			criadoEm: Date.now(),
			atualizadoEm: Date.now()
		});

		return { sucesso: true as const, usuarioId };
	}
});

/**
 * Listar todos os usuários com filtros
 */
export const listar = query({
	args: {
		setor: v.optional(v.string()),
		matricula: v.optional(v.string()),
		ativo: v.optional(v.boolean())
	},
	handler: async (ctx, args) => {
		let usuarios = await ctx.db.query('usuarios').collect();

		// Filtrar por matrícula (buscar no funcionário)
		if (args.matricula) {
			const usuariosComMatricula = await Promise.all(
				usuarios.map(async (u) => {
					const matricula = await obterMatriculaUsuario(ctx, u);
					return { usuario: u, matricula };
				})
			);
			usuarios = usuariosComMatricula
				.filter(({ matricula }) => matricula?.includes(args.matricula!))
				.map(({ usuario }) => usuario);
		}

		// Filtrar por ativo
		if (args.ativo !== undefined) {
			usuarios = usuarios.filter((u) => u.ativo === args.ativo);
		}

		// Buscar roles e funcionários
		const resultado = [];
		const usuariosSemRole: Array<{
			nome: string;
			matricula: string;
			roleId: Id<'roles'>;
		}> = [];

		for (const usuario of usuarios) {
			try {
				const role = await ctx.db.get(usuario.roleId);

				// Se a role não existe, criar uma role de erro mas ainda incluir o usuário
				if (!role) {
					const matricula = await obterMatriculaUsuario(ctx, usuario);
					usuariosSemRole.push({
						nome: usuario.nome,
						matricula: matricula || 'N/A',
						roleId: usuario.roleId
					});

					// Filtrar por setor - se filtro está ativo e role não existe, pular
					if (args.setor) {
						continue;
					}

					// Incluir usuário com role de erro
					let funcionario = undefined;
					if (usuario.funcionarioId) {
						try {
							const func = await ctx.db.get(usuario.funcionarioId);
							if (func) {
								funcionario = {
									_id: func._id,
									nome: func.nome,
									matricula: func.matricula,
									descricaoCargo: func.descricaoCargo,
									simboloTipo: func.simboloTipo
								};
							}
						} catch (error) {
							console.error(
								`Erro ao buscar funcionário ${usuario.funcionarioId} para usuário ${usuario._id}:`,
								error
							);
						}
					}

					const matriculaUsuario = await obterMatriculaUsuario(ctx, usuario);

					// Criar role de erro (sem _creationTime pois a role não existe)
					resultado.push({
						_id: usuario._id,
						matricula: matriculaUsuario,
						nome: usuario.nome,
						email: usuario.email,
						ativo: usuario.ativo,
						bloqueado: usuario.bloqueado,
						motivoBloqueio: usuario.motivoBloqueio,
						primeiroAcesso: usuario.primeiroAcesso,
						ultimoAcesso: usuario.ultimoAcesso,
						criadoEm: usuario.criadoEm,
						role: {
							_id: usuario.roleId,
							descricao: 'Perfil não encontrado' as const,
							nome: 'erro_role_ausente' as const,
							nivel: 999 as const,
							erro: true as const
						},
						funcionario,
						avisos: [
							{
								tipo: 'erro' as const,
								mensagem: `Perfil de acesso (ID: ${usuario.roleId}) não encontrado. Este usuário precisa ter seu perfil reatribuído.`
							}
						]
					});
					continue;
				}

				// Filtrar por setor
				if (args.setor && role.setor !== args.setor) {
					continue;
				}

				// Buscar funcionário associado
				let funcionario = undefined;
				if (usuario.funcionarioId) {
					try {
						const func = await ctx.db.get(usuario.funcionarioId);
						if (func) {
							funcionario = {
								_id: func._id,
								nome: func.nome,
								matricula: func.matricula,
								descricaoCargo: func.descricaoCargo,
								simboloTipo: func.simboloTipo
							};
						}
					} catch (error) {
						console.error(
							`Erro ao buscar funcionário ${usuario.funcionarioId} para usuário ${usuario._id}:`,
							error
						);
					}
				}

				// Construir objeto role - incluir _creationTime se existir (campo automático do Convex)
				const roleObj = {
					_id: role._id,
					descricao: role.descricao,
					nome: role.nome,
					nivel: role.nivel,
					...(role.criadoPor !== undefined && { criadoPor: role.criadoPor }),
					...(role.customizado !== undefined && {
						customizado: role.customizado
					}),
					...(role.editavel !== undefined && { editavel: role.editavel }),
					...(role.setor !== undefined && { setor: role.setor })
				};

				const matriculaUsuario = await obterMatriculaUsuario(ctx, usuario);

				resultado.push({
					_id: usuario._id,
					matricula: matriculaUsuario,
					nome: usuario.nome,
					email: usuario.email,
					ativo: usuario.ativo,
					bloqueado: usuario.bloqueado,
					motivoBloqueio: usuario.motivoBloqueio,
					primeiroAcesso: usuario.primeiroAcesso,
					ultimoAcesso: usuario.ultimoAcesso,
					criadoEm: usuario.criadoEm,
					role: roleObj,
					funcionario
				});
			} catch (error) {
				console.error(`Erro ao processar usuário ${usuario._id}:`, error);
				// Continua processando outros usuários mesmo se houver erro em um
			}
		}

		// Log de usuários sem role para depuração
		if (usuariosSemRole.length > 0) {
			console.warn(
				`⚠️ Encontrados ${usuariosSemRole.length} usuário(s) com perfil ausente:`,
				usuariosSemRole.map(
					(u) =>
						`${u.nome}${u.matricula !== 'N/A' ? ` (${u.matricula})` : ''} - RoleID: ${u.roleId}`
				)
			);
		}

		return resultado;
	}
});

/**
 * Ativar/Desativar usuário
 */
export const alterarStatus = mutation({
	args: {
		usuarioId: v.id('usuarios'),
		ativo: v.boolean()
	},
	returns: v.null(),
	handler: async (ctx, args) => {
		await ctx.db.patch(args.usuarioId, {
			ativo: args.ativo,
			atualizadoEm: Date.now()
		});

		// Se desativar, desativar todas as sessões
		if (!args.ativo) {
			const sessoes = await ctx.db
				.query('sessoes')
				.withIndex('by_usuario', (q) => q.eq('usuarioId', args.usuarioId))
				.collect();

			for (const sessao of sessoes) {
				await ctx.db.patch(sessao._id, { ativo: false });
			}
		}

		return null;
	}
});

/**
 * Resetar senha do usuário
 */
// export const resetarSenha = mutation({
//   args: {
//     usuarioId: v.id("usuarios"),
//     novaSenha: v.string(),
//   },
//   returns: v.null(),
//   handler: async (ctx, args) => {
//     const senhaHash = await hashPassword(args.novaSenha);

//     await ctx.db.patch(args.usuarioId, {
//       senhaHash,
//       primeiroAcesso: true,
//       atualizadoEm: Date.now(),
//     });

//     // Desativar todas as sessões
//     const sessoes = await ctx.db
//       .query("sessoes")
//       .withIndex("by_usuario", (q) => q.eq("usuarioId", args.usuarioId))
//       .collect();

//     for (const sessao of sessoes) {
//       await ctx.db.patch(sessao._id, { ativo: false });
//     }

//     return null;
//   },
// });

/**
 * Excluir usuário
 */
export const excluir = mutation({
	args: {
		usuarioId: v.id('usuarios')
	},
	returns: v.null(),
	handler: async (ctx, args) => {
		// Excluir sessões
		const sessoes = await ctx.db
			.query('sessoes')
			.withIndex('by_usuario', (q) => q.eq('usuarioId', args.usuarioId))
			.collect();

		for (const sessao of sessoes) {
			await ctx.db.delete(sessao._id);
		}

		// Excluir usuário
		await ctx.db.delete(args.usuarioId);

		return null;
	}
});

/**
 * Ativar usuário
 */
export const ativar = mutation({
	args: {
		id: v.id('usuarios')
	},
	returns: v.null(),
	handler: async (ctx, args) => {
		await ctx.db.patch(args.id, {
			ativo: true,
			atualizadoEm: Date.now()
		});
		return null;
	}
});

/**
 * Desativar usuário
 */
export const desativar = mutation({
	args: {
		id: v.id('usuarios')
	},
	returns: v.null(),
	handler: async (ctx, args) => {
		await ctx.db.patch(args.id, {
			ativo: false,
			atualizadoEm: Date.now()
		});

		// Desativar todas as sessões
		const sessoes = await ctx.db
			.query('sessoes')
			.withIndex('by_usuario', (q) => q.eq('usuarioId', args.id))
			.collect();

		for (const sessao of sessoes) {
			await ctx.db.patch(sessao._id, { ativo: false });
		}

		return null;
	}
});

/**
 * Alterar role de um usuário
 */
export const alterarRole = mutation({
	args: {
		usuarioId: v.id('usuarios'),
		novaRoleId: v.id('roles')
	},
	returns: v.null(),
	handler: async (ctx, args) => {
		// Verificar se a role existe
		const role = await ctx.db.get(args.novaRoleId);
		if (!role) {
			throw new Error('Role não encontrada');
		}

		// Atualizar usuário
		await ctx.db.patch(args.usuarioId, {
			roleId: args.novaRoleId,
			atualizadoEm: Date.now()
		});

		return null;
	}
});

/**
 * Atualizar perfil do usuário (foto, setor, status, preferências)
 */
export const atualizarPerfil = mutation({
	args: {
		fotoPerfil: v.optional(v.id('_storage')),
		avatar: v.optional(v.string()), // URL do avatar gerado (ex: DiceBear)
		setor: v.optional(v.string()),
		statusMensagem: v.optional(v.string()),
		statusPresenca: v.optional(
			v.union(
				v.literal('online'),
				v.literal('offline'),
				v.literal('ausente'),
				v.literal('externo'),
				v.literal('em_reuniao')
			)
		),
		notificacoesAtivadas: v.optional(v.boolean()),
		somNotificacao: v.optional(v.boolean()),
		temaPreferido: v.optional(v.string())
	},
	returns: v.null(),
	handler: async (ctx, args) => {
		const usuarioAtual = await getCurrentUserFunction(ctx);
		if (!usuarioAtual) throw new Error('Usuário não encontrado');

		// Validar statusMensagem (max 100 chars)
		if (args.statusMensagem && args.statusMensagem.length > 100) {
			throw new Error('Mensagem de status deve ter no máximo 100 caracteres');
		}

		// Atualizar apenas os campos fornecidos
		const updates: Partial<Doc<'usuarios'>> & { atualizadoEm: number } = {
			atualizadoEm: Date.now()
		};

		if (args.fotoPerfil !== undefined) updates.fotoPerfil = args.fotoPerfil;
		if (args.avatar !== undefined) updates.avatar = args.avatar;
		if (args.setor !== undefined) updates.setor = args.setor;
		if (args.statusMensagem !== undefined) updates.statusMensagem = args.statusMensagem;
		if (args.statusPresenca !== undefined) {
			updates.statusPresenca = args.statusPresenca;
			updates.ultimaAtividade = Date.now();
		}
		if (args.notificacoesAtivadas !== undefined)
			updates.notificacoesAtivadas = args.notificacoesAtivadas;
		if (args.somNotificacao !== undefined) updates.somNotificacao = args.somNotificacao;
		if (args.temaPreferido !== undefined) updates.temaPreferido = args.temaPreferido;

		await ctx.db.patch(usuarioAtual._id, updates);

		return null;
	}
});

/**
 * Atualizar tema preferido do usuário
 */
export const atualizarTema = mutation({
	args: {
		temaPreferido: v.string()
	},
	returns: v.object({ sucesso: v.boolean() }),
	handler: async (ctx, args) => {
		const usuarioAtual = await getCurrentUserFunction(ctx);
		if (!usuarioAtual) {
			throw new Error('Usuário não encontrado');
		}

		await ctx.db.patch(usuarioAtual._id, {
			temaPreferido: args.temaPreferido,
			atualizadoEm: Date.now()
		});

		return { sucesso: true };
	}
});

/**
 * Obter perfil do usuário atual
 */
export const obterPerfil = query({
	args: {},
	returns: v.union(
		v.object({
			_id: v.id('usuarios'),
			nome: v.string(),
			email: v.string(),
			matricula: v.optional(v.string()),
			funcionarioId: v.optional(v.id('funcionarios')),
			fotoPerfil: v.optional(v.id('_storage')),
			fotoPerfilUrl: v.union(v.string(), v.null()),
			avatar: v.optional(v.string()), // URL do avatar gerado (ex: DiceBear)
			setor: v.optional(v.string()),
			statusMensagem: v.optional(v.string()),
			statusPresenca: v.optional(
				v.union(
					v.literal('online'),
					v.literal('offline'),
					v.literal('ausente'),
					v.literal('externo'),
					v.literal('em_reuniao')
				)
			),
			notificacoesAtivadas: v.boolean(),
			somNotificacao: v.boolean()
		}),
		v.null()
	),
	handler: async (ctx) => {
		const usuarioAutenticado = await getCurrentUserFunction(ctx);
		if (!usuarioAutenticado) {
			return null;
		}

		const usuarioAtual = usuarioAutenticado;

		// Buscar fotoPerfil URL se existir
		let fotoPerfilUrl = null;
		if (usuarioAtual.fotoPerfil) {
			fotoPerfilUrl = await ctx.storage.getUrl(usuarioAtual.fotoPerfil);
		}

		const matricula = await obterMatriculaUsuario(ctx, usuarioAtual);

		return {
			_id: usuarioAtual._id,
			nome: usuarioAtual.nome,
			email: usuarioAtual.email,
			matricula: matricula || undefined,
			funcionarioId: usuarioAtual.funcionarioId,
			fotoPerfil: usuarioAtual.fotoPerfil,
			fotoPerfilUrl,
			avatar: usuarioAtual.avatar,
			setor: usuarioAtual.setor,
			statusMensagem: usuarioAtual.statusMensagem,
			statusPresenca: usuarioAtual.statusPresenca,
			notificacoesAtivadas: usuarioAtual.notificacoesAtivadas ?? true,
			somNotificacao: usuarioAtual.somNotificacao ?? true
		};
	}
});

/**
 * Listar todos usuários para o chat (com foto e status)
 */
export const listarParaChat = query({
	args: {},
	returns: v.array(
		v.object({
			_id: v.id('usuarios'),
			nome: v.string(),
			email: v.string(),
			matricula: v.optional(v.string()),
			fotoPerfil: v.optional(v.id('_storage')),
			fotoPerfilUrl: v.union(v.string(), v.null()),
			avatar: v.optional(v.string()), // URL do avatar gerado (ex: DiceBear)
			statusPresenca: v.optional(
				v.union(
					v.literal('online'),
					v.literal('offline'),
					v.literal('ausente'),
					v.literal('externo'),
					v.literal('em_reuniao')
				)
			),
			statusMensagem: v.optional(v.string()),
			ultimaAtividade: v.optional(v.number())
		})
	),
	handler: async (ctx) => {
		// Obter usuário autenticado usando função helper compartilhada
		const usuarioAtual = await getCurrentUserFunction(ctx);
		if (!usuarioAtual) {
			return [];
		}

		// Buscar todos os usuários ativos
		const usuarios = await ctx.db
			.query('usuarios')
			.filter((q) => q.eq(q.field('ativo'), true))
			.collect();

		// Filtrar o usuário atual da lista apenas se conseguimos identificá-lo com certeza
		// Se não conseguimos identificar (usuarioAtual é null), retornar todos
		// O frontend fará um filtro adicional usando obterPerfil como camada de segurança
		const usuariosFiltrados = usuarioAtual
			? usuarios.filter((u) => u._id !== usuarioAtual._id)
			: usuarios;

		// Buscar foto de perfil URL para cada usuário
		const usuariosComFoto = await Promise.all(
			usuariosFiltrados.map(async (usuario) => {
				let fotoPerfilUrl = null;
				if (usuario.fotoPerfil) {
					fotoPerfilUrl = await ctx.storage.getUrl(usuario.fotoPerfil);
				}

				const matricula = await obterMatriculaUsuario(ctx, usuario);

				return {
					_id: usuario._id,
					nome: usuario.nome,
					email: usuario.email,
					matricula: matricula || undefined,
					fotoPerfil: usuario.fotoPerfil,
					fotoPerfilUrl,
					statusPresenca: usuario.statusPresenca || 'offline',
					statusMensagem: usuario.statusMensagem,
					ultimaAtividade: usuario.ultimaAtividade
				};
			})
		);

		return usuariosComFoto;
	}
});

/**
 * Gera URL para upload de foto de perfil
 */
export const uploadFotoPerfil = mutation({
	args: {},
	returns: v.string(),
	handler: async (ctx) => {
		const usuarioAtual = await getCurrentUserFunction(ctx);
		if (!usuarioAtual) throw new Error('Usuário não autenticado');

		return await ctx.storage.generateUploadUrl();
	}
});

// ==================== GESTÃO AVANÇADA DE USUÁRIOS (TI_MASTER) ====================

/**
 * Bloquear usuário (apenas TI_MASTER)
 */
export const bloquearUsuario = mutation({
	args: {
		usuarioId: v.id('usuarios'),
		motivo: v.string(),
		bloqueadoPorId: v.id('usuarios')
	},
	returns: v.union(
		v.object({ sucesso: v.literal(true) }),
		v.object({ sucesso: v.literal(false), erro: v.string() })
	),
	handler: async (ctx, args) => {
		const usuarioAtual = await getCurrentUserFunction(ctx);
		if (!usuarioAtual) {
			return { sucesso: false as const, erro: 'Usuário não autenticado' };
		}

		const usuario = await ctx.db.get(args.usuarioId);
		if (!usuario) {
			return { sucesso: false as const, erro: 'Usuário não encontrado' };
		}

		// Atualizar usuário como bloqueado
		await ctx.db.patch(args.usuarioId, {
			bloqueado: true,
			motivoBloqueio: args.motivo,
			dataBloqueio: Date.now(),
			atualizadoEm: Date.now()
		});

		// Registrar no histórico de bloqueios
		await ctx.db.insert('bloqueiosUsuarios', {
			usuarioId: args.usuarioId,
			motivo: args.motivo,
			bloqueadoPor: args.bloqueadoPorId,
			dataInicio: Date.now(),
			ativo: true
		});

		// Desativar todas as sessões ativas do usuário
		const sessoes = await ctx.db
			.query('sessoes')
			.withIndex('by_usuario', (q) => q.eq('usuarioId', args.usuarioId))
			.filter((q) => q.eq(q.field('ativo'), true))
			.collect();

		for (const sessao of sessoes) {
			await ctx.db.patch(sessao._id, { ativo: false });
		}

		// Log de atividade
		await registrarAtividade(
			ctx,
			args.bloqueadoPorId,
			'bloquear',
			'usuarios',
			JSON.stringify({ usuarioId: args.usuarioId, motivo: args.motivo }),
			args.usuarioId
		);

		return { sucesso: true as const };
	}
});

/**
 * Desbloquear usuário (apenas TI_MASTER)
 */
export const desbloquearUsuario = mutation({
	args: {
		usuarioId: v.id('usuarios'),
		desbloqueadoPorId: v.id('usuarios')
	},
	returns: v.union(
		v.object({ sucesso: v.literal(true) }),
		v.object({ sucesso: v.literal(false), erro: v.string() })
	),
	handler: async (ctx, args) => {
		const usuarioAtual = await getCurrentUserFunction(ctx);
		if (!usuarioAtual) {
			return { sucesso: false as const, erro: 'Usuário não autenticado' };
		}

		const usuario = await ctx.db.get(args.usuarioId);
		if (!usuario) {
			return { sucesso: false as const, erro: 'Usuário não encontrado' };
		}

		// Atualizar usuário como desbloqueado
		await ctx.db.patch(args.usuarioId, {
			bloqueado: false,
			motivoBloqueio: undefined,
			dataBloqueio: undefined,
			tentativasLogin: 0,
			ultimaTentativaLogin: undefined,
			atualizadoEm: Date.now()
		});

		// Fechar bloqueios ativos
		const bloqueiosAtivos = await ctx.db
			.query('bloqueiosUsuarios')
			.withIndex('by_usuario', (q) => q.eq('usuarioId', args.usuarioId))
			.filter((q) => q.eq(q.field('ativo'), true))
			.collect();

		for (const bloqueio of bloqueiosAtivos) {
			await ctx.db.patch(bloqueio._id, {
				ativo: false,
				dataFim: Date.now(),
				desbloqueadoPor: args.desbloqueadoPorId
			});
		}

		// Log de atividade
		await registrarAtividade(
			ctx,
			args.desbloqueadoPorId,
			'desbloquear',
			'usuarios',
			JSON.stringify({ usuarioId: args.usuarioId }),
			args.usuarioId
		);

		return { sucesso: true as const };
	}
});

/**
 * Resetar senha de usuário (apenas TI_MASTER)
 */
// export const resetarSenhaUsuario = mutation({
//   args: {
//     usuarioId: v.id("usuarios"),
//     resetadoPorId: v.id("usuarios"),
//     novaSenhaTemporaria: v.optional(v.string()), // Se não fornecer, gera automática
//   },
//   returns: v.union(
//     v.object({ sucesso: v.literal(true), senhaTemporaria: v.string() }),
//     v.object({ sucesso: v.literal(false), erro: v.string() })
//   ),
//   handler: async (ctx, args) => {
//     const usuario = await ctx.db.get(args.usuarioId);
//     if (!usuario) {
//       return { sucesso: false as const, erro: "Usuário não encontrado" };
//     }

//     // Gerar senha temporária se não foi fornecida
//     const senhaTemporaria = args.novaSenhaTemporaria || gerarSenhaTemporaria();
//     const senhaHash = await hashPassword(senhaTemporaria);

//     // Atualizar usuário
//     await ctx.db.patch(args.usuarioId, {
//       senhaHash,
//       primeiroAcesso: true, // Força mudança de senha no próximo login
//       tentativasLogin: 0,
//       ultimaTentativaLogin: undefined,
//       atualizadoEm: Date.now(),
//     });

//     // Log de atividade
//     await registrarAtividade(
//       ctx,
//       args.resetadoPorId,
//       "resetar_senha",
//       "usuarios",
//       JSON.stringify({ usuarioId: args.usuarioId }),
//       args.usuarioId
//     );

//     return { sucesso: true as const, senhaTemporaria };
//   },
// });

// Helper para gerar senha temporária
function gerarSenhaTemporaria(): string {
	const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%';
	let senha = '';
	for (let i = 0; i < 12; i++) {
		senha += chars.charAt(Math.floor(Math.random() * chars.length));
	}
	return senha;
}

/**
 * Editar dados de usuário (apenas TI_MASTER)
 */
export const editarUsuario = mutation({
	args: {
		usuarioId: v.id('usuarios'),
		nome: v.optional(v.string()),
		email: v.optional(v.string()),
		roleId: v.optional(v.id('roles')),
		setor: v.optional(v.string()),
		editadoPorId: v.id('usuarios')
	},
	returns: v.union(
		v.object({ sucesso: v.literal(true) }),
		v.object({ sucesso: v.literal(false), erro: v.string() })
	),
	handler: async (ctx, args) => {
		const usuarioAtual = await getCurrentUserFunction(ctx);
		if (!usuarioAtual) {
			return { sucesso: false as const, erro: 'Usuário não autenticado' };
		}

		const usuario = await ctx.db.get(args.usuarioId);
		if (!usuario) {
			return { sucesso: false as const, erro: 'Usuário não encontrado' };
		}

		// Verificar se email já existe (se estiver mudando)
		if (args.email && args.email !== usuario.email) {
			const emailExistente = await ctx.db
				.query('usuarios')
				.withIndex('by_email', (q) => q.eq('email', args.email!))
				.first();

			if (emailExistente) {
				return { sucesso: false as const, erro: 'E-mail já cadastrado' };
			}
		}

		// Atualizar campos fornecidos
		const updates: Partial<Doc<'usuarios'>> & { atualizadoEm: number } = {
			atualizadoEm: Date.now()
		};

		if (args.nome !== undefined) updates.nome = args.nome;
		if (args.email !== undefined) updates.email = args.email;
		if (args.roleId !== undefined) updates.roleId = args.roleId;
		if (args.setor !== undefined) updates.setor = args.setor;

		await ctx.db.patch(args.usuarioId, updates);

		// Log de atividade
		await registrarAtividade(
			ctx,
			args.editadoPorId,
			'editar',
			'usuarios',
			JSON.stringify(updates),
			args.usuarioId
		);

		return { sucesso: true as const };
	}
});

/**
 * Criar/Promover usuário Admin Master (TI_MASTER - nível 0)
 */
export const criarAdminMaster = mutation({
	args: {
		nome: v.string(),
		email: v.string(),
		senha: v.optional(v.string())
	},
	returns: v.union(
		v.object({
			sucesso: v.literal(true),
			usuarioId: v.id('usuarios'),
			senhaTemporaria: v.string()
		}),
		v.object({ sucesso: v.literal(false), erro: v.string() })
	),
	handler: async (ctx, args) => {
		// Garantir que a role TI_MASTER exista (nível 0)
		let roleTIMaster = await ctx.db
			.query('roles')
			.withIndex('by_nome', (q) => q.eq('nome', 'ti_master'))
			.first();

		if (!roleTIMaster) {
			const roleId = await ctx.db.insert('roles', {
				nome: 'ti_master',
				descricao: 'TI Master',
				nivel: 0,
				setor: 'ti',
				customizado: false,
				editavel: false
			});
			roleTIMaster = await ctx.db.get(roleId);
		}

		if (!roleTIMaster) {
			return {
				sucesso: false as const,
				erro: 'Falha ao garantir role TI Master'
			};
		}

		const senhaTemporaria = args.senha || gerarSenhaTemporaria();

		const authUserId = await createAuthUser(ctx, {
			nome: args.nome,
			email: args.email,
			password: senhaTemporaria
		});

		// Verificar se email já existe
		const existentePorEmail = await ctx.db
			.query('usuarios')
			.withIndex('by_email', (q) => q.eq('email', args.email))
			.first();
		if (existentePorEmail) {
			// Promove usuário existente por email
			await ctx.db.patch(existentePorEmail._id, {
				nome: args.nome,
				roleId: roleTIMaster._id,
				ativo: true,
				primeiroAcesso: true,
				atualizadoEm: Date.now(),
				authId: authUserId
			});
			return {
				sucesso: true as const,
				usuarioId: existentePorEmail._id,
				senhaTemporaria
			};
		}

		// Criar novo usuário TI Master
		const usuarioId = await ctx.db.insert('usuarios', {
			authId: authUserId,
			nome: args.nome,
			email: args.email,
			roleId: roleTIMaster._id,
			ativo: true,
			primeiroAcesso: true,
			criadoEm: Date.now(),
			atualizadoEm: Date.now()
		});

		return { sucesso: true as const, usuarioId, senhaTemporaria };
	}
});
