import { v } from "convex/values";
import { query, mutation } from "./_generated/server";
import { simboloTipo } from "./schema";

export const getAll = query({
  args: {},
  returns: v.array(
    v.object({
      _id: v.id("simbolos"),
      _creationTime: v.number(),
      nome: v.string(),
      tipo: simboloTipo,
      descricao: v.string(),
      vencValor: v.string(),
      repValor: v.string(),
      valor: v.string(),
    })
  ),
  handler: async (ctx) => {
    return await ctx.db.query("simbolos").collect();
  },
});

export const getById = query({
  args: {
    id: v.id("simbolos"),
  },
  returns: v.union(
    v.object({
      _id: v.id("simbolos"),
      _creationTime: v.number(),
      nome: v.string(),
      tipo: simboloTipo,
      descricao: v.string(),
      vencValor: v.string(),
      repValor: v.string(),
      valor: v.string(),
    }),
    v.null()
  ),
  handler: async (ctx, args) => {
    return await ctx.db.get(args.id);
  },
});

export const create = mutation({
  args: {
    nome: v.string(),
    tipo: simboloTipo,
    refValor: v.string(),
    vencValor: v.string(),
    descricao: v.string(),
    valor: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    let refValor = args.refValor;
    let vencValor = args.vencValor;
    let valor = args.valor ?? "";

    if (args.tipo === "cargo_comissionado") {
      if (!refValor || !vencValor) {
        throw new Error(
          "Valor de referência e valor de vencimento são obrigatórios para cargo comissionado"
        );
      }
      valor = (Number(refValor) + Number(vencValor)).toFixed(2);
    } else {
      if (!args.valor) {
        throw new Error("Valor é obrigatório para função gratificada");
      }
      refValor = "";
      vencValor = "";
      valor = args.valor;
    }
    const novoSimboloId = await ctx.db.insert("simbolos", {
      nome: args.nome,
      descricao: args.descricao,
      repValor: refValor,
      vencValor: vencValor,
      tipo: args.tipo,
      valor,
    });
    return await ctx.db.get(novoSimboloId);
  },
});

export const remove = mutation({
  args: {
    id: v.id("simbolos"),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    await ctx.db.delete(args.id);
    return null;
  },
});

export const update = mutation({
  args: {
    id: v.id("simbolos"),
    nome: v.string(),
    tipo: simboloTipo,
    refValor: v.string(),
    vencValor: v.string(),
    descricao: v.string(),
    valor: v.optional(v.string()),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    let refValor = args.refValor;
    let vencValor = args.vencValor;
    let valor = args.valor ?? "";

    if (args.tipo === "cargo_comissionado") {
      if (!refValor || !vencValor) {
        throw new Error(
          "Valor de referência e valor de vencimento são obrigatórios para cargo comissionado"
        );
      }
      valor = (Number(refValor) + Number(vencValor)).toFixed(2);
    } else {
      if (!args.valor) {
        throw new Error("Valor é obrigatório para função gratificada");
      }
      refValor = "";
      vencValor = "";
      valor = args.valor;
    }

    await ctx.db.patch(args.id, {
      nome: args.nome,
      descricao: args.descricao,
      repValor: refValor,
      vencValor: vencValor,
      tipo: args.tipo,
      valor,
    });
    return null;
  },
});

/**
 * Remove símbolos duplicados, mantendo apenas a primeira ocorrência de cada símbolo
 */
export const removerDuplicados = mutation({
  args: {},
  returns: v.object({
    removidos: v.number(),
    mantidos: v.number(),
  }),
  handler: async (ctx) => {
    const todosSimbolos = await ctx.db.query("simbolos").collect();
    
    // Agrupar símbolos por nome
    const simbolosPorNome = new Map<string, typeof todosSimbolos>();
    
    for (const simbolo of todosSimbolos) {
      const key = simbolo.nome.trim().toLowerCase();
      if (!simbolosPorNome.has(key)) {
        simbolosPorNome.set(key, []);
      }
      simbolosPorNome.get(key)!.push(simbolo);
    }
    
    let removidos = 0;
    let mantidos = 0;
    
    // Para cada grupo de símbolos com o mesmo nome
    for (const [nome, simbolos] of simbolosPorNome) {
      // Ordenar por _creationTime (mais antigo primeiro)
      simbolos.sort((a, b) => a._creationTime - b._creationTime);
      
      // Manter o primeiro (mais antigo) e remover os demais
      const [primeiro, ...duplicados] = simbolos;
      mantidos++;
      
      // Remover duplicados
      for (const duplicado of duplicados) {
        await ctx.db.delete(duplicado._id);
        removidos++;
      }
    }
    
    console.log(`✅ Remoção concluída: ${mantidos} símbolos mantidos, ${removidos} duplicados removidos`);
    
    return { removidos, mantidos };
  },
});