import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
import type { MutationCtx } from "./_generated/server";
import { api } from "./_generated/api";
import { getCurrentUserFunction } from "./auth";
import type { Doc, Id } from "./_generated/dataModel";

const ticketStatusValidator = v.union(
  v.literal("aberto"),
  v.literal("em_andamento"),
  v.literal("aguardando_usuario"),
  v.literal("resolvido"),
  v.literal("encerrado"),
  v.literal("cancelado")
);

const ticketTipoValidator = v.union(
  v.literal("reclamacao"),
  v.literal("elogio"),
  v.literal("sugestao"),
  v.literal("chamado")
);

const prioridadeValidator = v.union(
  v.literal("baixa"),
  v.literal("media"),
  v.literal("alta"),
  v.literal("critica")
);

const arquivoValidator = v.object({
  arquivoId: v.id("_storage"),
  nome: v.optional(v.string()),
  tipo: v.optional(v.string()),
  tamanho: v.optional(v.number()),
});

async function assertAuth(ctx: Parameters<typeof getCurrentUserFunction>[0]) {
  const usuario = await getCurrentUserFunction(ctx);
  if (!usuario) {
    throw new Error("Usuário não autenticado");
  }
  return usuario;
}

type TicketDoc = Doc<"tickets">;
type SlaDoc = Doc<"slaConfigs"> | null;

function gerarNumeroTicket(): string {
  const agora = new Date();
  const ano = agora.getFullYear();
  const mes = String(agora.getMonth() + 1).padStart(2, "0");
  const sequencia = Math.floor(Math.random() * 9000 + 1000);
  return `SGSE-${ano}${mes}-${sequencia}`;
}

function calcularPrazos(base: number, sla: SlaDoc) {
  const horaMs = 60 * 60 * 1000;

  const tempoResposta = sla?.tempoRespostaHoras ?? 4;
  const tempoConclusao = sla?.tempoConclusaoHoras ?? 24;
  const tempoEncerramento = sla?.tempoEncerramentoHoras ?? null;

  return {
    resposta: base + tempoResposta * horaMs,
    conclusao: base + tempoConclusao * horaMs,
    encerramento: tempoEncerramento ? base + tempoEncerramento * horaMs : null,
  };
}

function montarTimeline(base: number, prazos: ReturnType<typeof calcularPrazos>) {
  const timeline: NonNullable<TicketDoc["timeline"]> = [
    {
      etapa: "abertura",
      status: "concluido",
      prazo: base,
      concluidoEm: base,
      observacao: "Chamado registrado com sucesso",
    },
    {
      etapa: "resposta_inicial",
      status: "pendente",
      prazo: prazos.resposta,
    },
    {
      etapa: "conclusao",
      status: "pendente",
      prazo: prazos.conclusao,
    },
  ];

  if (prazos.encerramento) {
    timeline.push({
      etapa: "encerramento",
      status: "pendente",
      prazo: prazos.encerramento,
    });
  }

  return timeline;
}

async function selecionarSlaConfig(
  ctx: Parameters<typeof getCurrentUserFunction>[0],
  prioridade: "baixa" | "media" | "alta" | "critica"
): Promise<Doc<"slaConfigs"> | null> {
  return await ctx.db
    .query("slaConfigs")
    .withIndex("by_prioridade", (q) => q.eq("prioridade", prioridade).eq("ativo", true))
    .first();
}

async function registrarNotificacoes(
  ctx: MutationCtx,
  params: {
    ticket: Doc<"tickets">;
    titulo: string;
    mensagem: string;
    usuarioEvento: Id<"usuarios">;
  }
) {
  const { ticket, titulo, mensagem, usuarioEvento } = params;

  // Notificar solicitante
  if (ticket.solicitanteEmail) {
    await ctx.runMutation(api.email.enfileirarEmail, {
      destinatario: ticket.solicitanteEmail,
      destinatarioId: ticket.solicitanteId,
      assunto: `${titulo} - Chamado ${ticket.numero}`,
      corpo: `${mensagem}\n\n---\nCentral de Chamados SGSE - Sistema de Gerenciamento de Secretaria`,
      enviadoPor: usuarioEvento,
    });
  }

  await ctx.db.insert("notificacoes", {
    usuarioId: ticket.solicitanteId,
    tipo: "nova_mensagem",
    ...(ticket.conversaId ? { conversaId: ticket.conversaId } : {}),
    remetenteId: usuarioEvento,
    titulo,
    descricao: mensagem.length > 120 ? `${mensagem.slice(0, 117)}...` : mensagem,
    lida: false,
    criadaEm: Date.now(),
  });

  // Notificar responsável (se houver)
  if (ticket.responsavelId && ticket.responsavelId !== ticket.solicitanteId) {
    const responsavel = await ctx.db.get(ticket.responsavelId);
    if (responsavel?.email) {
      await ctx.runMutation(api.email.enfileirarEmail, {
        destinatario: responsavel.email,
        destinatarioId: ticket.responsavelId,
        assunto: `${titulo} - Chamado ${ticket.numero}`,
        corpo: `${mensagem}\n\n---\nCentral de Chamados SGSE - Sistema de Gerenciamento de Secretaria`,
        enviadoPor: usuarioEvento,
      });
    }

    await ctx.db.insert("notificacoes", {
      usuarioId: ticket.responsavelId,
      tipo: "nova_mensagem",
      ...(ticket.conversaId ? { conversaId: ticket.conversaId } : {}),
      remetenteId: usuarioEvento,
      titulo,
      descricao: mensagem.length > 120 ? `${mensagem.slice(0, 117)}...` : mensagem,
      lida: false,
      criadaEm: Date.now(),
    });
  }
}

async function registrarInteracao(
  ctx: MutationCtx,
  params: {
    ticketId: Id<"tickets">;
    autorId: Id<"usuarios"> | null;
    origem: "usuario" | "ti" | "sistema";
    tipo: "mensagem" | "status" | "anexo" | "alerta";
    conteudo: string;
    visibilidade?: "publico" | "interno";
    anexos?: Array<{
      arquivoId: Id<"_storage">;
      nome?: string;
      tipo?: string;
      tamanho?: number;
    }>;
    statusAnterior?: TicketDoc["status"];
    statusNovo?: TicketDoc["status"];
  }
) {
  return await ctx.db.insert("ticketInteractions", {
    ticketId: params.ticketId,
    autorId: params.autorId || undefined,
    origem: params.origem,
    tipo: params.tipo,
    conteudo: params.conteudo,
    visibilidade: params.visibilidade ?? "publico",
    anexos: params.anexos,
    statusAnterior: params.statusAnterior,
    statusNovo: params.statusNovo,
    criadoEm: Date.now(),
  });
}

export const abrirChamado = mutation({
  args: {
    titulo: v.string(),
    descricao: v.string(),
    tipo: ticketTipoValidator,
    categoria: v.optional(v.string()),
    prioridade: prioridadeValidator,
    anexos: v.optional(v.array(arquivoValidator)),
    canalOrigem: v.optional(v.string()),
  },
  returns: v.object({
    ticketId: v.id("tickets"),
    numero: v.string(),
  }),
  handler: async (ctx, args) => {
    const usuario = await assertAuth(ctx);
    const agora = Date.now();
    const sla = await selecionarSlaConfig(ctx, args.prioridade);
    const prazos = calcularPrazos(agora, sla);
    const timeline = montarTimeline(agora, prazos);

    const ticketId = await ctx.db.insert("tickets", {
      numero: gerarNumeroTicket(),
      titulo: args.titulo.trim(),
      descricao: args.descricao.trim(),
      tipo: args.tipo,
      categoria: args.categoria,
      status: "aberto",
      prioridade: args.prioridade,
      solicitanteId: usuario._id,
      solicitanteNome: usuario.nome,
      solicitanteEmail: usuario.email,
      responsavelId: undefined,
      setorResponsavel: undefined,
      slaConfigId: sla?._id,
      conversaId: undefined,
      prazoResposta: prazos.resposta,
      prazoConclusao: prazos.conclusao,
      prazoEncerramento: prazos.encerramento ?? undefined,
      timeline,
      alertasEmitidos: [],
      anexos: args.anexos,
      tags: undefined,
      canalOrigem: args.canalOrigem,
      ultimaInteracaoEm: agora,
      criadoEm: agora,
      atualizadoEm: agora,
    });

    await registrarInteracao(ctx, {
      ticketId,
      autorId: usuario._id,
      origem: "usuario",
      tipo: "mensagem",
      conteudo: args.descricao,
      anexos: args.anexos,
    });

    const ticket = await ctx.db.get(ticketId);
    if (ticket) {
      await registrarNotificacoes(ctx, {
        ticket,
        titulo: "Chamado registrado",
        mensagem: "Recebemos sua solicitação e iniciaremos o atendimento em breve.",
        usuarioEvento: usuario._id,
      });
    }

    return {
      ticketId,
      numero: ticket ? ticket.numero : "",
    };
  },
});

export const listarChamadosUsuario = query({
  args: {},
  handler: async (ctx) => {
    const usuario = await assertAuth(ctx);

    const tickets = await ctx.db
      .query("tickets")
      .withIndex("by_solicitante", (q) => q.eq("solicitanteId", usuario._id))
      .collect();

    tickets.sort((a, b) => b.criadoEm - a.criadoEm);
    return tickets;
  },
});

export const listarChamadosTI = query({
  args: {
    status: v.optional(ticketStatusValidator),
    responsavelId: v.optional(v.id("usuarios")),
    setor: v.optional(v.string()),
    limite: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    // Permitir apenas usuários autenticados (regras detalhadas devem ser aplicadas no frontend)
    await assertAuth(ctx);

    let tickets: Array<Doc<"tickets">> = [];

    if (args.responsavelId) {
      tickets = await ctx.db
        .query("tickets")
        .withIndex("by_responsavel", (q) =>
          q.eq("responsavelId", args.responsavelId).eq("status", args.status ?? "aberto")
        )
        .collect();
    } else if (args.status) {
      tickets = await ctx.db
        .query("tickets")
        .withIndex("by_status", (q) => q.eq("status", args.status!))
        .collect();
    } else {
      tickets = await ctx.db.query("tickets").collect();
    }

    const filtrados = tickets.filter((ticket) => {
      if (args.setor && ticket.setorResponsavel !== args.setor) {
        return false;
      }
      return true;
    });

    // Enriquecer tickets com nome do responsável
    const ticketsEnriquecidos = await Promise.all(
      filtrados.map(async (ticket) => {
        let responsavelNome: string | undefined = undefined;
        if (ticket.responsavelId) {
          const responsavel = await ctx.db.get(ticket.responsavelId);
          responsavelNome = responsavel?.nome;
        }
        return {
          ...ticket,
          responsavelNome,
        };
      })
    );

    ticketsEnriquecidos.sort((a, b) => b.atualizadoEm - a.atualizadoEm);
    return args.limite ? ticketsEnriquecidos.slice(0, args.limite) : ticketsEnriquecidos;
  },
});

export const obterChamado = query({
  args: {
    ticketId: v.id("tickets"),
  },
  handler: async (ctx, args) => {
    const usuario = await assertAuth(ctx);
    const ticket = await ctx.db.get(args.ticketId);
    if (!ticket) {
      throw new Error("Chamado não encontrado");
    }

    const podeVer =
      ticket.solicitanteId === usuario._id ||
      ticket.responsavelId === usuario._id ||
      ticket.setorResponsavel === usuario.setor;

    if (!podeVer) {
      throw new Error("Acesso negado ao chamado");
    }

    const interactions = await ctx.db
      .query("ticketInteractions")
      .withIndex("by_ticket", (q) => q.eq("ticketId", args.ticketId))
      .collect();

    interactions.sort((a, b) => a.criadoEm - b.criadoEm);

    return {
      ticket,
      interactions,
    };
  },
});

export const registrarAtualizacao = mutation({
  args: {
    ticketId: v.id("tickets"),
    conteudo: v.string(),
    anexos: v.optional(v.array(arquivoValidator)),
    visibilidade: v.optional(v.union(v.literal("publico"), v.literal("interno"))),
    proximoStatus: v.optional(ticketStatusValidator),
  },
  handler: async (ctx, args) => {
    const usuario = await assertAuth(ctx);
    const ticket = await ctx.db.get(args.ticketId);
    if (!ticket) {
      throw new Error("Chamado não encontrado");
    }

    const agora = Date.now();
    let novoStatus = ticket.status;

    if (args.proximoStatus && args.proximoStatus !== ticket.status) {
      novoStatus = args.proximoStatus;
      await ctx.db.patch(ticket._id, {
        status: novoStatus,
        atualizadoEm: agora,
        ultimaInteracaoEm: agora,
      });
    } else {
      await ctx.db.patch(ticket._id, {
        atualizadoEm: agora,
        ultimaInteracaoEm: agora,
      });
    }

    await registrarInteracao(ctx, {
      ticketId: ticket._id,
      autorId: usuario._id,
      origem: "ti",
      tipo: args.proximoStatus ? "status" : "mensagem",
      conteudo: args.conteudo,
      visibilidade: args.visibilidade,
      anexos: args.anexos,
      statusAnterior: args.proximoStatus ? ticket.status : undefined,
      statusNovo: args.proximoStatus ? novoStatus : undefined,
    });

    const ticketAtualizado = await ctx.db.get(ticket._id);
    if (ticketAtualizado) {
      await registrarNotificacoes(ctx, {
        ticket: ticketAtualizado,
        titulo: `Atualização no chamado ${ticketAtualizado.numero}`,
        mensagem: args.conteudo,
        usuarioEvento: usuario._id,
      });
    }

    return { status: novoStatus };
  },
});

export const atribuirResponsavel = mutation({
  args: {
    ticketId: v.id("tickets"),
    responsavelId: v.id("usuarios"),
    motivo: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const usuario = await assertAuth(ctx);
    const ticket = await ctx.db.get(args.ticketId);
    if (!ticket) {
      throw new Error("Chamado não encontrado");
    }

    const responsavel = await ctx.db.get(args.responsavelId);
    if (!responsavel) {
      throw new Error("Responsável inválido");
    }

    const agora = Date.now();

    await ctx.db.patch(ticket._id, {
      responsavelId: args.responsavelId,
      setorResponsavel: responsavel.setor,
      atualizadoEm: agora,
    });

    const assignmentsAtivos = await ctx.db
      .query("ticketAssignments")
      .withIndex("by_ticket", (q) => q.eq("ticketId", ticket._id).eq("ativo", true))
      .collect();

    for (const assignment of assignmentsAtivos) {
      await ctx.db.patch(assignment._id, {
        ativo: false,
        encerradoEm: agora,
      });
    }

    await ctx.db.insert("ticketAssignments", {
      ticketId: ticket._id,
      responsavelId: args.responsavelId,
      atribuidoPor: usuario._id,
      motivo: args.motivo,
      ativo: true,
      criadoEm: agora,
      encerradoEm: undefined,
    });

    await registrarInteracao(ctx, {
      ticketId: ticket._id,
      autorId: usuario._id,
      origem: "ti",
      tipo: "status",
      conteudo: `Chamado atribuído para ${responsavel.nome}`,
    });

    const ticketAtualizado = await ctx.db.get(ticket._id);
    if (ticketAtualizado) {
      await registrarNotificacoes(ctx, {
        ticket: ticketAtualizado,
        titulo: "Chamado atribuído",
        mensagem: `Seu chamado agora está com ${responsavel.nome}.`,
        usuarioEvento: usuario._id,
      });
    }

    return { responsavelId: args.responsavelId };
  },
});

export const listarSlaConfigs = query({
  args: {},
  handler: async (ctx) => {
    await assertAuth(ctx);
    const slaConfigs = await ctx.db.query("slaConfigs").collect();
    slaConfigs.sort((a, b) => b.criadoEm - a.criadoEm);
    return slaConfigs;
  },
});

export const obterEstatisticasChamados = query({
  args: {},
  handler: async (ctx) => {
    await assertAuth(ctx);
    const todosTickets = await ctx.db.query("tickets").collect();
    
    const total = todosTickets.length;
    const abertos = todosTickets.filter((t) => t.status === "aberto").length;
    const emAndamento = todosTickets.filter((t) => t.status === "em_andamento").length;
    const vencidos = todosTickets.filter(
      (t) => (t.prazoConclusao && t.prazoConclusao < Date.now()) || t.status === "cancelado"
    ).length;
    
    return { total, abertos, emAndamento, vencidos };
  },
});

export const obterDadosSlaGrafico = query({
  args: {},
  handler: async (ctx) => {
    await assertAuth(ctx);
    const agora = Date.now();
    const todosTickets = await ctx.db.query("tickets").collect();
    const slaConfigs = await ctx.db.query("slaConfigs").collect();
    
    // Agrupar SLAs por prioridade
    const slaPorPrioridade = new Map<string, Doc<"slaConfigs">>();
    slaConfigs.filter(s => s.ativo).forEach(sla => {
      if (sla.prioridade) {
        slaPorPrioridade.set(sla.prioridade, sla);
      }
    });
    
    // Calcular status de SLA para cada ticket
    const statusSla = {
      dentroPrazo: 0,
      proximoVencimento: 0,
      vencido: 0,
      semPrazo: 0,
    };
    
    const porPrioridade = {
      baixa: { dentroPrazo: 0, proximoVencimento: 0, vencido: 0, total: 0 },
      media: { dentroPrazo: 0, proximoVencimento: 0, vencido: 0, total: 0 },
      alta: { dentroPrazo: 0, proximoVencimento: 0, vencido: 0, total: 0 },
      critica: { dentroPrazo: 0, proximoVencimento: 0, vencido: 0, total: 0 },
    };
    
    todosTickets.forEach(ticket => {
      if (!ticket.prazoConclusao) {
        statusSla.semPrazo++;
        return;
      }
      
      const prazoConclusao = ticket.prazoConclusao;
      const horasRestantes = (prazoConclusao - agora) / (1000 * 60 * 60);
      const sla = slaPorPrioridade.get(ticket.prioridade);
      const alertaHoras = sla?.alertaAntecedenciaHoras ?? 2;
      
      if (prazoConclusao < agora) {
        statusSla.vencido++;
        if (ticket.prioridade && porPrioridade[ticket.prioridade as keyof typeof porPrioridade]) {
          porPrioridade[ticket.prioridade as keyof typeof porPrioridade].vencido++;
          porPrioridade[ticket.prioridade as keyof typeof porPrioridade].total++;
        }
      } else if (horasRestantes <= alertaHoras) {
        statusSla.proximoVencimento++;
        if (ticket.prioridade && porPrioridade[ticket.prioridade as keyof typeof porPrioridade]) {
          porPrioridade[ticket.prioridade as keyof typeof porPrioridade].proximoVencimento++;
          porPrioridade[ticket.prioridade as keyof typeof porPrioridade].total++;
        }
      } else {
        statusSla.dentroPrazo++;
        if (ticket.prioridade && porPrioridade[ticket.prioridade as keyof typeof porPrioridade]) {
          porPrioridade[ticket.prioridade as keyof typeof porPrioridade].dentroPrazo++;
          porPrioridade[ticket.prioridade as keyof typeof porPrioridade].total++;
        }
      }
    });
    
    // Calcular taxa de cumprimento
    const totalComPrazo = statusSla.dentroPrazo + statusSla.proximoVencimento + statusSla.vencido;
    const taxaCumprimento = totalComPrazo > 0 
      ? Math.round((statusSla.dentroPrazo / totalComPrazo) * 100) 
      : 100;
    
    return {
      statusSla,
      porPrioridade,
      taxaCumprimento,
      totalComPrazo,
      atualizadoEm: agora,
    };
  },
});

export const salvarSlaConfig = mutation({
  args: {
    slaId: v.optional(v.id("slaConfigs")),
    nome: v.string(),
    descricao: v.optional(v.string()),
    prioridade: prioridadeValidator,
    tempoRespostaHoras: v.number(),
    tempoConclusaoHoras: v.number(),
    tempoEncerramentoHoras: v.optional(v.number()),
    alertaAntecedenciaHoras: v.number(),
    ativo: v.boolean(),
  },
  handler: async (ctx, args) => {
    const usuario = await assertAuth(ctx);
    const agora = Date.now();

    if (args.slaId) {
      await ctx.db.patch(args.slaId, {
        nome: args.nome,
        descricao: args.descricao,
        prioridade: args.prioridade,
        tempoRespostaHoras: args.tempoRespostaHoras,
        tempoConclusaoHoras: args.tempoConclusaoHoras,
        tempoEncerramentoHoras: args.tempoEncerramentoHoras,
        alertaAntecedenciaHoras: args.alertaAntecedenciaHoras,
        ativo: args.ativo,
        atualizadoPor: usuario._id,
        atualizadoEm: agora,
      });
      return args.slaId;
    }

    return await ctx.db.insert("slaConfigs", {
      nome: args.nome,
      descricao: args.descricao,
      prioridade: args.prioridade,
      tempoRespostaHoras: args.tempoRespostaHoras,
      tempoConclusaoHoras: args.tempoConclusaoHoras,
      tempoEncerramentoHoras: args.tempoEncerramentoHoras,
      alertaAntecedenciaHoras: args.alertaAntecedenciaHoras,
      ativo: args.ativo,
      criadoPor: usuario._id,
      atualizadoPor: usuario._id,
      criadoEm: agora,
      atualizadoEm: agora,
    });
  },
});

export const excluirSlaConfig = mutation({
  args: {
    slaId: v.id("slaConfigs"),
  },
  handler: async (ctx, args) => {
    await assertAuth(ctx);
    const sla = await ctx.db.get(args.slaId);
    if (!sla) {
      throw new Error("Configuração de SLA não encontrada");
    }
    await ctx.db.delete(args.slaId);
    return { sucesso: true };
  },
});

export const prorrogarChamado = mutation({
  args: {
    ticketId: v.id("tickets"),
    horasAdicionais: v.number(),
    prazo: v.union(v.literal("resposta"), v.literal("conclusao")),
    motivo: v.string(),
  },
  handler: async (ctx, args) => {
    const usuario = await assertAuth(ctx);
    const ticket = await ctx.db.get(args.ticketId);
    if (!ticket) {
      throw new Error("Chamado não encontrado");
    }

    const agora = Date.now();
    const horasMs = args.horasAdicionais * 60 * 60 * 1000;
    let novoPrazoResposta = ticket.prazoResposta;
    let novoPrazoConclusao = ticket.prazoConclusao;
    let prazoExtendido: number;

    if (args.prazo === "resposta") {
      prazoExtendido = (ticket.prazoResposta || agora) + horasMs;
      novoPrazoResposta = prazoExtendido;
      // Se o prazo de conclusão é antes do novo prazo de resposta, ajuste-o também
      if (ticket.prazoConclusao && ticket.prazoConclusao < prazoExtendido) {
        novoPrazoConclusao = prazoExtendido + (ticket.prazoConclusao - (ticket.prazoResposta || agora));
      }
    } else {
      prazoExtendido = (ticket.prazoConclusao || agora) + horasMs;
      novoPrazoConclusao = prazoExtendido;
    }

    // Atualizar timeline
    const timelineAtualizada = ticket.timeline?.map((etapa) => {
      if (args.prazo === "resposta" && etapa.etapa === "resposta_inicial") {
        return {
          ...etapa,
          prazo: prazoExtendido,
          status: prazoExtendido > agora ? "pendente" : etapa.status,
        };
      }
      if (args.prazo === "conclusao" && etapa.etapa === "conclusao") {
        return {
          ...etapa,
          prazo: prazoExtendido,
          status: prazoExtendido > agora ? "pendente" : etapa.status,
        };
      }
      return etapa;
    }) || ticket.timeline;

    await ctx.db.patch(ticket._id, {
      prazoResposta: novoPrazoResposta,
      prazoConclusao: novoPrazoConclusao,
      timeline: timelineAtualizada,
      atualizadoEm: agora,
      ultimaInteracaoEm: agora,
    });

    await registrarInteracao(ctx, {
      ticketId: ticket._id,
      autorId: usuario._id,
      origem: "ti",
      tipo: "status",
      conteudo: `Prazo ${args.prazo === "resposta" ? "de resposta" : "de conclusão"} prorrogado em ${args.horasAdicionais}h. Motivo: ${args.motivo}`,
    });

    const ticketAtualizado = await ctx.db.get(ticket._id);
    if (ticketAtualizado) {
      await registrarNotificacoes(ctx, {
        ticket: ticketAtualizado,
        titulo: `Prazo prorrogado - Chamado ${ticketAtualizado.numero}`,
        mensagem: `O prazo ${args.prazo === "resposta" ? "de resposta" : "de conclusão"} foi prorrogado em ${args.horasAdicionais} horas. Motivo: ${args.motivo}`,
        usuarioEvento: usuario._id,
      });
    }

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

export const emitirAlertaPrazo = mutation({
  args: {
    ticketId: v.id("tickets"),
    tipo: v.union(
      v.literal("resposta"),
      v.literal("conclusao"),
      v.literal("encerramento")
    ),
    mensagem: v.string(),
  },
  handler: async (ctx, args) => {
    const usuario = await assertAuth(ctx);
    const ticket = await ctx.db.get(args.ticketId);
    if (!ticket) {
      throw new Error("Chamado não encontrado");
    }

    const atualizado = [
      ...(ticket.alertasEmitidos || []),
      { tipo: args.tipo, emitidoEm: Date.now() },
    ];

    await ctx.db.patch(ticket._id, {
      alertasEmitidos: atualizado,
    });

    await registrarInteracao(ctx, {
      ticketId: ticket._id,
      autorId: usuario._id,
      origem: "sistema",
      tipo: "alerta",
      conteudo: args.mensagem,
    });

    await registrarNotificacoes(ctx, {
      ticket,
      titulo: `Alerta de SLA (${args.tipo})`,
      mensagem: args.mensagem,
      usuarioEvento: usuario._id,
    });

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

export const generateUploadUrl = mutation({
  args: {},
  handler: async (ctx) => {
    await assertAuth(ctx);
    return await ctx.storage.generateUploadUrl();
  },
});

