import { internalMutation } from "./_generated/server";
import { v } from "convex/values";

/**
 * Migração: Converte estrutura antiga de gestores individuais para times
 * 
 * Esta função cria automaticamente times baseados nos gestores existentes
 * e adiciona os funcionários subordinados aos respectivos times.
 * 
 * Execute uma vez via dashboard do Convex: 
 * Settings > Functions > Internal > migrarParaTimes > executar
 */
export const executar = internalMutation({
  args: {},
  returns: v.object({
    timesCreated: v.number(),
    funcionariosAtribuidos: v.number(),
    erros: v.array(v.string()),
  }),
  handler: async (ctx) => {
    const erros: string[] = [];
    let timesCreated = 0;
    let funcionariosAtribuidos = 0;

    try {
      // 1. Buscar todos os funcionários que têm gestor definido
      const funcionariosComGestor = await ctx.db
        .query("funcionarios")
        .filter((q) => q.neq(q.field("gestorId"), undefined))
        .collect();

      if (funcionariosComGestor.length === 0) {
        return {
          timesCreated: 0,
          funcionariosAtribuidos: 0,
          erros: ["Nenhum funcionário com gestor configurado encontrado"],
        };
      }

      // 2. Agrupar funcionários por gestor
      const gestoresMap = new Map<string, any[]>();
      
      for (const funcionario of funcionariosComGestor) {
        if (!funcionario.gestorId) continue;
        
        const gestorId = funcionario.gestorId;
        if (!gestoresMap.has(gestorId)) {
          gestoresMap.set(gestorId, []);
        }
        gestoresMap.get(gestorId)!.push(funcionario);
      }

      // 3. Para cada gestor, criar um time
      for (const [gestorId, subordinados] of gestoresMap.entries()) {
        try {
          const gestor = await ctx.db.get(gestorId as any);
          
          if (!gestor) {
            erros.push(`Gestor ${gestorId} não encontrado`);
            continue;
          }

          // Verificar se já existe time para este gestor
          const timeExistente = await ctx.db
            .query("times")
            .withIndex("by_gestor", (q) => q.eq("gestorId", gestorId as any))
            .filter((q) => q.eq(q.field("ativo"), true))
            .first();

          let timeId;
          
          if (timeExistente) {
            timeId = timeExistente._id;
          } else {
            // Criar novo time
            timeId = await ctx.db.insert("times", {
              nome: `Equipe ${gestor.nome}`,
              descricao: `Time gerenciado por ${gestor.nome} (migração automática)`,
              gestorId: gestorId as any,
              ativo: true,
              cor: "#3B82F6",
            });
            timesCreated++;
          }

          // Adicionar membros ao time
          for (const funcionario of subordinados) {
            try {
              // Verificar se já está em algum time
              const membroExistente = await ctx.db
                .query("timesMembros")
                .withIndex("by_funcionario", (q) => q.eq("funcionarioId", funcionario._id))
                .filter((q) => q.eq(q.field("ativo"), true))
                .first();

              if (!membroExistente) {
                await ctx.db.insert("timesMembros", {
                  timeId: timeId,
                  funcionarioId: funcionario._id,
                  dataEntrada: Date.now(),
                  ativo: true,
                });
                funcionariosAtribuidos++;
              }
            } catch (e: any) {
              erros.push(`Erro ao adicionar ${funcionario.nome} ao time: ${e.message}`);
            }
          }
        } catch (e: any) {
          erros.push(`Erro ao processar gestor ${gestorId}: ${e.message}`);
        }
      }

      return {
        timesCreated,
        funcionariosAtribuidos,
        erros,
      };
    } catch (e: any) {
      erros.push(`Erro geral na migração: ${e.message}`);
      return {
        timesCreated,
        funcionariosAtribuidos,
        erros,
      };
    }
  },
});

/**
 * Função auxiliar para limpar times inativos antigos
 */
export const limparTimesInativos = internalMutation({
  args: {
    diasInativos: v.optional(v.number()),
  },
  returns: v.number(),
  handler: async (ctx, args) => {
    const diasLimite = args.diasInativos || 30;
    const dataLimite = Date.now() - (diasLimite * 24 * 60 * 60 * 1000);
    
    const timesInativos = await ctx.db
      .query("times")
      .filter((q) => q.eq(q.field("ativo"), false))
      .collect();
    
    let removidos = 0;
    
    for (const time of timesInativos) {
      if (time._creationTime < dataLimite) {
        // Remover membros inativos do time
        const membrosInativos = await ctx.db
          .query("timesMembros")
          .withIndex("by_time", (q) => q.eq("timeId", time._id))
          .filter((q) => q.eq(q.field("ativo"), false))
          .collect();
        
        for (const membro of membrosInativos) {
          await ctx.db.delete(membro._id);
        }
        
        // Remover o time
        await ctx.db.delete(time._id);
        removidos++;
      }
    }
    
    return removidos;
  },
});

