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

import { PRODUTO_KTALOGU } from "./assinatura-cakto.ts";
import { acontecimentoParaODono, lembrarDoPix, lembreteDeCarrinho, lerAbandono, primeiroPasso } from "./automacoes-da-assinatura.ts";

const HORA = 60 * 60 * 1000;

describe("carrinho abandonado", () => {
  const corpo = (produto = PRODUTO_KTALOGU) => ({
    event: "checkout_abandonment",
    data: {
      offer: { id: "gvndd3a" },
      product: { id: produto },
      customerName: "Maria",
      customerEmail: " Maria@Exemplo.com ",
      checkoutUrl: "https://pay.cakto.com.br/gvndd3a",
      createdAt: "2026-09-30T10:00:00-03:00",
    },
  });

  it("lê o aviso da Cakto", () => {
    const lido = lerAbandono(corpo());
    assert.equal(lido?.email, "maria@exemplo.com");
    assert.equal(lido?.ofertaId, "gvndd3a");
    assert.equal(lido?.abandonadoEm.toISOString(), "2026-09-30T13:00:00.000Z");
  });

  it("webhook V2 manda em lista, e também vale", () => {
    const { event, data } = corpo();
    assert.equal(lerAbandono({ event, data: [data] })?.email, "maria@exemplo.com");
  });

  it("outro produto ou outro evento não é carrinho da Ktalogu", () => {
    assert.equal(lerAbandono(corpo("05903b83-1332-4989-b6ed-f3f829341669")), null);
    assert.equal(lerAbandono({ ...corpo(), event: "purchase_approved" }), null);
  });

  it("lembra em 1 hora e em 24 horas, e para depois de 3 dias", () => {
    const quando = new Date("2026-09-30T13:00:00Z");
    const depois = (horas: number) => new Date(quando.getTime() + horas * HORA);
    assert.equal(lembreteDeCarrinho(quando, depois(0.5)), null);
    assert.equal(lembreteDeCarrinho(quando, depois(1)), "carrinho-1h");
    assert.equal(lembreteDeCarrinho(quando, depois(23)), "carrinho-1h");
    assert.equal(lembreteDeCarrinho(quando, depois(24)), "carrinho-24h");
    assert.equal(lembreteDeCarrinho(quando, depois(80)), null);
  });
});

describe("Pix pendente", () => {
  const criado = new Date("2026-09-30T13:00:00Z");

  it("lembra depois de 1 hora, se o Pix ainda vale", () => {
    assert.equal(lembrarDoPix(criado, new Date("2026-10-01T13:00:00Z"), new Date("2026-09-30T13:30:00Z")), false);
    assert.equal(lembrarDoPix(criado, new Date("2026-10-01T13:00:00Z"), new Date("2026-09-30T14:10:00Z")), true);
  });

  it("não manda código que está vencendo ou já venceu", () => {
    assert.equal(lembrarDoPix(criado, new Date("2026-09-30T14:20:00Z"), new Date("2026-09-30T14:10:00Z")), false);
    assert.equal(lembrarDoPix(criado, new Date("2026-09-30T14:00:00Z"), new Date("2026-09-30T14:10:00Z")), false);
  });
});

describe("primeiros passos", () => {
  const nada = { produto: false, loja: false, orcamento: false };

  it("dia 1 produto, dia 3 loja, dia 7 orçamento", () => {
    assert.equal(primeiroPasso(0, nada), null);
    assert.equal(primeiroPasso(1, nada), "passo-produto");
    assert.equal(primeiroPasso(3, nada), "passo-loja");
    assert.equal(primeiroPasso(7, nada), "passo-orcamento");
    assert.equal(primeiroPasso(12, nada), null);
  });

  it("quem já fez não recebe", () => {
    assert.equal(primeiroPasso(1, { ...nada, produto: true }), null);
    assert.equal(primeiroPasso(4, { ...nada, loja: true }), null);
    assert.equal(primeiroPasso(8, { produto: true, loja: true, orcamento: true }), null);
  });
});

describe("aviso ao dono", () => {
  it("separa venda nova, troca, renovação e os problemas", () => {
    assert.equal(acontecimentoParaODono("purchase_approved", "Acesso liberado até X (anual)."), "nova");
    assert.equal(acontecimentoParaODono("purchase_approved", "Acesso liberado até X (anual, +20 dias de crédito)."), "troca");
    assert.equal(acontecimentoParaODono("subscription_renewed", ""), "renovacao");
    assert.equal(acontecimentoParaODono("subscription_renewal_refused", ""), "recusado");
    assert.equal(acontecimentoParaODono("subscription_canceled", ""), "cancelamento");
    assert.equal(acontecimentoParaODono("refund", ""), "reembolso");
    assert.equal(acontecimentoParaODono("chargeback", ""), "chargeback");
  });

  it("o que não interessa fica de fora (inclusive a 'assinatura criada', que repete a compra)", () => {
    assert.equal(acontecimentoParaODono("pix_gerado", ""), null);
    assert.equal(acontecimentoParaODono("subscription_created", ""), null);
    assert.equal(acontecimentoParaODono("refund_requested", ""), null);
  });
});
