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

import {
  arranjoAutomaticoDaBoutique,
  arranjoAutomaticoDoVendor,
  destinoDaSecao,
  lerBanner,
  lerGrade,
  lerMensagemDaLoja,
  lerMensagemDoPainel,
  modoDaSecao,
  secoesParaOsTemasAntigos,
  urlDeImagem,
  CANAL_DO_EDITOR,
} from "./pagina-inicial.ts";
import { criarPassagemDoEditor, lerPassagemDoEditor } from "./passagem-do-editor.ts";

test("o modo das seções antigas é lido como a loja sempre leu", () => {
  assert.equal(modoDaSecao({ config: { mode: "category_products" }, section_type: "manual_products" }), "category_products");
  assert.equal(modoDaSecao({ config: { image_url: "https://x/y.png" }, section_type: "manual_products" }), "image_banner");
  assert.equal(modoDaSecao({ config: null, section_type: "all_products" }), "all_products");
  assert.equal(modoDaSecao({ config: { mode: "qualquer" }, section_type: "manual_products" }), "manual_products");
  assert.equal(modoDaSecao({ config: JSON.stringify({ mode: "image_grid" }) }), "image_grid");
});

test("imagem só entra com endereço de página", () => {
  assert.equal(urlDeImagem("https://a.supabase.co/x.png"), "https://a.supabase.co/x.png");
  assert.equal(urlDeImagem("javascript:alert(1)"), "");
  assert.equal(urlDeImagem("//outro.site/x.png"), "");
  assert.equal(urlDeImagem("/images/x.png"), "/images/x.png");
});

test("link de produto, categoria e endereço", () => {
  const categorias = [{ id: "c1", slug: "canecas" }];
  assert.deepEqual(destinoDaSecao({ tipo: "produto", produto_id: "p1" }, "aurora"), { href: "/aurora/p/p1", externo: false, novaAba: false });
  assert.deepEqual(destinoDaSecao({ tipo: "categoria", categoria_id: "c1", categoria_slug: "velho" }, "aurora", categorias), {
    href: "/aurora/c/canecas",
    externo: false,
    novaAba: false,
  });
  assert.deepEqual(destinoDaSecao({ tipo: "url", url: "www.site.com.br", nova_aba: true }, "aurora"), {
    href: "https://www.site.com.br",
    externo: true,
    novaAba: true,
  });
  assert.equal(destinoDaSecao({ tipo: "url", url: "javascript:alert(1)" }, "aurora"), null);
  assert.equal(destinoDaSecao({ tipo: "nenhum" }, "aurora"), null);
});

test("banner antigo continua sem formato e com o link de antes", () => {
  const banner = lerBanner({ mode: "image_banner", image_url: "https://x/b.svg", link_url: "/aurora/c/x", open_in_new_tab: true });
  assert.equal(banner.formato, null);
  assert.deepEqual(banner.link, { tipo: "url", url: "/aurora/c/x", nova_aba: true });
  assert.equal(lerBanner({ formato: "cinema" }).formato, "cinema");
});

test("a grade corta as imagens pelo layout", () => {
  const itens = Array.from({ length: 6 }, (_, i) => ({ imagem: `https://x/${i}.png` }));
  assert.equal(lerGrade({ layout: "2", itens }).itens.length, 2);
  assert.equal(lerGrade({ layout: "1+2", itens }).itens.length, 3);
  assert.equal(lerGrade({ layout: "lixo", itens }).layout, "3");
});

test("tipos novos viram tipos antigos nos temas Padrão e Vitrine", () => {
  const produtos = [
    { id: "p1", category_id: "c1", image_url: "https://x/p1.png" },
    { id: "p2", category_id: "c2", image_url: "https://x/p2.png" },
    { id: "p3", category_id: "c1", image_url: "https://x/p3.png" },
  ];
  const categorias = [
    { id: "c1", name: "Canecas", slug: "canecas", parent_id: null },
    { id: "c2", name: "Camisetas", slug: "camisetas", parent_id: null },
    { id: "c3", name: "Brancas", slug: "brancas", parent_id: "c2" },
  ];
  const [destaques, circulos, soDela, intacta] = secoesParaOsTemasAntigos(
    [
      { id: "a", section_type: "manual_products", config: { mode: "featured_products", quantidade: 2 }, products: [] },
      { id: "b", section_type: "manual_products", config: { mode: "category_circles" }, products: [] },
      { id: "c", section_type: "manual_products", config: { mode: "category_products", target_category_id: "c1", so_da_categoria: true }, products: [] },
      { id: "d", section_type: "manual_products", config: { mode: "category_products", target_category_id: "c1" }, products: [] },
    ],
    produtos,
    categorias
  );
  assert.equal((destaques.config as Record<string, unknown>).mode, "manual_products");
  assert.deepEqual((destaques.products as Array<{ id: string }>).map((p) => p.id), ["p1", "p2"]);
  const itens = (circulos.config as unknown as { items: Array<{ target_category_id: string; image_url: string }> }).items;
  assert.deepEqual(itens.map((i) => i.target_category_id), ["c1", "c2"]);
  assert.equal(itens[0].image_url, "https://x/p1.png");
  assert.equal((soDela.config as Record<string, unknown>).mode, "subcategory_products");
  assert.equal((intacta.config as Record<string, unknown>).mode, "category_products");
});

test("a home automática do Vendor vira seções na mesma ordem", () => {
  const produtos = [
    { id: "p1", category_id: "c1" },
    { id: "p2", category_id: "c1" },
    { id: "p3", category_id: "c2" },
    { id: "p4", category_id: "c2" },
    { id: "p5", category_id: "c3" },
  ];
  const categorias = [
    { id: "c1", name: "Canecas", slug: "canecas", parent_id: null },
    { id: "c2", name: "Camisetas", slug: "camisetas", parent_id: null },
    { id: "c3", name: "Agendas", slug: "agendas", parent_id: null },
  ];
  const banners = [
    { id: "b1", image_url: "https://x/1.png" },
    { id: "b2", image_url: "https://x/2.png", link_type: "product", product_id: "p1" },
    { id: "b3", image_url: "https://x/3.png", link_type: "url", link_url: "https://site.com" },
  ];
  const lista = arranjoAutomaticoDoVendor(produtos, categorias, banners);
  assert.deepEqual(
    lista.map((s) => s.config.mode),
    ["category_circles", "featured_products", "category_products", "image_grid", "category_products"]
  );
  assert.equal(lista[1].title, "Mais vendidos");
  assert.equal(lista[2].config.so_da_categoria, true);
  const itens = lista[3].config.itens as Array<{ imagem: string; link: { tipo: string } }>;
  assert.deepEqual(itens.map((i) => i.imagem), ["https://x/2.png", "https://x/3.png"]);
  assert.deepEqual(itens.map((i) => i.link.tipo), ["produto", "url"]);

  /* Sem categoria com dois produtos: só "Mais vendidos". Sem produto: nada. */
  assert.deepEqual(arranjoAutomaticoDoVendor([{ id: "p1" }], [], []).map((s) => s.title), ["Mais vendidos"]);
  assert.deepEqual(arranjoAutomaticoDoVendor([], [], []), []);
});

test("mensagens fora do canal ou do formato são ignoradas", () => {
  assert.equal(lerMensagemDoPainel({ tipo: "rascunho", secoes: [] }), null);
  assert.equal(lerMensagemDoPainel("texto"), null);
  const rascunho = lerMensagemDoPainel({
    canal: CANAL_DO_EDITOR,
    tipo: "rascunho",
    selecionada: "x",
    secoes: [{ id: "x", title: "Oi", config: { mode: "image_grid" }, produtos: ["p1", 5] }, { semId: true }],
  });
  assert.ok(rascunho && rascunho.tipo === "rascunho");
  assert.equal(rascunho.secoes.length, 1);
  assert.deepEqual(rascunho.secoes[0].produtos, ["p1", "5"]);
  assert.equal(lerMensagemDaLoja({ canal: CANAL_DO_EDITOR, tipo: "acao", acao: "apagar-tudo", id: "x" }), null);
  assert.deepEqual(lerMensagemDaLoja({ canal: CANAL_DO_EDITOR, tipo: "acao", acao: "subir", id: "x" }), {
    canal: CANAL_DO_EDITOR,
    tipo: "acao",
    acao: "subir",
    id: "x",
  });
});

test("a passagem do editor só vale íntegra, no prazo, para a loja e o dono certos", () => {
  const chave = "segredo-de-teste";
  const agora = 1_800_000_000;
  const passagem = criarPassagemDoEditor({ dono: "u1", slug: "Aurora", origemDoPainel: "https://admin.ktalogu.com.br", agoraS: agora }, chave);
  const lida = lerPassagemDoEditor(passagem, { dono: "u1", slug: "aurora" }, chave, agora + 10);
  assert.ok(lida);
  assert.equal(lida.origemDoPainel, "https://admin.ktalogu.com.br");

  assert.equal(lerPassagemDoEditor(passagem, { dono: "u2", slug: "aurora" }, chave, agora), null, "outro dono");
  assert.equal(lerPassagemDoEditor(passagem, { dono: "u1", slug: "metra" }, chave, agora), null, "outra loja");
  assert.equal(lerPassagemDoEditor(passagem, { dono: "u1", slug: "aurora" }, "outra-chave", agora), null, "outra chave");
  assert.equal(lerPassagemDoEditor(passagem, { dono: "u1", slug: "aurora" }, chave, agora + 3 * 3600), null, "vencida");
  const [carga, assinatura] = passagem.split(".");
  const adulterada = Buffer.from(
    JSON.stringify({ ...JSON.parse(Buffer.from(carga, "base64url").toString()), o: "https://ruim.com" })
  ).toString("base64url");
  assert.equal(lerPassagemDoEditor(`${adulterada}.${assinatura}`, { dono: "u1", slug: "aurora" }, chave, agora), null, "adulterada");
  const comHttp = criarPassagemDoEditor({ dono: "u1", slug: "aurora", origemDoPainel: "http://admin.ktalogu.com.br", agoraS: agora }, chave);
  assert.equal(lerPassagemDoEditor(comHttp, { dono: "u1", slug: "aurora" }, chave, agora), null, "http fora do localhost");
  const local = criarPassagemDoEditor({ dono: "u1", slug: "aurora", origemDoPainel: "http://localhost:3002", agoraS: agora }, chave);
  assert.equal(lerPassagemDoEditor(local, { dono: "u1", slug: "aurora" }, chave, agora)?.origemDoPainel, "http://localhost:3002");
});

test("a home automática da Boutique segue a ordem da referência e só põe o que tem dado", () => {
  const categorias = [
    { id: "vestidos", name: "Vestidos", slug: "vestidos", parent_id: null },
    { id: "longos", name: "Longos", slug: "longos", parent_id: "vestidos" },
    { id: "conjuntos", name: "Conjuntos", slug: "conjuntos", parent_id: null },
  ];
  const foto = (n: string) => [
    { image_url: `https://x/${n}-1.png`, is_primary: true, sort_order: 0 },
    { image_url: `https://x/${n}-modelo.png`, is_primary: false, sort_order: 1 },
  ];
  const produtos = [
    { id: "a", category_id: "longos", product_images: foto("a") },
    { id: "b", category_id: "vestidos", product_images: foto("b") },
    { id: "c", category_id: "conjuntos", product_images: foto("c") },
    { id: "d", category_id: "conjuntos" },
    { id: "e", category_id: "vestidos" },
  ];
  const semVenda = arranjoAutomaticoDaBoutique(produtos, categorias, { nomeDaLoja: "Femme" });
  assert.deepEqual(
    semVenda.map((s) => s.config.mode),
    ["featured_products", "category_navigator", "auto_list", "category_products"]
  );
  /* Os cards usam a foto da modelo (a 2ª) e a maior categoria conta as filhas. */
  const itens = semVenda[1].config.items as Array<{ target_category_id: string; image_url: string }>;
  assert.equal(itens[0].target_category_id, "vestidos");
  assert.equal(itens[0].image_url, "https://x/a-modelo.png");
  assert.equal(semVenda[3].config.target_category_id, "vestidos");

  const completa = arranjoAutomaticoDaBoutique(produtos, categorias, {
    nomeDaLoja: "Femme",
    maisVendidos: ["c", "a", "zzz"],
    combos: [{ main_product_id: "a", combo_product_id: "c" }],
  });
  assert.deepEqual(
    completa.map((s) => `${s.config.mode}${s.config.lista ? `:${s.config.lista}` : ""}`),
    ["featured_products", "category_navigator", "auto_list:lancamentos", "auto_list:mais_vendidos", "combo_highlight"]
  );
  assert.equal(completa[4].title, "Elas vestem Femme");
  /* Kit com peça que a loja não mostra não vira look. */
  const kitEscondido = arranjoAutomaticoDaBoutique(produtos, categorias, { combos: [{ main_product_id: "a", combo_product_id: "fora" }] });
  assert.ok(!kitEscondido.some((s) => s.config.mode === "combo_highlight"));
  assert.deepEqual(arranjoAutomaticoDaBoutique([], categorias), []);
});
