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

import {
  alvoDaPendencia,
  cepFormatado,
  cestLido,
  comoResolver,
  documentoFormatado,
  GRUPOS_DE_SITUACAO,
  inscricaoLida,
  ncmFormatado,
  ncmLido,
  OPCOES_DE_GRUPO,
  segundosDeEspera,
  semFornecedor,
  textoComLimites,
} from "./ferramentas/notas-fiscais-regras.ts";

test("como resolver: cliente e produto se resolvem pelo assistente, o resto no painel", () => {
  assert.deepEqual(
    [comoResolver("cliente").quem, comoResolver("cliente").ferramenta],
    ["assistente", "corrigir_dados_fiscais_do_cliente"]
  );
  assert.equal(comoResolver("produto", "produto.ncm:abc").ferramenta, "corrigir_ncm_dos_produtos");
  assert.equal(comoResolver("empresa", "empresa.uf").ferramenta, "alterar_dados_fiscais_da_empresa");
  assert.equal(comoResolver("tributacao").ferramenta, "salvar_tributacao_fiscal");
  assert.equal(comoResolver("csc").quem, "painel");
  assert.match(comoResolver("empresa", "creditos.sem_saldo").onde_no_painel ?? "", /Assinatura/);
  assert.equal(comoResolver("aguardar").quem, "aguardar");
  assert.equal(comoResolver("aguardar").ferramenta, "consultar_situacao_da_nota");
  assert.equal(comoResolver("certificado").quem, "painel");
  assert.equal(comoResolver("suporte").quem, "suporte");
  assert.equal(comoResolver(null).quem, "painel");
  assert.equal(comoResolver("pedido", "avulsa.item.valor:0").ferramenta, "emitir_nota_avulsa");
  /* Nada do que volta cita o fornecedor do serviço de notas. */
  for (const onde of ["cliente", "produto", "pedido", "pagamento", "perfil", "empresa", "certificado", "numeracao", "csc", "aguardar", "suporte", null]) {
    assert.doesNotMatch(JSON.stringify(comoResolver(onde)), /spedy|servidor|api\b/i);
  }
});

test("alvo da pendência: produto do catálogo ou item digitado no pedido", () => {
  const produto = "11111111-1111-1111-1111-111111111111";
  const item = "22222222-2222-2222-2222-222222222222";
  assert.deepEqual(alvoDaPendencia(`produto.ncm:${produto}`, produto), { produto_id: produto });
  assert.deepEqual(alvoDaPendencia(`produto.ncm:${item}`, null), { item_do_pedido_id: item });
  assert.deepEqual(alvoDaPendencia("cliente.documento", "x"), {});
});

test("NCM, CEST, inscrição, documento e CEP", () => {
  assert.equal(ncmLido("4911.10.90"), "49111090");
  assert.equal(ncmLido("4911"), null);
  assert.equal(ncmLido(""), "");
  assert.equal(cestLido("01.001.00"), "0100100");
  assert.equal(cestLido("123"), null);
  assert.equal(ncmFormatado("49111090"), "4911.10.90");
  assert.equal(ncmFormatado(null), null);
  assert.equal(inscricaoLida(" isento "), "ISENTO");
  assert.equal(inscricaoLida("110.042.490.114"), "110042490114");
  assert.equal(documentoFormatado("11222333000181"), "11.222.333/0001-81");
  assert.equal(documentoFormatado("12345678909"), "123.456.789-09");
  assert.equal(cepFormatado("13010-000"), "13010-000");
  assert.equal(cepFormatado("1301"), null);
});

test("motivo do cancelamento e carta de correção: limites da lei", () => {
  assert.deepEqual(textoComLimites("  venda   desfeita pelo cliente ", 15, 255), { ok: true, texto: "venda desfeita pelo cliente" });
  const curto = textoComLimites("erro", 15, 255);
  assert.equal(curto.ok, false);
  assert.equal(textoComLimites("x".repeat(256), 15, 255).ok, false);
});

test("espera: nunca passa de 25 segundos", () => {
  assert.equal(segundosDeEspera(undefined), 0);
  assert.equal(segundosDeEspera(-3), 0);
  assert.equal(segundosDeEspera(10), 10);
  assert.equal(segundosDeEspera(90), 25);
  assert.equal(segundosDeEspera("7"), 7);
});

test("grupos de situação e mensagens sem o nome do fornecedor", () => {
  assert.deepEqual([...OPCOES_DE_GRUPO], ["todas", "autorizadas", "andamento", "problemas", "canceladas", "previas"]);
  assert.ok(GRUPOS_DE_SITUACAO.problemas.includes("rejeitada"));
  assert.equal(semFornecedor("Falha na Spedy: timeout"), "Falha no serviço de notas: timeout");
  assert.equal(semFornecedor("Resposta da Spedy"), "Resposta do serviço de notas");
});
