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

import { acharCelula, escolhaDoProduto, estaBaixo, lerCombinacao, normalizar, rotuloDaCelula, textoDaGrade } from "./ferramentas/estoque-v2-regras.ts";

/* Estoque v2 no assistente: ler a combinação escrita e achar a célula, como o banco compara nomes. */

test("normalizar como o banco (sem acento, sem maiúscula, sem dois-pontos no fim)", () => {
  assert.equal(normalizar("  Tamanho: "), "tamanho");
  assert.equal(normalizar("Coração Açaí"), "coracao acai");
  assert.equal(normalizar(null), "");
});

test("lerCombinacao aceita Atributo: valor e só os valores", () => {
  assert.deepEqual(lerCombinacao("Tamanho: G, Cor: Preta"), [
    { atributo: "Tamanho", valor: "G" },
    { atributo: "Cor", valor: "Preta" },
  ]);
  assert.deepEqual(lerCombinacao("G / Preta"), [
    { atributo: null, valor: "G" },
    { atributo: null, valor: "Preta" },
  ]);
  assert.deepEqual(lerCombinacao(""), []);
});

const grade = [
  { nome: "Tamanho", valores: ["P", "M", "G"] },
  { nome: "Cor", valores: ["Branca", "Preta"] },
];
const celulas = [
  { id: "c1", valor1: "G", valor2: "Preta" },
  { id: "c2", valor1: "P", valor2: "Branca" },
  { id: "c3", valor1: "G", valor2: "Branca", ativo: false },
];

test("acharCelula pela grade, com e sem nome do eixo", () => {
  const a = acharCelula(lerCombinacao("Cor: preta, Tamanho: g"), celulas, grade, "Camiseta lisa");
  assert.equal(a.ok && a.celula.id, "c1");
  const b = acharCelula(lerCombinacao("P / Branca"), celulas, grade, "Camiseta lisa");
  assert.equal(b.ok && b.celula.id, "c2");
  const falta = acharCelula(lerCombinacao("G"), celulas, grade, "Camiseta lisa");
  assert.equal(falta.ok, false);
  assert.match(!falta.ok ? falta.erro : "", /diga cor/);
  assert.equal(acharCelula(lerCombinacao("XG / Preta"), celulas, grade, "Camiseta lisa").ok, false);
  /* célula inativa (saiu da grade) não é achada */
  assert.equal(acharCelula(lerCombinacao("G / Branca"), celulas, grade).ok, false);
  /* sem grade: a célula única, a combinação não importa */
  const unica = acharCelula([], [{ id: "u", valor1: null, valor2: null }], [], "DTF");
  assert.equal(unica.ok && unica.celula.id, "u");
});

test("escolhaDoProduto monta o selected_options pelas opções do cadastro", () => {
  const atributos = [
    { name: "Tamanho", options: [{ id: "o1", label: "G" }, { id: "o2", label: "P" }] },
    { name: "Cor", options: ["Preta", "Branca"] },
  ];
  const ok = escolhaDoProduto(lerCombinacao("g / Preta"), atributos);
  assert.equal(ok.ok, true);
  assert.deepEqual(ok.ok && ok.selected, {
    options: [
      { option_id: "o1", attribute_name: "Tamanho", label: "G" },
      { option_id: null, attribute_name: "Cor", label: "Preta" },
    ],
  });
  assert.equal(ok.ok && ok.texto, "Tamanho: G, Cor: Preta");
  const ruim = escolhaDoProduto(lerCombinacao("Cor: Azul"), atributos);
  assert.equal(ruim.ok, false);
  assert.match(!ruim.ok ? ruim.erro : "", /Opções: Preta, Branca/);
  const vazio = escolhaDoProduto([], atributos);
  assert.equal(vazio.ok && vazio.selected, null);
});

test("textos e mínimo", () => {
  assert.equal(rotuloDaCelula("Camiseta lisa", "G", "Preta"), "Camiseta lisa (G / Preta)");
  assert.equal(rotuloDaCelula("DTF", null, null), "DTF");
  assert.equal(textoDaGrade(grade), "Tamanho (P, M, G) × Cor (Branca, Preta)");
  assert.equal(textoDaGrade([]), null);
  assert.equal(estaBaixo(2, 3, null), true);
  assert.equal(estaBaixo(5, null, 3), false);
  assert.equal(estaBaixo(0, null, null), false);
});
