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

import {
  avisosDoCarrinho,
  combinacaoDaEscolha,
  esgotadoNaVitrine,
  estoqueDaEscolha,
  fraseDoCarrinho,
  marcarProduto,
  problemasDoV2,
} from "./estoque-v2-da-loja.ts";
import { estaEsgotado, estoqueLimitaAVenda, semEsgotados } from "./loja/regras-da-loja.ts";

/*
  Estoque v2 na loja: quem decide é o banco (estoque_disponivel /
  estoque_conferir_itens). Aqui só a tradução para a tela, e a prova de que
  a regra única (estoqueLimitaAVenda/estaEsgotado) obedece às marcas do v2
  sem mudar NADA para quem está fora dele.
*/

test("fora do v2: a regra de sempre, intacta", () => {
  assert.equal(estoqueLimitaAVenda({ track_inventory: true, allow_negative_stock: false }), true);
  assert.equal(estoqueLimitaAVenda({ track_inventory: true, allow_negative_stock: true }), false);
  assert.equal(estaEsgotado({ track_inventory: true, allow_negative_stock: false, stock: 0 }), true);
  assert.equal(estaEsgotado({ track_inventory: false, stock: 0 }), false);
});

test("no v2 vale a marca do banco, não os campos antigos", () => {
  /* Encomenda: os campos antigos dizem "não controla", mas o insumo da composição limita. */
  const encomendaSemInsumo = { track_inventory: false, stock: 0, estoque_v2: true, estoque_v2_limita: true, estoque_v2_esgotado: true };
  assert.equal(estoqueLimitaAVenda(encomendaSemInsumo), true);
  assert.equal(estaEsgotado(encomendaSemInsumo), true);
  /* Pronto que permite negativo: zerado no espelho, mas vende. */
  const prontoNegativo = { track_inventory: true, allow_negative_stock: false, stock: 0, estoque_v2: true, estoque_v2_limita: false, estoque_v2_esgotado: false };
  assert.equal(estoqueLimitaAVenda(prontoNegativo), false);
  assert.equal(estaEsgotado(prontoNegativo), false);
  assert.deepEqual(
    semEsgotados([
      { id: "a", ...encomendaSemInsumo },
      { id: "b", ...prontoNegativo },
    ]).map((p) => p.id),
    ["b"]
  );
});

test("vitrine: falta escolher não é esgotado; não controla nunca é", () => {
  assert.equal(esgotadoNaVitrine({ limita: true, cabe: false, motivo: null }), true);
  assert.equal(esgotadoNaVitrine({ limita: true, cabe: false, motivo: "falta_escolher" }), false);
  assert.equal(esgotadoNaVitrine({ limita: false, cabe: true, motivo: null }), false);
  assert.equal(esgotadoNaVitrine(null), false);
  const marcado = marcarProduto({ id: "p" }, { limita: true, cabe: false, motivo: "falta_escolher" });
  assert.equal(marcado.estoque_v2, true);
  assert.equal(marcado.estoque_v2_limita, false);
  assert.equal(marcado.estoque_v2_esgotado, false);
});

test("a combinação escrita para o cliente, sem os serviços", () => {
  const escolha = {
    options: [
      { attribute_name: "Tamanho", label: "G" },
      { attribute_name: "Cor", label: "Preta" },
      { attribute_name: "Prazo", label: "Expressa" },
    ],
  };
  assert.equal(combinacaoDaEscolha(escolha, ["Tamanho", "Cor"]), "G / Preta");
  assert.equal(combinacaoDaEscolha(escolha), "G / Preta / Expressa");
  assert.equal(combinacaoDaEscolha(null), "");
});

test("a escolha da página: esgotado, sem limite, falta escolher", () => {
  assert.equal(estoqueDaEscolha({ v2: false }), null);
  const esgotado = estoqueDaEscolha({ v2: true, limita: true, cabe: false, disponivel: 0 }, { combinacao: "G / Preta" });
  assert.deepEqual(esgotado, { v2: true, limita: true, disponivel: 0, cabe: false, motivo: null, aviso: "Esgotado em G / Preta." });
  const livre = estoqueDaEscolha({ v2: true, limita: false, cabe: true, disponivel: null });
  assert.equal(livre?.limita, false);
  assert.equal(livre?.disponivel, null);
  assert.equal(livre?.aviso, null);
  const cinco = estoqueDaEscolha({ v2: true, limita: true, cabe: true, disponivel: 5 });
  assert.equal(cinco?.disponivel, 5);
  assert.equal(cinco?.aviso, null);
  /* Ainda escolhendo: sem aviso. Escolha completa que o estoque não acha: avisa. */
  const falta = { v2: true, limita: true, cabe: false, disponivel: 0, motivo: "falta_escolher", itens: [{ sem_celula: true, falta_escolher: "tamanho e cor" }] };
  assert.equal(estoqueDaEscolha(falta)?.aviso, null);
  assert.equal(estoqueDaEscolha(falta, { escolhaCompleta: true })?.aviso, "Escolha tamanho e cor para ver se tem em estoque.");
});

test("carrinho: frase por item com a combinação, nunca o insumo", () => {
  const itens = [
    { title: "Camisetas", selected_options: { options: [{ attribute_name: "Tamanho", label: "G" }, { attribute_name: "Cor", label: "Preta" }] } },
    { title: "Caneca" },
  ];
  const problemas = [
    { indice: 0, celula_id: "c1", disponivel: 0, mensagem: 'Acabou o estoque de "Camiseta lisa (G / Preta)"…' },
    { indice: 1, celula_id: "c2", disponivel: 2 },
  ];
  assert.equal(problemasDoV2(problemas), true);
  assert.equal(problemasDoV2([{ indice: 0, mensagem: "x" }]), false);
  const avisos = avisosDoCarrinho(problemas, itens);
  assert.equal(avisos.get(0), "Camisetas (G / Preta): esgotado.");
  assert.equal(avisos.get(1), "Caneca: só 2 disponíveis.");
  assert.equal(fraseDoCarrinho(avisos), "Camisetas (G / Preta): esgotado. Caneca: só 2 disponíveis. Ajuste o carrinho e tente de novo.");
  assert.equal(fraseDoCarrinho(new Map()), null);
  assert.equal(avisosDoCarrinho([{ indice: 0, celula_id: null }], itens).get(0), "Camisetas (G / Preta): esta combinação não está disponível no momento.");
});
