import assert from "node:assert/strict";
import { test } from "node:test";
import {
  conferirLinkDeAcesso,
  diaUtilDepois,
  lerCamposDoComprador,
  lerConfigDigital,
  lerPreVenda,
  pendenciasParaPublicar,
  precoValido,
  resumoDoQueRecebe,
  seloDoEntregavel,
  tipoDigitalValido,
} from "./produto.ts";

test("config vazia vira o mínimo com o tipo padrão", () => {
  assert.deepEqual(lerConfigDigital(undefined), {
    tipo: "arquivos",
    resumo: null,
    recebe: [],
    perguntas: [],
    funcionaCom: [],
    licenca: null,
    acesso: null,
    amostras: [],
    entrega: { modo: "na_hora", prazoDias: 3 },
    preVenda: null,
    limiteDeDownloads: null,
    marcaNoPdf: null,
    avisarCodigosCom: 5,
  });
  assert.equal(lerConfigDigital({ tipo: "curso" }).tipo, "curso");
  assert.equal(lerConfigDigital({ tipo: "hack" }, "link").tipo, "link");
});

test("config corta, limpa e descarta o que não serve", () => {
  const lido = lerConfigDigital({
    tipo: "arquivos",
    resumo: "  Kit completo  ",
    perguntas: [{ pergunta: "Recebo físico?", resposta: "Não, é digital." }, { pergunta: "sem resposta" }],
    funcionaCom: ["Canva", "", 3, "Impressora"],
    amostras: ["https://img.com/a.webp", "http://inseguro/b.png", "javascript:alert(1)"],
    licenca: { tipo: "comercial", texto: "Pode vender o impresso." },
    acesso: { prazoDias: 365.4 },
    recebe: [{ titulo: "Convite", detalhe: "PDF A5", selo: "pdf" }, { titulo: "" }],
  });
  assert.equal(lido.resumo, "Kit completo");
  assert.equal(lido.perguntas.length, 1);
  assert.deepEqual(lido.funcionaCom, ["Canva", "Impressora"]);
  assert.deepEqual(lido.amostras, ["https://img.com/a.webp"]);
  assert.deepEqual(lido.licenca, { tipo: "comercial", texto: "Pode vender o impresso." });
  assert.deepEqual(lido.acesso, { prazoDias: 365 });
  assert.deepEqual(lido.recebe, [{ titulo: "Convite", detalhe: "PDF A5", selo: "PDF" }]);
  assert.deepEqual(lerConfigDigital({ acesso: { prazoDias: null } }).acesso, { prazoDias: null }, "null = para sempre");
});

test("o que você recebe não leva endereço nenhum", () => {
  const recebe = resumoDoQueRecebe([
    { tipo: "arquivo", titulo: "Moldes", descricao: null, ativo: true, arquivo: { extensao: "pdf", tamanhoLegivel: "31 MB" } },
    { tipo: "link", titulo: "Grupo VIP", descricao: "No WhatsApp", ativo: true },
    { tipo: "texto", titulo: "Instruções", descricao: null, ativo: false },
  ]);
  assert.deepEqual(recebe, [
    { titulo: "Moldes", detalhe: "PDF · 31 MB", selo: "PDF" },
    { titulo: "Grupo VIP", detalhe: "No WhatsApp · Acesso liberado depois do pagamento", selo: "LINK" },
  ]);
  assert.ok(!JSON.stringify(recebe).includes("http"));
});

test("selo, tipo, preço e link", () => {
  assert.equal(seloDoEntregavel("arquivo", "zip"), "ZIP");
  assert.equal(seloDoEntregavel("codigos"), "CÓD");
  assert.equal(tipoDigitalValido("curso"), "curso");
  assert.equal(tipoDigitalValido("fisico"), null);
  assert.equal(precoValido("29,90"), 29.9);
  assert.equal(precoValido(-1), null);
  assert.equal(precoValido(0), 0);
  assert.equal(precoValido(10.005), 10.01);
  assert.equal(conferirLinkDeAcesso("https://chat.whatsapp.com/abc").ok, true);
  assert.equal(conferirLinkDeAcesso("javascript:alert(1)").ok, false);
  assert.equal(conferirLinkDeAcesso("site sem protocolo").ok, false);
  assert.equal(conferirLinkDeAcesso("https://localhost").ok, false);
});

test("pendências para publicar, em português", () => {
  assert.deepEqual(pendenciasParaPublicar({ nome: "Kit", preco: 10, imagem: "x", entregaveisAtivos: 1, arquivosNaoProntos: 0 }), []);
  assert.equal(pendenciasParaPublicar({ nome: "", preco: 0, imagem: null, entregaveisAtivos: 0, arquivosNaoProntos: 2 }).length, 4);
});

test("fase 3: como entrega, pré-venda, limite, marca no PDF e aviso dos códigos", () => {
  const lido = lerConfigDigital({
    tipo: "arquivos",
    entrega: { modo: "encomenda", prazoDias: 120 },
    preVenda: { em: "2026-11-01T03:00:00.000Z" },
    limiteDeDownloads: 5.4,
    marcaNoPdf: true,
    avisarCodigosCom: "8",
  });
  assert.deepEqual(lido.entrega, { modo: "encomenda", prazoDias: 90 }, "prazo cortado em 90 dias úteis");
  assert.deepEqual(lido.preVenda, { em: "2026-11-01T03:00:00.000Z" });
  assert.equal(lido.limiteDeDownloads, 5);
  assert.equal(lido.marcaNoPdf, true);
  assert.equal(lido.avisarCodigosCom, 8);
  const padrao = lerConfigDigital({ entrega: { modo: "hack" }, limiteDeDownloads: 0, marcaNoPdf: "sim" });
  assert.deepEqual(padrao.entrega, { modo: "na_hora", prazoDias: 3 });
  assert.equal(padrao.limiteDeDownloads, null, "zero = sem limite");
  assert.equal(padrao.marcaNoPdf, null, "só sim ou não; o resto segue a loja");
  assert.equal(lerPreVenda({ em: "lixo" }), null);
  assert.equal(lerPreVenda(null), null);
});

test("dias úteis pulam sábado e domingo", () => {
  /* Sexta, 09/10/2026 + 3 dias úteis = quarta, 14/10. */
  assert.equal(diaUtilDepois(new Date("2026-10-09T12:00:00Z"), 3).toISOString().slice(0, 10), "2026-10-14");
  /* Sábado + 1 = segunda. */
  assert.equal(diaUtilDepois(new Date("2026-10-10T12:00:00Z"), 1).toISOString().slice(0, 10), "2026-10-12");
  assert.equal(diaUtilDepois(new Date("2026-10-10T12:00:00Z"), 0).toISOString().slice(0, 10), "2026-10-10");
});

test("pendências da fase 3: códigos e grátis sem assinatura", () => {
  const base = { nome: "Licença", preco: 10, imagem: "x", entregaveisAtivos: 1, arquivosNaoProntos: 0 };
  assert.deepEqual(pendenciasParaPublicar({ ...base, codigosLivres: 0 }), ["Adicione os códigos: cada compra leva um."]);
  assert.deepEqual(pendenciasParaPublicar({ ...base, codigosLivres: 3 }), []);
  assert.equal(pendenciasParaPublicar({ ...base, preco: 0, gratisSemAssinatura: true }).length, 1);
  assert.equal(seloDoEntregavel("encomenda"), "SOB");
});

test("campos do comprador (sob encomenda): limpos, sem repetir id, no formato dos físicos", () => {
  const campos = lerCamposDoComprador([
    { id: "nome", title: "  Nome no convite ", field_type: "text", required: true },
    { id: "nome", title: "Idade", field_type: "number" },
    { title: "" },
    { id: "x<script>", title: "Observações", field_type: "html" },
  ]);
  assert.deepEqual(campos.map((c) => [c.id, c.title, c.field_type, c.required]), [
    ["nome", "Nome no convite", "text", true],
    ["nome_2", "Idade", "number", false],
    ["xscript", "Observações", "text", false],
  ]);
  assert.deepEqual(lerCamposDoComprador("lixo"), []);
});
