import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
import { hashPassword, generateToken } from "./auth/utils";
import { registrarAtividade } from "./logsAtividades";
import { Id } from "./_generated/dataModel";

/**
 * 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) {
      throw new Error(
        `Este funcionário já está associado ao usuário: ${usuarioExistente.nome} (${usuarioExistente.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: {
    matricula: v.string(),
    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 matrícula já existe
    const existente = await ctx.db
      .query("usuarios")
      .withIndex("by_matricula", (q) => q.eq("matricula", args.matricula))
      .first();

    if (existente) {
      return { sucesso: false as const, erro: "Matrícula já cadastrada" };
    }

    // 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" };
    }

    // Gerar hash da senha inicial
    const senhaHash = await hashPassword(args.senhaInicial);

    // Criar usuário
    const usuarioId = await ctx.db.insert("usuarios", {
      matricula: args.matricula,
      senhaHash,
      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()),
  },
  returns: v.array(
    v.object({
      _id: v.id("usuarios"),
      matricula: v.string(),
      nome: v.string(),
      email: v.string(),
      ativo: v.boolean(),
      bloqueado: v.optional(v.boolean()),
      motivoBloqueio: v.optional(v.string()),
      primeiroAcesso: v.boolean(),
      ultimoAcesso: v.optional(v.number()),
      criadoEm: v.number(),
      role: v.object({
        _id: v.id("roles"),
        nome: v.string(),
        nivel: v.number(),
        setor: v.optional(v.string()),
      }),
      funcionario: v.optional(
        v.object({
          _id: v.id("funcionarios"),
          nome: v.string(),
          simboloTipo: v.union(
            v.literal("cargo_comissionado"),
            v.literal("funcao_gratificada")
          ),
        })
      ),
    })
  ),
  handler: async (ctx, args) => {
    let usuarios = await ctx.db.query("usuarios").collect();

    // Filtrar por matrícula
    if (args.matricula) {
      usuarios = usuarios.filter((u) =>
        u.matricula.includes(args.matricula!)
      );
    }

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

    // Buscar roles e funcionários
    const resultado = [];
    for (const usuario of usuarios) {
      const role = await ctx.db.get(usuario.roleId);
      if (!role) continue;

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

      let funcionario = undefined;
      if (usuario.funcionarioId) {
        const func = await ctx.db.get(usuario.funcionarioId);
        if (func) {
          funcionario = {
            _id: func._id,
            nome: func.nome,
            simboloTipo: func.simboloTipo,
          };
        }
      }

      resultado.push({
        _id: usuario._id,
        matricula: usuario.matricula,
        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: role._id,
          nome: role.nome,
          nivel: role.nivel,
          setor: role.setor,
        },
        funcionario,
      });
    }

    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, avatar, setor, status, preferências)
 */
export const atualizarPerfil = mutation({
  args: {
    avatar: v.optional(v.string()),
    fotoPerfil: v.optional(v.id("_storage")),
    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()),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    // TENTAR BETTER AUTH PRIMEIRO
    const identity = await ctx.auth.getUserIdentity();
    
    let usuarioAtual = null;
    
    if (identity && identity.email) {
      // Buscar por email (Better Auth)
      usuarioAtual = await ctx.db
        .query("usuarios")
        .withIndex("by_email", (q) => q.eq("email", identity.email!))
        .first();
    }
    
    // SE NÃO ENCONTROU, BUSCAR POR SESSÃO ATIVA (Sistema customizado)
    if (!usuarioAtual) {
      const sessaoAtiva = await ctx.db
        .query("sessoes")
        .filter((q) => q.eq(q.field("ativo"), true))
        .order("desc")
        .first();
      
      if (sessaoAtiva) {
        usuarioAtual = await ctx.db.get(sessaoAtiva.usuarioId);
      }
    }

    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: any = { atualizadoEm: Date.now() };
    
    if (args.avatar !== undefined) updates.avatar = args.avatar;
    if (args.fotoPerfil !== undefined) updates.fotoPerfil = args.fotoPerfil;
    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;

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

    return null;
  },
});

/**
 * 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.string(),
      funcionarioId: v.optional(v.id("funcionarios")),
      avatar: v.optional(v.string()),
      fotoPerfil: v.optional(v.id("_storage")),
      fotoPerfilUrl: v.union(v.string(), v.null()),
      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) => {
    console.log("=== DEBUG obterPerfil ===");
    
    // TENTAR BETTER AUTH PRIMEIRO
    const identity = await ctx.auth.getUserIdentity();
    console.log("Identity:", identity ? "encontrado" : "null");
    
    let usuarioAtual = null;
    
    if (identity && identity.email) {
      console.log("Tentando buscar por email:", identity.email);
      // Buscar por email (Better Auth)
      usuarioAtual = await ctx.db
        .query("usuarios")
        .withIndex("by_email", (q) => q.eq("email", identity.email!))
        .first();
      
      console.log("Usuário encontrado por email:", usuarioAtual ? "SIM" : "NÃO");
    }
    
    // SE NÃO ENCONTROU, BUSCAR POR SESSÃO ATIVA (Sistema customizado)
    if (!usuarioAtual) {
      console.log("Buscando por sessão ativa...");
      const sessaoAtiva = await ctx.db
        .query("sessoes")
        .filter((q) => q.eq(q.field("ativo"), true))
        .order("desc")
        .first();
      
      console.log("Sessão ativa encontrada:", sessaoAtiva ? "SIM" : "NÃO");
      
      if (sessaoAtiva) {
        usuarioAtual = await ctx.db.get(sessaoAtiva.usuarioId);
        console.log("Usuário da sessão encontrado:", usuarioAtual ? "SIM" : "NÃO");
      }
    }
    
    if (!usuarioAtual) {
      console.log("❌ Nenhum usuário encontrado");
      // Listar todos os usuários para debug
      const todosUsuarios = await ctx.db.query("usuarios").collect();
      console.log("Total de usuários no banco:", todosUsuarios.length);
      console.log("Emails cadastrados:", todosUsuarios.map(u => u.email));
      return null;
    }
    
    console.log("✅ Usuário encontrado:", usuarioAtual.nome);

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

    return {
      _id: usuarioAtual._id,
      nome: usuarioAtual.nome,
      email: usuarioAtual.email,
      matricula: usuarioAtual.matricula,
      funcionarioId: usuarioAtual.funcionarioId,
      avatar: usuarioAtual.avatar,
      fotoPerfil: usuarioAtual.fotoPerfil,
      fotoPerfilUrl,
      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 avatar, 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()),
      avatar: v.optional(v.string()),
      fotoPerfil: v.optional(v.id("_storage")),
      fotoPerfilUrl: v.union(v.string(), v.null()),
      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) => {
    // Buscar todos os usuários ativos
    const usuarios = await ctx.db
      .query("usuarios")
      .filter((q) => q.eq(q.field("ativo"), true))
      .collect();

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

        return {
          _id: usuario._id,
          nome: usuario.nome,
          email: usuario.email,
          matricula: usuario.matricula || undefined,
          avatar: usuario.avatar,
          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: {},
  handler: async (ctx) => {
    // TENTAR BETTER AUTH PRIMEIRO
    const identity = await ctx.auth.getUserIdentity();
    
    let usuarioAtual = null;
    
    if (identity && identity.email) {
      // Buscar por email (Better Auth)
      usuarioAtual = await ctx.db
        .query("usuarios")
        .withIndex("by_email", (q) => q.eq("email", identity.email!))
        .first();
    }
    
    // SE NÃO ENCONTROU, BUSCAR POR SESSÃO ATIVA (Sistema customizado)
    if (!usuarioAtual) {
      const sessaoAtiva = await ctx.db
        .query("sessoes")
        .filter((q) => q.eq(q.field("ativo"), true))
        .order("desc")
        .first();
      
      if (sessaoAtiva) {
        usuarioAtual = await ctx.db.get(sessaoAtiva.usuarioId);
      }
    }

    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 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 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 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: any = {
      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 };
  },
});

/**
 * Desativar usuário logicamente (soft delete - apenas TI_MASTER)
 */
export const excluirUsuarioLogico = mutation({
  args: {
    usuarioId: v.id("usuarios"),
    excluidoPorId: 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 usuario = await ctx.db.get(args.usuarioId);
    if (!usuario) {
      return { sucesso: false as const, erro: "Usuário não encontrado" };
    }

    // Marcar como inativo
    await ctx.db.patch(args.usuarioId, {
      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.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.excluidoPorId,
      "excluir",
      "usuarios",
      JSON.stringify({ usuarioId: args.usuarioId }),
      args.usuarioId
    );

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

/**
 * Criar usuário completo com permissões (TI_MASTER)
 */
export const criarUsuarioCompleto = mutation({
  args: {
    matricula: v.string(),
    nome: v.string(),
    email: v.string(),
    roleId: v.id("roles"),
    setor: v.optional(v.string()),
    senhaInicial: v.optional(v.string()),
    criadoPorId: v.id("usuarios"),
    enviarEmailBoasVindas: v.optional(v.boolean()),
  },
  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) => {
    // Verificar se matrícula já existe
    const existente = await ctx.db
      .query("usuarios")
      .withIndex("by_matricula", (q) => q.eq("matricula", args.matricula))
      .first();

    if (existente) {
      return { sucesso: false as const, erro: "Matrícula já cadastrada" };
    }

    // 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" };
    }

    // Gerar senha inicial se não fornecida
    const senhaTemporaria = args.senhaInicial || gerarSenhaTemporaria();
    const senhaHash = await hashPassword(senhaTemporaria);

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

    // Log de atividade
    await registrarAtividade(
      ctx,
      args.criadoPorId,
      "criar",
      "usuarios",
      JSON.stringify({ usuarioId, matricula: args.matricula, nome: args.nome }),
      usuarioId
    );

    // TODO: Se enviarEmailBoasVindas = true, enfileirar email
    // Isso será implementado quando criarmos o sistema de emails

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

