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

import {
  ICONES,
  caminhoNoDeposito,
  corHex,
  descreverDestino,
  iconePeloNome,
  instanteBr,
  instanteEmBrasilia,
  limitar,
  linkHttps,
  montarSelos,
  montarTarja,
  moverPara,
  novaOrdem,
  posicoesQueMudam,
  selosGravados,
  slugValido,
  tarjaGravada,
} from "./ferramentas/loja-vitrine-regras.ts";

/* ------------------------------------------------------------- ícones */

test("os ícones do assistente são os mesmos da tela de banners", () => {
  const arquivo = readFileSync(new URL("../../app/dashboard/catalog/banners/page.tsx", import.meta.url), "utf8");
  const daTela = [...arquivo.matchAll(/\{ value: "([a-zA-Z]+)", label: "[^"]+", Icon:/g)].map((m) => m[1]);
  assert.deepEqual(daTela, ICONES.map((i) => i.chave));
});

test("ícone pelo nome em português, com ou sem acento, ou pela chave", () => {
  assert.equal(iconePeloNome("caminhão"), "truck");
  assert.equal(iconePeloNome("Caminhao"), "truck");
  assert.equal(iconePeloNome("truck"), "truck");
  assert.equal(iconePeloNome("Cartão"), "creditCard");
  assert.equal(iconePeloNome("creditCard"), "creditCard");
  assert.equal(iconePeloNome("credit-card"), "creditCard");
  assert.equal(iconePeloNome("segurança"), "shieldCheck");
  assert.equal(iconePeloNome("Localização"), "mapPin");
  assert.equal(iconePeloNome("atendimento"), "headphones");
  assert.equal(iconePeloNome("relógio"), "clock");
  assert.equal(iconePeloNome("foguete"), null);
  assert.equal(iconePeloNome(""), null);
});

test("tarja: exatamente 3 itens, ícone conhecido e título", () => {
  const ok = montarTarja([
    { icone: "caminhão", titulo: "Frete grátis", subtitulo: "Acima de R$ 200" },
    { icone: "cartão", titulo: " Parcele  em 3x ", subtitulo: "" },
    { icone: "garantia", titulo: "<b>Garantia</b>" },
  ]);
  assert.ok(ok.ok);
  assert.deepEqual(ok.valor, [
    { icon: "truck", title: "Frete grátis", subtitle: "Acima de R$ 200" },
    { icon: "creditCard", title: "Parcele em 3x", subtitle: "" },
    { icon: "badgeCheck", title: "Garantia", subtitle: "" },
  ]);
  assert.equal(montarTarja([{ icone: "caminhão", titulo: "a" }]).ok, false);
  const ruim = montarTarja([
    { icone: "foguete", titulo: "a" },
    { icone: "pacote", titulo: "b" },
    { icone: "pacote", titulo: "c" },
  ]);
  assert.equal(ruim.ok, false);
  assert.match(!ruim.ok ? ruim.erro : "", /Caminhão/);
});

test("selos: exatamente 2", () => {
  assert.ok(montarSelos([{ icone: "caminhão", titulo: "Entrega" }, { icone: "segurança", titulo: "Garantia" }]).ok);
  assert.equal(montarSelos([{ icone: "caminhão", titulo: "Entrega" }]).ok, false);
  assert.equal(montarSelos([{ icone: "caminhão", titulo: "" }, { icone: "caminhão", titulo: "x" }]).ok, false);
});

test("o que está gravado é completado com o padrão, como a tela lê", () => {
  assert.equal(tarjaGravada(null).length, 3);
  assert.equal(tarjaGravada([{ icon: "clock", title: "Rápido", subtitle: "" }])[0].icon, "clock");
  assert.equal(tarjaGravada([{ icon: "clock", title: "Rápido" }])[1].icon, "creditCard");
  assert.equal(selosGravados("lixo").length, 2);
  assert.equal(selosGravados([{}, { icon: "mapPin", title: "Loja física" }])[0].icon, "mapPin");
});

/* ---------------------------------------------------- limites e números */

test("prova social: os limites da tela", () => {
  assert.equal(limitar(3, 5, 120, 18), 5);
  assert.equal(limitar(500, 5, 120, 18), 120);
  assert.equal(limitar(30, 5, 120, 18), 30);
  assert.equal(limitar(0, 5, 120, 18), 18);
  assert.equal(limitar("abc", 2, 20, 5), 5);
  assert.equal(limitar(7.6, 1, 5, 2), 5);
});

/* ------------------------------------------------------- cores e links */

test("cor em código", () => {
  assert.equal(corHex("#1f6feb"), "#1F6FEB");
  assert.equal(corHex("fff"), "#FFFFFF");
  assert.equal(corHex("vermelho"), null);
  assert.equal(corHex("#12345"), null);
});

test("link só https, completo e sem espaço", () => {
  assert.equal(linkHttps("https://loja.com.br/promo"), "https://loja.com.br/promo");
  assert.equal(linkHttps("http://loja.com.br"), null);
  assert.equal(linkHttps("javascript:alert(1)"), null);
  assert.equal(linkHttps("https://loja com"), null);
  assert.equal(linkHttps("https://localhost/x"), null);
  assert.equal(linkHttps("https://user:senha@loja.com.br"), null);
  assert.equal(linkHttps("catalog://product/1"), null);
});

test("slug de categoria", () => {
  assert.equal(slugValido("Canecas-Personalizadas"), "canecas-personalizadas");
  assert.equal(slugValido("canecas personalizadas"), null);
  assert.equal(slugValido("../x"), null);
});

test("destino do botão da faixa, como a tela lê", () => {
  assert.deepEqual(descreverDestino("catalog://product/abc"), { tipo: "produto", valor: "abc" });
  assert.deepEqual(descreverDestino("catalog://category/canecas"), { tipo: "categoria", valor: "canecas" });
  assert.deepEqual(descreverDestino("catalog://subcategory/brancas"), { tipo: "subcategoria", valor: "brancas" });
  assert.deepEqual(descreverDestino("https://x.com.br"), { tipo: "link", valor: "https://x.com.br" });
  assert.deepEqual(descreverDestino(""), { tipo: "nenhum", valor: null });
});

/* --------------------------------------------------------------- datas */

test("contagem regressiva no horário de Brasília", () => {
  assert.equal(instanteEmBrasilia("2026-10-31", "23:59"), "2026-11-01T02:59:00.000Z");
  assert.equal(instanteEmBrasilia("2026-10-31"), "2026-11-01T02:59:00.000Z");
  assert.equal(instanteEmBrasilia("2026-13-01", "10:00"), null);
  assert.equal(instanteEmBrasilia("2026-10-31", "25:00"), null);
  assert.equal(instanteBr("2026-11-01T02:59:00.000Z"), "31/10/2026 23:59");
  assert.equal(instanteBr(null), null);
});

/* --------------------------------------------------------------- ordem */

test("nova ordem: ids pedidos na frente, o resto como estava", () => {
  assert.deepEqual(novaOrdem(["a", "b", "c", "d"], ["c", "a"]), { ok: true, valor: ["c", "a", "b", "d"] });
  assert.equal(novaOrdem(["a", "b"], ["x"]).ok, false);
  assert.equal(novaOrdem(["a", "b"], ["a", "a"]).ok, false);
});

test("mover para uma posição", () => {
  assert.deepEqual(moverPara(["a", "b", "c", "d"], "d", 1), ["d", "a", "b", "c"]);
  assert.deepEqual(moverPara(["a", "b", "c", "d"], "a", 3), ["b", "c", "a", "d"]);
  assert.deepEqual(moverPara(["a", "b", "c"], "a", 99), ["b", "c", "a"]);
  assert.deepEqual(moverPara(["a", "b", "c"], "c", 0), ["c", "a", "b"]);
});

test("só regrava a posição de quem muda", () => {
  const linhas = [
    { id: "a", position: 1 },
    { id: "b", position: 2 },
    { id: "c", position: 3 },
  ];
  assert.deepEqual(posicoesQueMudam(linhas, ["a", "c", "b"], 1), [
    { id: "c", position: 2 },
    { id: "b", position: 3 },
  ]);
  assert.deepEqual(posicoesQueMudam(linhas, ["a", "b", "c"], 0), [
    { id: "a", position: 0 },
    { id: "b", position: 1 },
    { id: "c", position: 2 },
  ]);
});

/* ------------------------------------------------------------ arquivos */

test("só apaga arquivo da pasta permitida", () => {
  const base = "https://x.supabase.co/storage/v1/object/public/products/";
  assert.equal(caminhoNoDeposito(`${base}stories/abc_1.webp`, "stories"), "stories/abc_1.webp");
  assert.equal(caminhoNoDeposito(`${base}banners/p1/abc.webp?v=1`, "banners/p1"), "banners/p1/abc.webp");
  assert.equal(caminhoNoDeposito(`${base}banners/p2/abc.webp`, "banners/p1"), null);
  assert.equal(caminhoNoDeposito(`${base}produtos/foto.jpg`, "stories"), null);
  assert.equal(caminhoNoDeposito(`${base}stories/../produtos/foto.jpg`, "stories"), null);
  assert.equal(caminhoNoDeposito("https://outro.site/stories/a.webp", "stories"), null);
});
