/*
  Modelos prontos da página inicial: um toque monta um RASCUNHO da home com
  os dados da PRÓPRIA loja (categorias, produtos, banners, cupom, corte de
  produção, endereço). Nunca publica sozinho: a pessoa olha, mexe e publica.

  Regra dos textos: nada inventado. Preço, frete grátis, prazo, desconto,
  "fazemos a arte" só entram quando a loja tem o dado (cupom ativo, corte
  ligado, endereço...). Sem o dado, frase neutra.

  Regras puras, sem "@/": o teste roda sozinho (modelos-da-pagina-inicial.test.ts).
*/

import { ehFamiliaVendor, secaoNova, type Modo, type SecaoDoEditor, type Tema } from "./pagina-inicial.ts";

export type ChaveDoModelo = "grafica_rapida" | "brindes_corporativos" | "comunicacao_visual" | "personalizados";

export const MODELOS_PRONTOS: Array<{ chave: ChaveDoModelo; nome: string; resumo: string }> = [
  { chave: "grafica_rapida", nome: "Gráfica rápida", resumo: "Categorias em círculos, corte do dia, mais pedidos, como pedir e dúvidas de impressão." },
  { chave: "brindes_corporativos", nome: "Brindes corporativos", resumo: "Linhas de brindes por categoria, personalização com a marca e dúvidas de empresa." },
  { chave: "comunicacao_visual", nome: "Comunicação visual", resumo: "Categorias de placas, adesivos e lonas, do arquivo à peça pronta, e onde estamos." },
  { chave: "personalizados", nome: "Personalizados", resumo: "Lançamentos, mais vendidos, kits e o que o cliente já viu, para presentes e datas." },
];

export function ehModeloPronto(valor: unknown): valor is ChaveDoModelo {
  return MODELOS_PRONTOS.some((m) => m.chave === valor);
}

export type DadosParaOModelo = {
  tema: Tema;
  /* Os temas Padrão e Vitrine já mostram os banners no topo quando o carrossel do topo está ligado. */
  carrosselDoTopoLigado: boolean;
  categorias: Array<{ id: string; name: string; slug: string; parent_id?: string | null }>;
  produtos: Array<{ id: string; name: string; category_id?: string | null; image_url?: string | null }>;
  banners: Array<{ image_url: string; link_type?: string | null; product_id?: string | null; link_url?: string | null; open_in_new_tab?: boolean | null }>;
  cupom: { id: string; code: string } | null;
  corte: { ligado: boolean; hora: string | null };
  temEndereco: boolean;
  temWhatsapp: boolean;
  temCombos: boolean;
};

function linkDoBanner(banner: DadosParaOModelo["banners"][number]) {
  if (banner.link_type === "product" && banner.product_id) return { tipo: "produto", produto_id: banner.product_id, nova_aba: banner.open_in_new_tab === true };
  if (banner.link_type === "url" && banner.link_url) return { tipo: "url", url: banner.link_url, nova_aba: banner.open_in_new_tab === true };
  return { tipo: "nenhum" };
}

function hora(texto: string | null) {
  const achado = /^(\d{1,2}):(\d{2})/.exec(String(texto ?? ""));
  if (!achado) return null;
  const h = Number(achado[1]);
  const m = Number(achado[2]);
  return m ? `${h}h${String(m).padStart(2, "0")}` : `${h}h`;
}

/** As categorias principais com mais produtos (as que enchem uma seção). */
export function categoriasMaisCheias(dados: Pick<DadosParaOModelo, "categorias" | "produtos">, quantas: number) {
  const contagem = new Map<string, number>();
  const pai = new Map(dados.categorias.map((c) => [c.id, c.parent_id ?? null]));
  const raizDe = (id: string) => {
    let atual: string | null = id;
    for (let i = 0; i < 6 && atual && pai.get(atual); i += 1) atual = pai.get(atual) ?? null;
    return atual;
  };
  for (const produto of dados.produtos) {
    if (!produto.category_id) continue;
    const raiz = raizDe(produto.category_id);
    if (raiz) contagem.set(raiz, (contagem.get(raiz) ?? 0) + 1);
  }
  return dados.categorias
    .filter((c) => !c.parent_id && (contagem.get(c.id) ?? 0) >= 2)
    .sort((a, b) => (contagem.get(b.id) ?? 0) - (contagem.get(a.id) ?? 0) || a.name.localeCompare(b.name, "pt-BR"))
    .slice(0, quantas);
}

type Pergunta = { pergunta: string; resposta: string };

const PERGUNTAS: Record<ChaveDoModelo, Pergunta[]> = {
  grafica_rapida: [
    { pergunta: "Como envio a minha arte?", resposta: "Depois de escolher o produto, você envia o arquivo pelo pedido ou pelo nosso atendimento. Prefira PDF ou imagem em alta resolução, no tamanho final." },
    { pergunta: "Em quanto tempo fica pronto?", resposta: "O prazo depende do produto e da quantidade. Ele aparece no produto ou no orçamento antes de você fechar o pedido." },
    { pergunta: "Vejo como vai ficar antes de imprimir?", resposta: "Fale com a gente pelo atendimento: combinamos a conferência da arte antes de o pedido entrar na produção." },
    { pergunta: "Como acompanho o meu pedido?", resposta: "Depois de fechar, você recebe o link do pedido para acompanhar cada etapa até a entrega ou a retirada." },
  ],
  brindes_corporativos: [
    { pergunta: "Qual é a quantidade mínima?", resposta: "Cada brinde tem a sua quantidade mínima, que aparece na página do produto. Para quantidades maiores, peça um orçamento." },
    { pergunta: "Vocês gravam a marca da minha empresa?", resposta: "A personalização disponível aparece em cada produto. Envie o logotipo em boa resolução (de preferência em vetor) e confirmamos antes de produzir." },
    { pergunta: "Qual é o prazo de produção?", resposta: "O prazo depende do brinde, da personalização e da quantidade. Ele é informado no orçamento, antes da aprovação." },
    { pergunta: "Emitem nota fiscal para empresa?", resposta: "Fale com o nosso atendimento com os dados da empresa para combinarmos a emissão." },
  ],
  comunicacao_visual: [
    { pergunta: "Que arquivo devo enviar?", resposta: "PDF ou imagem em alta resolução, no tamanho final da peça. Se tiver dúvida sobre medidas, fale com a gente antes de enviar." },
    { pergunta: "Vocês fazem a arte?", resposta: "Fale com o nosso atendimento: contamos se fazemos a criação para o seu caso e quanto fica, junto com o orçamento." },
    { pergunta: "Como funciona o preço por metro quadrado?", resposta: "Nos produtos vendidos por medida, você informa a largura e a altura e o valor é calculado na hora, pelo tamanho da peça." },
    { pergunta: "Como acompanho o meu pedido?", resposta: "Depois de fechar, você recebe o link do pedido para acompanhar cada etapa." },
  ],
  personalizados: [
    { pergunta: "Posso personalizar com nome ou foto?", resposta: "As opções de personalização aparecem em cada produto. Você escolhe e envia o que precisa ao fazer o pedido." },
    { pergunta: "Em quanto tempo fica pronto?", resposta: "O prazo depende do produto e da quantidade e aparece antes de você fechar o pedido." },
    { pergunta: "Como acompanho o meu pedido?", resposta: "Depois de fechar, você recebe o link do pedido para acompanhar cada etapa até a entrega." },
  ],
};

const COMO_PEDIR: Record<ChaveDoModelo, { titulo: string; chamada: string; texto: string }> = {
  grafica_rapida: {
    titulo: "Como fazer o seu pedido",
    chamada: "Simples assim",
    texto: "- **Escolha** o produto e a quantidade\n- **Envie** a sua arte (ou fale com a gente)\n- **Acompanhe** a produção pelo link do pedido",
  },
  brindes_corporativos: {
    titulo: "Brindes com a sua marca",
    chamada: "Para empresas e eventos",
    texto: "Escolha os brindes, a quantidade e a personalização. **Envie o logotipo** da empresa e acompanhe o pedido do orçamento até a entrega.",
  },
  comunicacao_visual: {
    titulo: "Do arquivo à peça pronta",
    chamada: "Como funciona",
    texto: "- **Escolha** o material e informe as medidas\n- **Envie** o arquivo no tamanho final\n- **Acompanhe** cada etapa pelo link do pedido",
  },
  personalizados: {
    titulo: "Feito do seu jeito",
    chamada: "Presentes e datas especiais",
    texto: "Escolha o produto, **personalize** com o que quiser e acompanhe o pedido até chegar.",
  },
};

function com(modo: Modo, mudar: (secao: SecaoDoEditor) => SecaoDoEditor = (s) => s): SecaoDoEditor {
  return mudar(secaoNova(modo));
}

function frasesDaFaixa(dados: DadosParaOModelo): string[] {
  const frases: string[] = [];
  const horaDoCorte = dados.corte.ligado ? hora(dados.corte.hora) : null;
  if (horaDoCorte) frases.push(`Pedidos até as ${horaDoCorte} entram na produção do dia`);
  if (dados.cupom) frases.push(`Use o cupom ${dados.cupom.code} na sua compra`);
  if (dados.temWhatsapp) frases.push("Tire as suas dúvidas pelo WhatsApp");
  frases.push("Acompanhe o seu pedido pelo link");
  if (dados.temEndereco) frases.push("Retire ou visite a nossa loja");
  return frases.slice(0, 5);
}

/**
 * A página do modelo, com os dados da loja. A grade "Todos os produtos"
 * entra no fim nos temas Padrão e Vitrine (lá ela é fixa).
 */
export function paginaDoModelo(chave: ChaveDoModelo, dados: DadosParaOModelo): SecaoDoEditor[] {
  const lista: SecaoDoEditor[] = [];
  const raizes = dados.categorias.filter((c) => !c.parent_id);
  const cheias = categoriasMaisCheias(dados, chave === "personalizados" ? 2 : 3);
  const fotoDeProduto = dados.produtos.find((p) => /^https:\/\//.test(String(p.image_url || "")))?.image_url || "";
  /* A família Vendor (Vendor e Boutique): banners no topo e sem grade fixa. */
  const vendor = ehFamiliaVendor(dados.tema);

  /* 1. Banners: só quando o topo da loja ainda não mostra os mesmos banners. */
  const topoMostraBanners = vendor || dados.carrosselDoTopoLigado;
  const banners = dados.banners.filter((b) => /^https?:\/\//.test(b.image_url));
  if (!topoMostraBanners && banners.length >= 2) {
    lista.push(
      com("banner_carousel", (s) => ({
        ...s,
        title: "Destaques",
        config: { ...s.config, formato: "panoramico", itens: banners.slice(0, 8).map((b) => ({ imagem: b.image_url, link: linkDoBanner(b) })) },
      }))
    );
  } else if (!topoMostraBanners && banners.length === 1) {
    lista.push(com("image_banner", (s) => ({ ...s, title: "Destaque", config: { ...s.config, formato: "panoramico", image_url: banners[0].image_url, link: linkDoBanner(banners[0]) } })));
  }

  /* 2. A faixa que desliza com o que a loja tem de verdade. */
  if (chave !== "personalizados") {
    lista.push(com("marquee", (s) => ({ ...s, title: "Avisos da loja", config: { ...s.config, itens: frasesDaFaixa(dados), velocidade: "normal" } })));
  }

  /* 3. As categorias em círculos. */
  if (raizes.length >= 2) lista.push(com("category_circles", (s) => ({ ...s, title: chave === "comunicacao_visual" ? "O que você precisa?" : "Categorias", title_align: "center" })));

  /* 4. O corte de produção (só com o corte ligado). */
  if (dados.corte.ligado && dados.corte.hora && (chave === "grafica_rapida" || chave === "comunicacao_visual")) lista.push(com("order_cutoff"));

  /* 5. As listas e as categorias mais cheias. */
  const maisPedidos = com("auto_list", (s) => ({ ...s, title: chave === "brindes_corporativos" ? "Os mais pedidos" : "Mais vendidos", config: { ...s.config, lista: "mais_vendidos", dias: 90, quantidade: 8 } }));
  const lancamentos = com("auto_list", (s) => ({ ...s, title: "Novidades", config: { ...s.config, lista: "lancamentos", dias: 30, quantidade: 8 } }));
  const porCategoria = cheias.map((categoria) =>
    com("category_products", (s) => ({
      ...s,
      title: categoria.name,
      config: { ...s.config, target_category_id: categoria.id, target_category_slug: categoria.slug, show_view_more: true, quantidade: 8 },
    }))
  );
  if (chave === "grafica_rapida") {
    lista.push(maisPedidos, ...porCategoria.slice(0, 2), lancamentos);
  } else if (chave === "brindes_corporativos") {
    lista.push(...porCategoria, maisPedidos);
  } else if (chave === "comunicacao_visual") {
    lista.push(...porCategoria, lancamentos);
  } else {
    lista.push(lancamentos, maisPedidos, ...porCategoria);
  }

  /* 6. O cupom (só cupom ativo). */
  if (dados.cupom) {
    lista.push(com("coupon_highlight", (s) => ({ ...s, title: "Cupom para você", config: { ...s.config, cupom_id: dados.cupom!.id, chamada: "Use na sua compra" } })));
  }

  /* 7. Kits (só com "compre junto" cadastrado). */
  if (chave === "personalizados" && dados.temCombos) lista.push(com("combo_highlight"));

  /* 8. Como pedir, com a foto de um produto da loja. */
  if (fotoDeProduto) {
    const texto = COMO_PEDIR[chave];
    lista.push(
      com("text_image", (s) => ({
        ...s,
        title: texto.titulo,
        config: { ...s.config, chamada: texto.chamada, texto: texto.texto, imagem: fotoDeProduto, lado: "esquerda", proporcao: "quadrado" },
      }))
    );
  }

  if (chave === "personalizados") lista.push(com("recently_viewed"));

  /* 9. Perguntas frequentes e onde estamos. */
  lista.push(com("faq", (s) => ({ ...s, title: "Perguntas frequentes", config: { ...s.config, itens: PERGUNTAS[chave], abrir_primeira: true } })));
  if (dados.temEndereco) lista.push(com("store_location"));

  /* A grade fixa dos temas Padrão e Vitrine fica no fim. */
  if (!vendor) lista.push(com("all_products", (s) => ({ ...s, title: "Todos os produtos" })));
  return lista;
}
