import assert from "node:assert/strict";
import { test } from "node:test";

import { ErroNosDados, horarioDeBrasilia, lerDadosDaLive, lerItem, paraOsCampos, pessoasDoGratis, salaParaOBanco, semLimiteDePessoas, situacaoDaLive } from "./sala.ts";

const AGORA = new Date("2026-10-10T15:00:00.000Z").getTime();

test("dia e hora de Brasília viram ISO (-03:00) e voltam para os campos", () => {
  const iso = horarioDeBrasilia("2026-10-16", "20:00");
  assert.equal(iso, "2026-10-16T23:00:00.000Z");
  assert.deepEqual(paraOsCampos(iso!), { dia: "2026-10-16", hora: "20:00" });
  assert.equal(horarioDeBrasilia("16/10/2026", "20:00"), null);
  assert.equal(horarioDeBrasilia("2026-10-16", "8h"), null);
});

test("lerDadosDaLive confere o que veio da tela", () => {
  const d = lerDadosDaLive(
    {
      titulo: "  Precificação   sem medo ",
      dia: "2026-10-16",
      hora: "20:00",
      duracaoMin: 90,
      esperaMin: 15,
      acesso: "paga",
      preco: "47,00",
      limiteVagas: "",
      chat: "perguntas",
      participacao: "qualquer",
      aprender: ["Montar o preço", "", "  Tirar dúvidas  "],
      produtosVitrine: ["00000000-0000-4000-8000-000000000001", "nada", "00000000-0000-4000-8000-000000000001"],
      capa: "http://inseguro.com/x.png",
      apresentadorFoto: "https://cdn.exemplo.com/foto.jpg",
    },
    AGORA,
  );
  assert.equal(d.titulo, "Precificação sem medo");
  assert.equal(d.comecaEm, "2026-10-16T23:00:00.000Z");
  assert.equal(d.preco, 47);
  assert.equal(d.limiteVagas, null);
  assert.equal(d.chat, "perguntas");
  assert.equal(d.participacao, "mao");
  assert.deepEqual(d.aprender, ["Montar o preço", "Tirar dúvidas"]);
  assert.deepEqual(d.produtosVitrine, ["00000000-0000-4000-8000-000000000001"]);
  assert.equal(d.capa, null);
  assert.equal(d.apresentadorFoto, "https://cdn.exemplo.com/foto.jpg");
  assert.equal(d.vaga, "gratis");
});

test("lerDadosDaLive recusa o que não dá para salvar", () => {
  assert.throws(() => lerDadosDaLive({ titulo: "", dia: "2026-10-16", hora: "20:00" }, AGORA), ErroNosDados);
  assert.throws(() => lerDadosDaLive({ titulo: "Live", dia: "", hora: "" }, AGORA), /dia e a hora/);
  assert.throws(() => lerDadosDaLive({ titulo: "Live", dia: "2026-10-16", hora: "20:00", acesso: "paga", preco: 0 }, AGORA), /preço/);
  assert.throws(() => lerDadosDaLive({ titulo: "Live", dia: "2026-10-16", hora: "20:00", acesso: "aberta", vaga: "pacote" }, AGORA), /pacote/);
  /* Grátis e aberta não têm preço, mesmo que venha um. */
  assert.equal(lerDadosDaLive({ titulo: "Live", dia: "2026-10-16", hora: "20:00", acesso: "cadastro", preco: 30 }, AGORA).preco, 0);
});

test("item para soltar: cupom em maiúsculas, link só https, produto com caminho da loja", () => {
  const cupom = lerItem({ tipo: "cupom", titulo: "30% off", codigo: "live 30" });
  assert.equal(cupom?.codigo, "LIVE30");
  assert.equal(lerItem({ tipo: "link", titulo: "Planilha", destino: "javascript:alert(1)" })?.destino, null);
  assert.equal(lerItem({ tipo: "produto", titulo: "Kit", destino: "/p/123" })?.destino, "/p/123");
  assert.equal(lerItem({ tipo: "produto", titulo: "Kit", destino: "//malicioso.com" })?.destino, null);
  assert.equal(lerItem({ tipo: "cupom", titulo: "" }), null);
});

test("salaParaOBanco usa os nomes das colunas", () => {
  const d = lerDadosDaLive({ titulo: "Live", dia: "2026-10-16", hora: "20:00", acesso: "aberta", vitrine: true }, AGORA);
  const linha = salaParaOBanco(d);
  assert.equal(linha.comeca_em, d.comecaEm);
  assert.equal(linha.vitrine, true);
  assert.equal(linha.gravacao_para, "compradores");
});

test("situação da live na lista do painel", () => {
  const base = { comeca_em: "2026-10-10T22:00:00.000Z", duracao_min: 60 };
  assert.equal(situacaoDaLive({ ...base, status: "agendada" }, AGORA), "hoje");
  assert.equal(situacaoDaLive({ ...base, comeca_em: "2026-10-16T23:00:00.000Z", status: "agendada" }, AGORA), "agendada");
  assert.equal(situacaoDaLive({ ...base, comeca_em: "2026-10-01T23:00:00.000Z", status: "agendada" }, AGORA), "passou");
  assert.equal(situacaoDaLive({ ...base, status: "ao_vivo" }, AGORA), "ao_vivo");
  assert.equal(situacaoDaLive({ ...base, status: "cancelada" }, AGORA), "cancelada");
});

test("reunião: aberta pelo link, todo mundo fala, sem loja e a gravação fica para baixar", () => {
  const d = lerDadosDaLive({ categoria: "reuniao", titulo: "Conversa com fornecedor", dia: "2026-10-20", hora: "10:00", acesso: "paga", preco: 50, vitrine: true, produtosVitrine: ["8d1f1a3e-0c1b-4c5e-9a55-2f1d3c4b5a6e"], gravacaoPara: "compradores" });
  assert.equal(d.categoria, "reuniao");
  assert.equal(d.acesso, "aberta");
  assert.equal(d.preco, 0);
  assert.equal(d.participacao, "livre");
  assert.equal(d.vitrine, false);
  assert.deepEqual(d.produtosVitrine, []);
  assert.equal(d.gravacaoPara, "ninguem");
  assert.equal(d.gravacaoModo, "sala");
});

test("começar agora: a hora é a de agora", () => {
  const agora = Date.parse("2026-10-13T15:00:00.000Z");
  const d = lerDadosDaLive({ categoria: "reuniao", titulo: "Reunião das 12:00", agora: true }, agora);
  assert.equal(d.comecaEm, "2026-10-13T15:00:00.000Z");
});

test("live de venda continua como era", () => {
  const d = lerDadosDaLive({ titulo: "Lançamento", dia: "2026-10-20", hora: "20:00", acesso: "paga", preco: 30, gravacaoModo: "sala" });
  assert.equal(d.categoria, "venda");
  assert.equal(d.participacao, "mao");
  assert.equal(d.gravacaoPara, "compradores");
  assert.equal(d.gravacaoModo, "sala");
});

test("pessoas do grátis: cortesia sem limite, número da regra e padrão", () => {
  assert.equal(pessoasDoGratis({ gratis_pessoas: 100000, pessoas_sem_limite: true }), "sem limite de pessoas");
  assert.equal(pessoasDoGratis({ gratis_pessoas: 100000 }), "sem limite de pessoas");
  assert.equal(pessoasDoGratis({ gratis_pessoas: 100, pessoas_sem_limite: false }), "até 100 pessoas");
  assert.equal(pessoasDoGratis({ gratis_pessoas: 30 }), "até 30 pessoas");
  assert.equal(pessoasDoGratis(null), "até 30 pessoas");
  assert.equal(semLimiteDePessoas(undefined), false);
});
