import { test } from "node:test";
import assert from "node:assert/strict";
import { juntarEndereco, partirEndereco, type Endereco } from "./endereco.ts";

/**
 * Endereço: montar e desmontar.
 *
 * O que importa aqui e a ida e volta. `juntarEndereco` escreve o texto que vai
 * para o banco; `partirEndereco` le esse mesmo texto quando alguem abre o
 * compromisso para editar. Se os dois desandarem, o endereco se desmonta na
 * tela de edicao — sem erro nenhum no console, so campos no lugar errado.
 *
 * Roda com `npm test`, sem dependencia: o Node 22 executa TypeScript direto.
 */

const base = (p: Partial<Endereco> = {}): Endereco => ({
  rua: "",
  numero: "",
  complemento: "",
  bairro: "",
  cidade: "",
  uf: "",
  ...p,
});

test("monta no formato que o geocodificador espera", () => {
  const texto = juntarEndereco(
    base({ rua: "Avenida Paulista", numero: "1578", bairro: "Bela Vista", cidade: "São Paulo", uf: "SP" })
  );
  assert.equal(texto, "Avenida Paulista, 1578, Bela Vista, São Paulo - SP");
});

test("complemento sai da parte principal, entre parenteses", () => {
  const texto = juntarEndereco(
    base({ rua: "Rua A", numero: "10", complemento: "Sala 3", cidade: "Salvador", uf: "BA" })
  );
  /* Sala e andar nao ajudam a achar o ponto no mapa; ficam fora da busca. */
  assert.equal(texto, "Rua A, 10, Salvador - BA (Sala 3)");
});

test("campo vazio nao deixa virgula solta", () => {
  const texto = juntarEndereco(base({ rua: "Rua B", cidade: "Piatã", uf: "BA" }));
  assert.equal(texto, "Rua B, Piatã - BA");
  assert.ok(!texto.includes(", ,"), "nao pode sobrar virgula de campo vazio");
});

test("ida e volta preserva o endereço completo", () => {
  const original = base({
    rua: "Rua das Flores",
    numero: "250",
    complemento: "Apto 12",
    bairro: "Centro",
    cidade: "Vitória da Conquista",
    uf: "BA",
  });
  assert.deepEqual(partirEndereco(juntarEndereco(original)), original);
});

test("ida e volta sem número — o caso de cidade pequena", () => {
  /* CEP de cidade do interior costuma vir sem rua e sem numero. E o caso que
     motivou separar os campos, entao precisa sobreviver ao ciclo. */
  const original = base({ rua: "Praça da Matriz", bairro: "Centro", cidade: "Piatã", uf: "BA" });
  assert.deepEqual(partirEndereco(juntarEndereco(original)), original);
});

test("distingue número de bairro quando só há duas partes", () => {
  /* "Rua X, 123" e "Rua X, Centro" tem a mesma forma. So o conteudo decide. */
  assert.equal(partirEndereco("Rua X, 123").numero, "123");
  assert.equal(partirEndereco("Rua X, 123").bairro, "");
  assert.equal(partirEndereco("Rua X, Centro").bairro, "Centro");
  assert.equal(partirEndereco("Rua X, Centro").numero, "");
});

test("aceita s/n como número", () => {
  assert.equal(partirEndereco("Estrada do Sol, s/n").numero, "s/n");
});

test("texto livre antigo não se perde — cai em rua", () => {
  /* Endereco salvo antes dos campos separados nao segue formato nenhum.
     Melhor um campo com texto demais do que um endereco perdido. */
  const e = partirEndereco("perto do posto, depois da igreja");
  assert.equal(e.rua, "perto do posto");
  assert.equal(e.bairro, "depois da igreja");
});

test("vazio e nulo devolvem o endereço em branco, sem estourar", () => {
  const vazio = base();
  assert.deepEqual(partirEndereco(""), vazio);
  assert.deepEqual(partirEndereco(null), vazio);
  assert.deepEqual(partirEndereco(undefined), vazio);
  assert.deepEqual(partirEndereco("   "), vazio);
});

test("UF sai em maiúscula mesmo digitada em minúscula", () => {
  assert.equal(partirEndereco("Rua A, 1, Centro, Salvador - ba").uf, "BA");
});

test("bairro com vírgula no meio não se parte", () => {
  const e = partirEndereco("Rua A, 100, Jardim das Acácias, Zona 2, Maringá - PR");
  assert.equal(e.numero, "100");
  assert.equal(e.bairro, "Jardim das Acácias, Zona 2");
  assert.equal(e.cidade, "Maringá");
});
