import assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
  codigoComecaPelaAtividade,
  conferirCodigoDoServico,
  dicaDoCodigo,
  formatarCnae,
  lerExemploDaCidade,
  type ExemploDaCidade,
} from "./formato-da-cidade.ts";

/* O exemplo que a Spedy devolve para Campinas (uma nota autorizada de verdade). */
const CAMPINAS: ExemploDaCidade = { codigoMunicipal: "802000102", cnae: "8020-0/01", itemLc116: "11.05" };
/* As atividades da MK5 no cadastro da empresa. */
const ATIVIDADES_DA_MK5 = ["4761003", "8299703", "4689399", "1822999", "1813099"];

const conferir = (codigo: string | null, cnae: string | null, exemplo: ExemploDaCidade | null = CAMPINAS) =>
  conferirCodigoDoServico({ codigo, cnae, exemplo, cnaesDaEmpresa: ATIVIDADES_DA_MK5, cidade: "Campinas" });

describe("formato do código do serviço na prefeitura", () => {
  it("lê os três códigos do exemplo da Spedy", () => {
    assert.deepEqual(
      lerExemploDaCidade({ cityServiceCode: "802000102", cnaeCode: "8020-0/01", federalServiceCode: "11.05", total: {} }),
      CAMPINAS
    );
    assert.equal(lerExemploDaCidade({ description: "sem códigos" }), null);
    assert.equal(lerExemploDaCidade(null), null);
  });

  it("Campinas monta o código com a atividade; Goiânia não", () => {
    assert.equal(codigoComecaPelaAtividade(CAMPINAS), true);
    assert.equal(codigoComecaPelaAtividade({ codigoMunicipal: "1.01", cnae: "6201-5/01", itemLc116: "1.01" }), false);
    assert.equal(formatarCnae("1813099"), "1813-0/99");
  });

  it("a primeira tentativa da MK5: o item da lista nacional no lugar do código da prefeitura", () => {
    const avisos = conferir("13.05", "4761003");
    assert.equal(avisos.length, 1);
    assert.equal(avisos[0].tipo, "formato");
    assert.match(avisos[0].texto, /9 números, sem ponto/);
  });

  it("a segunda tentativa: o código do exemplo, que é de outra atividade", () => {
    const avisos = conferir("802000102", "4761003");
    assert.equal(avisos.length, 1);
    assert.equal(avisos[0].tipo, "fora-das-atividades");
    assert.match(avisos[0].texto, /8020-0\/01/);
  });

  it("código certo com a atividade errada: sugere a que combina", () => {
    const avisos = conferir("181309900", "4761003");
    assert.equal(avisos.length, 1);
    assert.equal(avisos[0].tipo, "outra-atividade");
    assert.equal(avisos[0].cnaeSugerido, "1813099");
  });

  it("código e atividade que combinam não ganham aviso", () => {
    assert.deepEqual(conferir("181309900", "1813099"), []);
    assert.deepEqual(conferir("181309900", "1813-0/99"), []);
  });

  it("cidade com código de ponto: confere só a forma", () => {
    const goiania: ExemploDaCidade = { codigoMunicipal: "1.01", cnae: null, itemLc116: "1.01" };
    assert.deepEqual(conferir("13.05", null, goiania), []);
    assert.equal(conferir("1305", null, goiania)[0]?.tipo, "formato");
    const saoBernardo: ExemploDaCidade = { codigoMunicipal: "1.01/102301", cnae: null, itemLc116: "1.01" };
    assert.equal(conferir("1.01", null, saoBernardo)[0]?.tipo, "formato");
    assert.deepEqual(conferir("13.05/130501", null, saoBernardo), []);
  });

  it("sem exemplo da cidade ou sem código digitado, nada a dizer", () => {
    assert.deepEqual(conferir("13.05", "4761003", null), []);
    assert.deepEqual(conferir("", "4761003"), []);
  });

  it("a dica mostra o formato e o começo do código da atividade escolhida, nunca um código para copiar", () => {
    const dica = dicaDoCodigo(CAMPINAS, "Campinas", "1813099");
    assert.match(dica ?? "", /atividade \(CNAE\) com mais 2 números/);
    assert.match(dica ?? "", /começa por 1813099/);
    assert.doesNotMatch(dica ?? "", /802000102/);
    assert.match(dicaDoCodigo({ codigoMunicipal: "1.01", cnae: null, itemLc116: null }, "Goiânia", null) ?? "", /formato: 1\.01\. É só um exemplo/);
    assert.equal(dicaDoCodigo(null, "Campinas", null), null);
  });
});
