import { randomUUID } from "node:crypto";

import { after } from "next/server";

import { tentativaPermitida } from "@/lib/limite-de-tentativas";
import { ehDaEquipe, textoDaMensagem } from "@/lib/live/regras";
import { lerCorpo, rotaDeQuemEsta } from "@/lib/live/servidor/rota";
import { ErroDaLive, mensagemParaTela } from "@/lib/live/servidor/sala";
import { avisarSala } from "@/lib/live/sinal";

export const runtime = "nodejs";

/*
 * Mandar no bate-papo. Bate-papo desligado: só quem apresenta escreve (avisos).
 * Modo "só perguntas": a mensagem de quem participa vira pergunta e não vai para a
 * sala; quem apresenta vê pelo sinal de vida e responde para todos.
 */
export async function POST(req: Request, { params }: { params: Promise<{ salaId: string }> }) {
  const { salaId } = await params;
  return rotaDeQuemEsta(req, salaId, async ({ admin, sala, eu }) => {
    const corpo = await lerCorpo(req);
    const texto = textoDaMensagem(corpo.texto);
    if (!texto) throw new ErroDaLive("Escreva alguma coisa.", 400);
    const equipe = ehDaEquipe(eu.papel);
    if (!equipe && sala.chat === "desligado") throw new ErroDaLive("O bate-papo desta live está fechado.", 403);
    if (sala.status === "encerrada" || sala.status === "cancelada") throw new ErroDaLive("A live terminou.", 410);
    if (!equipe && !tentativaPermitida(`live-msg:${eu.id}`, 6, 15)) {
      throw new ErroDaLive("Calma! Espere uns segundos para mandar outra.", 429);
    }
    const pergunta = !equipe && (sala.chat === "perguntas" || corpo.pergunta === true);
    /*
     * A mensagem sai para a sala antes de ser gravada (o banco fica longe e
     * cada ida conta): o id e a hora nascem aqui e a gravação termina logo
     * depois da resposta. Se a gravação falhar, quem recarregar não a vê.
     */
    const linha = {
      id: randomUUID(),
      sala_id: sala.id,
      participante_id: eu.id,
      nome: eu.nome,
      papel: eu.papel,
      foto: eu.foto,
      texto,
      pergunta,
      criado_em: new Date().toISOString(),
    };
    after(async () => {
      const { error } = await admin.from("live_mensagens").insert(linha);
      if (error) console.error("[live] mensagem não foi gravada", error.message);
    });
    const msg = mensagemParaTela(linha);
    /* Pergunta no modo "só perguntas" fica entre quem perguntou e quem apresenta. */
    if (!(pergunta && sala.chat === "perguntas")) await avisarSala(admin, { id: sala.id, canal: sala.canal }, [{ t: "msg", msg }]);
    return { msg };
  });
}
