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

import { lerAjustesDaLoja } from "./ajustes.ts";
import {
  chipDoPrazo,
  corDoSelo,
  emPreVenda,
  entregaNaVitrine,
  textosDaEntrega,
  formatosDoQueRecebe,
  lerConfigDigitalDaLoja,
  passosDaEntrega,
  prazoQueVale,
  textoDoPrazo,
  textoDoPrazoDoCurso,
  textoDoPrazoDoTipo,
} from "./produto.ts";

test("lixo vira uma página vazia e segura", () => {
  const vazio = lerConfigDigitalDaLoja("lixo");
  assert.equal(vazio.tipo, "arquivos");
  assert.deepEqual(vazio.recebe, []);
  assert.deepEqual(vazio.amostras, []);
  assert.equal(vazio.licenca, null);
  assert.equal(vazio.prazoDias, undefined);
});

test("só endereços https viram amostra; itens sem título somem", () => {
  const lido = lerConfigDigitalDaLoja({
    amostras: ["https://exemplo.com/a.png", "http://exemplo.com/b.png", "javascript:alert(1)", 42],
    recebe: [{ titulo: "  Convites  ", selo: "pdf", detalhe: "A5" }, { selo: "PNG" }, null],
  });
  assert.deepEqual(lido.amostras, ["https://exemplo.com/a.png"]);
  assert.deepEqual(lido.recebe, [{ titulo: "Convites", detalhe: "A5", selo: "PDF" }]);
});

test("o prazo: do produto, senão o da loja, senão sem prazo", () => {
  assert.equal(lerConfigDigitalDaLoja({ acesso: null }).prazoDias, undefined);
  assert.equal(lerConfigDigitalDaLoja({ acesso: { prazoDias: null } }).prazoDias, null);
  assert.equal(lerConfigDigitalDaLoja({ acesso: { prazoDias: 90 } }).prazoDias, 90);
  assert.equal(prazoQueVale(undefined, 30), 30);
  assert.equal(prazoQueVale(null, 30), null);
  assert.equal(prazoQueVale(90, 30), 90);
  assert.equal(prazoQueVale(undefined, null), null);
  assert.equal(textoDoPrazo(null), "Acesso sem prazo. Baixe quantas vezes precisar.");
  assert.equal(textoDoPrazo(365), "Acesso por 1 ano a partir da compra.");
  assert.equal(textoDoPrazo(60), "Acesso por 2 meses a partir da compra.");
  assert.equal(textoDoPrazo(7), "Acesso por 7 dias a partir da compra.");
});

test("selos e formatos", () => {
  assert.equal(corDoSelo("pdf"), "#E5484D");
  assert.equal(corDoSelo("PNG"), "#2F80ED");
  assert.equal(corDoSelo("LINK"), "#7B61FF");
  assert.equal(formatosDoQueRecebe([]), null);
  assert.equal(
    formatosDoQueRecebe([
      { titulo: "a", detalhe: null, selo: "PDF" },
      { titulo: "b", detalhe: null, selo: "PNG" },
      { titulo: "c", detalhe: null, selo: "PDF" },
      { titulo: "d", detalhe: null, selo: "TEXTO" },
    ]),
    "PDF + PNG"
  );
});

test("os passos acompanham o jeito de comprar", () => {
  const pix = passosDaEntrega({ jeito: "comprar", gratis: false, meios: ["pix"], prazoDias: null });
  assert.equal(pix[0].titulo, "Pague com Pix");
  assert.equal(pix[1].titulo, "Receba na hora");
  const dois = passosDaEntrega({ jeito: "comprar", gratis: false, meios: ["pix", "cartao"], prazoDias: null });
  assert.equal(dois[0].titulo, "Pague com Pix ou cartão");
  const zap = passosDaEntrega({ jeito: "whatsapp", gratis: false, meios: [], prazoDias: 30 });
  assert.equal(zap[0].titulo, "Combine com a loja");
  assert.equal(zap[1].titulo, "Receba quando a loja confirmar");
  assert.equal(zap[2].texto, "Acesso por 1 mês a partir da compra.");
  const gratis = passosDaEntrega({ jeito: "comprar", gratis: true, meios: [], prazoDias: null });
  assert.equal(gratis[0].titulo, "Peça o seu");
});

test("os ajustes da loja completam o padrão", () => {
  const padrao = lerAjustesDaLoja(null);
  assert.deepEqual(padrao, {
    area: { nome: null, aparencia: "escura", cor: null, banner: null, fonte: "cinema", fundo: "preto", capas: "em_pe" },
    prazoDias: null,
    botaoWhatsapp: true,
    player: { continuar: true, percentualAssistida: 90, velocidades: [0.75, 1, 1.25, 1.5, 2], proximaSozinha: true },
    comentarios: { quando: "na_hora", avisar: true },
    certificado: { emitir: true, assinatura: null },
    protecao: { aparelhos: 2, freioLugares: 5, marcaDagua: false },
  });
  assert.deepEqual(lerAjustesDaLoja({ acesso: { aparelhos: 0, freioLugares: null, marcaDagua: true } }).protecao, {
    aparelhos: 2,
    freioLugares: null,
    marcaDagua: true,
  });
  assert.equal(lerAjustesDaLoja({ acesso: { freioLugares: 1 } }).protecao.freioLugares, 2);
  /* Velocidade inventada não entra (3x), "2" escrito como texto vale (igual ao painel), e 1x nunca falta. */
  assert.deepEqual(lerAjustesDaLoja({ player: { velocidades: [1.5, 3, "2"], percentualAssistida: 10 } }).player.velocidades, [1, 1.5, 2]);
  assert.equal(lerAjustesDaLoja({ player: { percentualAssistida: 10 } }).player.percentualAssistida, 50);
  assert.equal(lerAjustesDaLoja({ comentarios: { quando: "aprovacao" } }).comentarios.quando, "aprovacao");
  assert.equal(lerAjustesDaLoja({ comentarios: { avisar: false } }).comentarios.avisar, false);
  const lido = lerAjustesDaLoja({
    area: { nome: "  Escola Aurora ", aparencia: "clara", cor: "#f26b1d", banner: "http://inseguro.com/x.png" },
    acesso: { prazoDias: 99999 },
    entrega: { botaoWhatsapp: false },
  });
  assert.deepEqual(lido.area, { nome: "Escola Aurora", aparencia: "clara", cor: "#F26B1D", banner: null, fonte: "cinema", fundo: "claro", capas: "em_pe" });
  assert.equal(lido.prazoDias, 3650);
  assert.equal(lido.botaoWhatsapp, false);
});

test("curso: prazo e passos falam de assistir, não de baixar", () => {
  assert.equal(textoDoPrazoDoCurso(null), "Acesso para sempre. Assista quantas vezes quiser.");
  assert.equal(textoDoPrazoDoCurso(365), "Acesso por 1 ano a partir da compra.");
  assert.equal(chipDoPrazo(null), "Acesso para sempre");
  assert.equal(chipDoPrazo(365), "Acesso por 1 ano");
  assert.equal(chipDoPrazo(45), "Acesso por 45 dias");
  const passos = passosDaEntrega({ jeito: "comprar", gratis: false, meios: ["pix"], prazoDias: null, curso: true });
  assert.equal(passos.length, 3);
  assert.equal(passos[0].titulo, "Pague com Pix");
  assert.equal(passos[1].titulo, "Receba o acesso no e-mail");
  assert.equal(passos[2].titulo, "Assista no seu ritmo");
  assert.ok(!passos.some((p) => /baix/i.test(p.titulo + p.texto)));
});

test("fase 3: como entrega, pré-venda, limite e marca no PDF", () => {
  const lido = lerConfigDigitalDaLoja({
    entrega: { modo: "encomenda", prazoDias: 2 },
    preVenda: { em: "2030-01-01T03:00:00.000Z" },
    limiteDeDownloads: 5,
    marcaNoPdf: false,
  });
  assert.deepEqual(lido.entrega, { modo: "encomenda", prazoDias: 2 });
  assert.equal(emPreVenda(lido, Date.parse("2029-12-31T00:00:00Z")), true);
  assert.equal(emPreVenda(lido, Date.parse("2030-01-02T00:00:00Z")), false);
  assert.equal(lido.limiteDeDownloads, 5);
  assert.equal(lido.marcaNoPdf, false);
  const vazio = lerConfigDigitalDaLoja({});
  assert.deepEqual(vazio.entrega, { modo: "na_hora", prazoDias: 3 });
  assert.equal(vazio.preVenda, null);
  assert.equal(vazio.limiteDeDownloads, null);
  assert.equal(vazio.marcaNoPdf, null);
  assert.equal(corDoSelo("CÓD"), "#0F766E");
});

test("a promessa da entrega: na hora, sob encomenda e pré-venda", () => {
  const agora = Date.parse("2026-10-10T12:00:00.000Z");
  const naHora = entregaNaVitrine({ entrega: { modo: "na_hora", prazoDias: 3 }, preVenda: null }, agora);
  assert.equal(naHora.modo, "na_hora");
  assert.equal(textosDaEntrega(naHora), null);

  const encomenda = entregaNaVitrine({ entrega: { modo: "encomenda", prazoDias: 3 }, preVenda: null }, agora);
  assert.deepEqual(textosDaEntrega(encomenda), {
    chip: "Sob encomenda · até 3 dias úteis",
    linha: "Feito para você: a loja produz e entrega em até 3 dias úteis, no seu e-mail e em Minhas compras.",
    botao: "Encomendar",
  });
  assert.equal(textosDaEntrega({ modo: "encomenda", prazoDias: 0, liberaEm: null })?.chip, "Sob encomenda · no mesmo dia útil");

  /* A pré-venda vence a encomenda enquanto a data não chega; depois some sozinha. */
  const preVenda = { entrega: { modo: "encomenda" as const, prazoDias: 3 }, preVenda: { em: "2026-11-01T03:00:00.000Z" } };
  assert.deepEqual(entregaNaVitrine(preVenda, agora), { modo: "pre_venda", prazoDias: 0, liberaEm: "01/11" });
  assert.equal(textosDaEntrega(entregaNaVitrine(preVenda, agora), true)?.linha, "Pré-venda: garanta agora e comece em 01/11. O acesso chega no seu e-mail.");
  assert.equal(entregaNaVitrine(preVenda, Date.parse("2026-11-02T00:00:00.000Z")).modo, "encomenda");
});

test("código ou licença: a página fala em copiar o código, nunca em baixar", () => {
  const passos = passosDaEntrega({ jeito: "comprar", gratis: true, meios: [], prazoDias: null, codigo: true });
  assert.deepEqual(
    passos.map((p) => p.titulo),
    ["Peça o seu", "Receba o código na hora", "Use quando quiser"],
  );
  assert.ok(!passos.some((p) => /baix/i.test(p.titulo + p.texto)));
  const zap = passosDaEntrega({ jeito: "whatsapp", gratis: false, meios: [], prazoDias: 30, codigo: true });
  assert.equal(zap[1].texto, "O seu código chega no seu e-mail assim que o pagamento for confirmado.");
  assert.equal(zap[2].texto, "Acesso por 1 mês a partir da compra.");
  const preVenda = passosDaEntrega({
    jeito: "comprar",
    gratis: false,
    meios: ["pix"],
    prazoDias: null,
    codigo: true,
    entrega: { modo: "pre_venda", prazoDias: 0, liberaEm: "01/11" },
  });
  assert.equal(preVenda[1].titulo, "Receba em 01/11");
  assert.ok(!preVenda.some((p) => /baix/i.test(p.titulo + p.texto)));

  assert.equal(textoDoPrazoDoTipo("codigo", null), "Acesso sem prazo. Copie o código quando precisar.");
  assert.equal(textoDoPrazoDoTipo("codigo", 365), "Acesso por 1 ano a partir da compra.");
  assert.equal(textoDoPrazoDoTipo("curso", null), "Acesso para sempre. Assista quantas vezes quiser.");
  assert.equal(textoDoPrazoDoTipo("arquivos", null), "Acesso sem prazo. Baixe quantas vezes precisar.");
});
