/*
 * As peças que o editor de banners oferece para pôr no banner (textos com
 * estilo pronto, chamadas de venda, formas, logo e fotos), já no tamanho do
 * banner e no centro dele. A biblioteca do editor desenha cada uma com o
 * mesmo HTML do banner, então a prévia é exatamente o que entra.
 */
import {
  FONTE_PADRAO,
  SEM_FILTROS,
  degrade,
  novoId,
  solida,
  sombraDura,
  sombraSuave,
  type EstiloDeTextura,
  type Forma,
  type FundoDoTexto,
  type Pintura,
  type PecaDeForma,
  type PecaDeImagem,
  type PecaDeTexto,
  type PecaDeTextura,
  type PecaDeIcone,
  type PecaDeTraco,
  type PecaDeQr,
  type PecaDeTabela,
  type PecaDeGrafico,
  ICONES,
  CHAVES_DOS_ICONES,
} from "./documento";

export type Medida = { largura: number; altura: number };

const noCentro = (m: Medida, w: number, h: number) => ({ x: (m.largura - w) / 2, y: (m.altura - h) / 2, w, h, rot: 0, opacidade: 1 });
const lado = (m: Medida) => Math.min(m.largura, m.altura);

function fundo(forma: FundoDoTexto["forma"], cor: string, extra: Partial<FundoDoTexto> = {}): FundoDoTexto {
  return { forma, pintura: solida(cor), borda: null, raio: 16, pontas: forma === "estrela" ? 5 : 16, profundidade: forma === "estrela" ? 0.55 : 0.2, ...extra };
}

export function texto(m: Medida, campos: Partial<PecaDeTexto>, w: number, h: number): PecaDeTexto {
  return {
    id: novoId("t"),
    tipo: "texto",
    ...noCentro(m, w, h),
    texto: "Seu texto aqui",
    fonte: FONTE_PADRAO,
    tamanho: lado(m) * 0.12,
    peso: 800,
    pintura: solida("#FFFFFF"),
    alinhamento: "centro",
    vertical: "meio",
    italico: false,
    caixaAlta: false,
    riscado: false,
    sublinhado: false,
    espaco: 0,
    linha: 1.05,
    fundo: null,
    contorno: null,
    sombra: null,
    ...campos,
  };
}

export function forma(m: Medida, f: Forma, w: number, h: number, cor: string, campos: Partial<PecaDeForma> = {}): PecaDeForma {
  return {
    id: novoId("f"),
    tipo: "forma",
    ...noCentro(m, w, h),
    forma: f,
    pintura: solida(cor),
    raio: f === "retangulo" ? lado(m) * 0.04 : 0,
    borda: null,
    sombra: null,
    pontas: f === "estrela" ? 5 : 16,
    profundidade: f === "estrela" ? 0.55 : 0.2,
    ...campos,
  };
}

export function imagem(m: Medida, src: string, papel: PecaDeImagem["papel"], proporcao = 1): PecaDeImagem {
  const h = papel === "logo" ? lado(m) * 0.14 : lado(m) * 0.6;
  const w = h * Math.min(6, Math.max(0.2, proporcao));
  return {
    id: novoId("i"),
    tipo: "imagem",
    ...noCentro(m, w, h),
    src,
    papel,
    ajuste: "conter",
    raio: papel === "logo" ? 0 : lado(m) * 0.03,
    circulo: false,
    borda: null,
    /* Sem sombra: ela quase não aparece na tela, mas sai marcada na impressão (sublimação). Quem quer, liga em Efeitos. */
    sombra: null,
    filtros: { ...SEM_FILTROS },
  };
}

/** As figurinhas do editor (Fluent Emoji, da Microsoft, licença MIT) moram no depósito da Ktalogu. */
export const DEPOSITO_DAS_FIGURINHAS = "https://ptpstwltddugnnlewvbw.supabase.co/storage/v1/object/public/products/editor-modelos/figurinhas";

/** Uma figurinha (desenho sem fundo): menor que a foto, sem sombra nem canto arredondado. */
export function figurinha(m: Medida, chave: string, nome: string, proporcao = 1): PecaDeImagem {
  const h = lado(m) * 0.32;
  const w = h * Math.min(4, Math.max(0.25, proporcao));
  return { ...imagem(m, `${DEPOSITO_DAS_FIGURINHAS}/${chave}.webp`, "foto", proporcao), ...noCentro(m, w, h), nome, raio: 0, sombra: null };
}

export type PecaPronta<T> = { chave: string; nome: string; criar: (m: Medida) => T };

/* ----------------------------------------------------------- textos prontos */

/** O contador das páginas ("01/05"), fixo em todas: cada página mostra o número dela. */
export function contadorDePaginas(m: Medida): PecaDeTexto {
  const peca = texto(m, { texto: "{pagina}/{total}", fonte: "montserrat", tamanho: lado(m) * 0.035, peso: 700, alinhamento: "direita" }, lado(m) * 0.2, lado(m) * 0.06);
  return { ...peca, nome: "Contador de páginas", x: m.largura - lado(m) * 0.25, y: m.altura - lado(m) * 0.1, fixa: true };
}

export const TEXTOS_PRONTOS: PecaPronta<PecaDeTexto>[] = [
  { chave: "titulo", nome: "Título", criar: (m) => texto(m, { texto: "Título do banner", tamanho: lado(m) * 0.16, peso: 900 }, m.largura * 0.6, lado(m) * 0.22) },
  { chave: "subtitulo", nome: "Subtítulo", criar: (m) => texto(m, { texto: "Subtítulo do banner", tamanho: lado(m) * 0.075, peso: 700 }, m.largura * 0.5, lado(m) * 0.12) },
  { chave: "apoio", nome: "Texto", criar: (m) => texto(m, { texto: "Um texto de apoio para explicar a oferta.", tamanho: lado(m) * 0.045, peso: 500, linha: 1.25 }, m.largura * 0.42, lado(m) * 0.14) },
  { chave: "impacto", nome: "Impacto", criar: (m) => texto(m, { texto: "ATÉ 50% OFF", fonte: "anton", peso: 400, tamanho: lado(m) * 0.22, sombra: sombraDura() }, m.largura * 0.55, lado(m) * 0.28) },
  { chave: "contorno", nome: "Com contorno", criar: (m) => texto(m, { texto: "MEGA PROMO", fonte: "bangers", peso: 400, tamanho: lado(m) * 0.2, pintura: solida("#FFD400"), contorno: { cor: "#141414", largura: Math.max(4, lado(m) * 0.012) }, sombra: sombraDura(0.4), espaco: 0.03 }, m.largura * 0.55, lado(m) * 0.26) },
  { chave: "degrade", nome: "Degradê", criar: (m) => texto(m, { texto: "Black Friday", fonte: "poppins", peso: 800, tamanho: lado(m) * 0.16, pintura: degrade("#FFD400", "#FF3D00", 90) }, m.largura * 0.55, lado(m) * 0.22) },
  { chave: "elegante", nome: "Elegante", criar: (m) => texto(m, { texto: "Coleção nova", fonte: "playfair-display", peso: 900, italico: true, tamanho: lado(m) * 0.14 }, m.largura * 0.5, lado(m) * 0.2) },
  { chave: "escrita", nome: "Escrita", criar: (m) => texto(m, { texto: "Feito com carinho", fonte: "pacifico", peso: 400, tamanho: lado(m) * 0.11 }, m.largura * 0.5, lado(m) * 0.2) },
];

/* ------------------------------------------------------- chamadas de venda */

export const CHAMADAS_PRONTAS: PecaPronta<PecaDeTexto>[] = [
  { chave: "botao", nome: "Botão", criar: (m) => texto(m, { texto: "COMPRE AGORA", tamanho: lado(m) * 0.055, peso: 900, pintura: solida("#141414"), espaco: 0.04, fundo: fundo("pilula", "#FFD400") }, lado(m) * 0.78, lado(m) * 0.13) },
  { chave: "selo", nome: "Selo de oferta", criar: (m) => texto(m, { texto: "-30%", fonte: "anton", peso: 400, tamanho: lado(m) * 0.11, pintura: solida("#141414"), rot: -12, fundo: fundo("explosao", "#FFD400") }, lado(m) * 0.36, lado(m) * 0.36) },
  { chave: "estrela", nome: "Estrela", criar: (m) => texto(m, { texto: "NOVO", fonte: "anton", peso: 400, tamanho: lado(m) * 0.07, pintura: solida("#FFFFFF"), rot: 10, fundo: fundo("estrela", "#E11D48") }, lado(m) * 0.34, lado(m) * 0.34) },
  { chave: "preco", nome: "Etiqueta de preço", criar: (m) => texto(m, { texto: "R$ 29,90", fonte: "anton", peso: 400, tamanho: lado(m) * 0.16, pintura: solida("#141414"), fundo: fundo("etiqueta", "#FFD400") }, lado(m) * 1.1, lado(m) * 0.26) },
  { chave: "faixa", nome: "Faixa", criar: (m) => texto(m, { texto: "FRETE GRÁTIS", tamanho: lado(m) * 0.05, peso: 900, espaco: 0.05, fundo: fundo("faixa", "#00A650") }, lado(m) * 0.8, lado(m) * 0.12) },
  { chave: "antigo", nome: "Preço antigo", criar: (m) => texto(m, { texto: "De R$ 49,90", tamanho: lado(m) * 0.06, peso: 600, riscado: true }, lado(m) * 0.6, lado(m) * 0.1) },
  { chave: "etiqueta", nome: "Etiqueta", criar: (m) => texto(m, { texto: "NOVIDADE", tamanho: lado(m) * 0.05, peso: 900, espaco: 0.14, fundo: fundo("pilula", "#141414") }, lado(m) * 0.5, lado(m) * 0.1) },
  { chave: "balao", nome: "Balão", criar: (m) => texto(m, { texto: "Só hoje!", fonte: "lilita-one", peso: 400, tamanho: lado(m) * 0.08, pintura: solida("#141414"), fundo: fundo("balao", "#FFFFFF") }, lado(m) * 0.5, lado(m) * 0.3) },
  { chave: "cupom", nome: "Cupom", criar: (m) => texto(m, { texto: "CUPOM: PROMO10", tamanho: lado(m) * 0.05, peso: 900, pintura: solida("#141414"), espaco: 0.06, fundo: fundo("retangulo", "#FFFFFF", { borda: { cor: "#141414", largura: 4 }, raio: 12 }) }, lado(m) * 0.8, lado(m) * 0.13) },
];

/* ------------------------------------------------------------------ formas */

export const FORMAS_PRONTAS: PecaPronta<PecaDeForma>[] = [
  { chave: "retangulo", nome: "Retângulo", criar: (m) => forma(m, "retangulo", lado(m) * 0.6, lado(m) * 0.4, "#FFFFFF") },
  { chave: "circulo", nome: "Círculo", criar: (m) => forma(m, "circulo", lado(m) * 0.5, lado(m) * 0.5, "#FFFFFF") },
  { chave: "triangulo", nome: "Triângulo", criar: (m) => forma(m, "triangulo", lado(m) * 0.45, lado(m) * 0.4, "#FFD400") },
  { chave: "losango", nome: "Losango", criar: (m) => forma(m, "losango", lado(m) * 0.4, lado(m) * 0.4, "#FFD400") },
  { chave: "estrela", nome: "Estrela", criar: (m) => forma(m, "estrela", lado(m) * 0.4, lado(m) * 0.4, "#FFD400") },
  { chave: "explosao", nome: "Explosão", criar: (m) => forma(m, "explosao", lado(m) * 0.4, lado(m) * 0.4, "#FFD400") },
  { chave: "coracao", nome: "Coração", criar: (m) => forma(m, "coracao", lado(m) * 0.38, lado(m) * 0.36, "#E11D48") },
  { chave: "balao", nome: "Balão", criar: (m) => forma(m, "balao", lado(m) * 0.5, lado(m) * 0.36, "#FFFFFF") },
  { chave: "seta", nome: "Seta", criar: (m) => forma(m, "seta", lado(m) * 0.4, lado(m) * 0.24, "#FFD400") },
  { chave: "etiqueta", nome: "Etiqueta", criar: (m) => forma(m, "etiqueta", lado(m) * 0.6, lado(m) * 0.22, "#FFD400") },
  { chave: "faixa", nome: "Faixa", criar: (m) => forma(m, "faixa", lado(m) * 0.8, lado(m) * 0.14, "#00A650") },
  { chave: "onda", nome: "Onda", criar: (m) => forma(m, "onda", m.largura, lado(m) * 0.16, "#FFFFFF", { x: 0, y: m.altura - lado(m) * 0.16 }) },
  { chave: "faixa-cheia", nome: "Faixa inteira", criar: (m) => forma(m, "retangulo", m.largura, lado(m) * 0.16, "#141414", { x: 0, raio: 0 }) },
  { chave: "moldura", nome: "Moldura", criar: (m) => forma(m, "retangulo", m.largura - lado(m) * 0.08, m.altura - lado(m) * 0.08, "#FFFFFF", { raio: lado(m) * 0.03, pintura: { tipo: "nenhuma", cor: "#FFFFFF", cor2: "#FFFFFF", angulo: 0 }, borda: { cor: "#FFFFFF", largura: Math.max(4, lado(m) * 0.012) } }) },
  { chave: "anel", nome: "Anel", criar: (m) => forma(m, "circulo", lado(m) * 0.6, lado(m) * 0.6, "#FFFFFF", { pintura: { tipo: "nenhuma", cor: "#FFFFFF", cor2: "#FFFFFF", angulo: 0 }, borda: { cor: "#FFFFFF", largura: Math.max(3, lado(m) * 0.008) } }) },
];

/* ---------------------------------------------------------------- texturas */

export function textura(m: Medida, estilo: EstiloDeTextura, campos: Partial<PecaDeTextura> = {}): PecaDeTextura {
  return {
    id: novoId("tex"),
    nome: "Textura",
    tipo: "textura",
    x: 0,
    y: 0,
    w: m.largura,
    h: m.altura,
    rot: 0,
    opacidade: estilo === "grao" ? 0.22 : 0.16,
    estilo,
    cor: "#FFFFFF",
    quantidade: 22,
    tamanho: 0,
    centroX: 70,
    centroY: 50,
    giro: 0,
    ...campos,
  };
}

export const TEXTURAS_PRONTAS: PecaPronta<PecaDeTextura>[] = [
  { chave: "raios", nome: "Raios", criar: (m) => textura(m, "raios") },
  { chave: "raios-centro", nome: "Raios no centro", criar: (m) => textura(m, "raios", { centroX: 50, centroY: 50, quantidade: 32 }) },
  { chave: "pontos", nome: "Bolinhas", criar: (m) => textura(m, "pontos", { tamanho: lado(m) * 0.05 }) },
  { chave: "listras", nome: "Listras", criar: (m) => textura(m, "listras", { tamanho: lado(m) * 0.06, opacidade: 0.1 }) },
  { chave: "xadrez", nome: "Xadrez", criar: (m) => textura(m, "xadrez", { tamanho: lado(m) * 0.08, opacidade: 0.08 }) },
  { chave: "ondas", nome: "Ondas", criar: (m) => textura(m, "ondas", { tamanho: lado(m) * 0.08, opacidade: 0.2 }) },
  { chave: "grao", nome: "Grão", criar: (m) => textura(m, "grao") },
  { chave: "meio-tom", nome: "Retícula", criar: (m) => textura(m, "meio-tom", { tamanho: lado(m) * 0.035, giro: 180, opacidade: 0.35 }) },
  { chave: "topografia", nome: "Curvas de nível", criar: (m) => textura(m, "topografia", { quantidade: 16, centroX: 75, centroY: 30, opacidade: 0.3 }) },
];

/* ------------------------------------------------------------------ fundos */

/** Um fundo é um retângulo do tamanho do banner, travado no lugar (pinta-se como qualquer forma). */
export function fundoCheio(m: Medida, pintura: Pintura): PecaDeForma {
  return { ...forma(m, "retangulo", m.largura, m.altura, pintura.cor, { x: 0, y: 0, raio: 0, pintura }), nome: "Fundo", bloqueada: true };
}

const fundoPronto = (chave: string, nome: string, pintura: Pintura): PecaPronta<PecaDeForma> => ({ chave, nome, criar: (m) => fundoCheio(m, pintura) });

export const FUNDOS_PRONTOS: PecaPronta<PecaDeForma>[] = [
  fundoPronto("roxo", "Roxo", degrade("#7C3AED", "#4C1D95", 120)),
  fundoPronto("oferta", "Oferta", degrade("#FF3D00", "#E11D48", 120)),
  fundoPronto("laranja", "Laranja", degrade("#FFB020", "#FF5A00", 120)),
  fundoPronto("amarelo", "Amarelo", degrade("#FFE14D", "#FFB800", 160)),
  fundoPronto("verde", "Verde", degrade("#10B981", "#047857", 120)),
  fundoPronto("azul", "Azul", degrade("#3B82F6", "#1E3A8A", 120)),
  fundoPronto("noite", "Noite", degrade("#1E1B4B", "#0B0618", 160)),
  fundoPronto("rosa", "Rosa", degrade("#F472B6", "#BE185D", 120)),
  fundoPronto("preto", "Preto", solida("#111111")),
  fundoPronto("branco", "Branco", solida("#FFFFFF")),
  fundoPronto("luz", "Luz no centro", { tipo: "radial", cor: "#8B5CF6", cor2: "#2E1065", angulo: 0 }),
  fundoPronto("por-do-sol", "Pôr do sol", degrade("#FDBA74", "#DB2777", 180)),
  fundoPronto("creme", "Creme", solida("#F5EFE6")),
  fundoPronto("grafite", "Grafite", degrade("#27272A", "#09090B", 160)),
  fundoPronto("menta", "Menta", degrade("#D1FAE5", "#A7F3D0", 160)),
  fundoPronto("aurora", "Aurora", degrade("#22D3EE", "#A855F7", 135)),
];

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

export function icone(m: Medida, chave: string, cor = "#FFFFFF", campos: Partial<PecaDeIcone> = {}): PecaDeIcone {
  const l = lado(m) * 0.22;
  return {
    id: novoId("ic"),
    tipo: "icone",
    ...noCentro(m, l, l),
    nome: ICONES[chave]?.nome || "Ícone",
    icone: chave,
    pintura: solida(cor),
    espessura: 2,
    preenchido: false,
    sombra: null,
    ...campos,
  };
}

export const ICONES_PRONTOS: PecaPronta<PecaDeIcone>[] = CHAVES_DOS_ICONES.map((chave) => ({ chave, nome: ICONES[chave].nome, criar: (m: Medida) => icone(m, chave, "#141414") }));

/* ------------------------------------------------------------ formas novas */

export const FORMAS_A_MAIS: PecaPronta<PecaDeForma>[] = [
  { chave: "hexagono", nome: "Hexágono", criar: (m) => forma(m, "hexagono", lado(m) * 0.42, lado(m) * 0.38, "#7C3AED") },
  { chave: "pentagono", nome: "Pentágono", criar: (m) => forma(m, "pentagono", lado(m) * 0.4, lado(m) * 0.38, "#06B6D4") },
  { chave: "octogono", nome: "Octógono", criar: (m) => forma(m, "octogono", lado(m) * 0.4, lado(m) * 0.4, "#E11D48") },
  { chave: "paralelogramo", nome: "Paralelogramo", criar: (m) => forma(m, "paralelogramo", lado(m) * 0.6, lado(m) * 0.2, "#141414") },
  { chave: "cruz", nome: "Cruz", criar: (m) => forma(m, "cruz", lado(m) * 0.3, lado(m) * 0.3, "#FFFFFF") },
  { chave: "raio", nome: "Raio", criar: (m) => forma(m, "raio", lado(m) * 0.26, lado(m) * 0.4, "#FFD400") },
  { chave: "nuvem", nome: "Nuvem", criar: (m) => forma(m, "nuvem", lado(m) * 0.5, lado(m) * 0.32, "#FFFFFF") },
  { chave: "gota", nome: "Gota", criar: (m) => forma(m, "gota", lado(m) * 0.28, lado(m) * 0.38, "#3B82F6") },
  { chave: "semicirculo", nome: "Meia-lua", criar: (m) => forma(m, "semicirculo", lado(m) * 0.5, lado(m) * 0.25, "#FFD400") },
  { chave: "anel-cheio", nome: "Anel grosso", criar: (m) => forma(m, "anel", lado(m) * 0.44, lado(m) * 0.44, "#FFFFFF") },
  { chave: "linha", nome: "Linha", criar: (m) => forma(m, "retangulo", lado(m) * 0.5, Math.max(3, lado(m) * 0.008), "#FFFFFF", { raio: 0 }) },
  { chave: "pilula", nome: "Pílula", criar: (m) => forma(m, "retangulo", lado(m) * 0.5, lado(m) * 0.14, "#FFFFFF", { raio: lado(m) * 0.07 }) },
  { chave: "cartao", nome: "Cartão com sombra", criar: (m) => forma(m, "retangulo", lado(m) * 0.6, lado(m) * 0.4, "#FFFFFF", { raio: lado(m) * 0.03, sombra: sombraSuave(0.18) }) },
  { chave: "vidro", nome: "Vidro", criar: (m) => forma(m, "retangulo", lado(m) * 0.6, lado(m) * 0.4, "#FFFFFF", { raio: lado(m) * 0.04, opacidade: 0.18, borda: { cor: "#FFFFFF", largura: Math.max(2, lado(m) * 0.004) } }) },
  { chave: "luz", nome: "Brilho redondo", criar: (m) => forma(m, "circulo", lado(m) * 0.7, lado(m) * 0.7, "#FFFFFF", { pintura: { tipo: "radial", cor: "#FFFFFF", cor2: "#FFFFFF", angulo: 0, alfa2: 0 }, opacidade: 0.5 }) },
  { chave: "rasgado", nome: "Papel rasgado", criar: (m) => forma(m, "rasgado", lado(m) * 0.7, lado(m) * 0.16, "#F1EFEA", { pontas: 7, profundidade: 0.22, rot: -3 }) },
  { chave: "fita", nome: "Fita ondulada", criar: (m) => forma(m, "fita", m.largura, lado(m) * 0.3, "#7C3AED", { x: 0, profundidade: 0.25 }) },
  { chave: "escurecer", nome: "Escurecer embaixo", criar: (m) => forma(m, "retangulo", m.largura, m.altura * 0.6, "#000000", { x: 0, y: m.altura * 0.4, raio: 0, pintura: { tipo: "linear", cor: "#000000", cor2: "#000000", angulo: 180, alfa: 0, alfa2: 0.85 } }) },
];

/* ------------------------------------------------- combinações de texto */

/* Duas ou três peças que já saem casadas (como as "combinações de fontes" do Canva): entram juntas. */
export type CombinacaoPronta = { chave: string; nome: string; criar: (m: Medida) => PecaDeTexto[] };

function combinar(m: Medida, linhas: Array<{ campos: Partial<PecaDeTexto>; w: number; h: number }>, respiro = 0.02) {
  const total = linhas.reduce((s, l) => s + l.h, 0) + respiro * lado(m) * (linhas.length - 1);
  let y = (m.altura - total) / 2;
  return linhas.map((l) => {
    const peca = texto(m, l.campos, l.w, l.h);
    peca.y = y;
    y += l.h + respiro * lado(m);
    return peca;
  });
}

export const COMBINACOES_PRONTAS: CombinacaoPronta[] = [
  {
    chave: "mega",
    nome: "Mega oferta",
    criar: (m) =>
      combinar(m, [
        { campos: { texto: "SÓ ESTA SEMANA", tamanho: lado(m) * 0.045, peso: 800, espaco: 0.3, pintura: solida("#FFD400") }, w: lado(m) * 0.9, h: lado(m) * 0.07 },
        { campos: { texto: "MEGA OFERTA", fonte: "anton", peso: 400, tamanho: lado(m) * 0.2, linha: 0.95, sombra: sombraDura(0.35) }, w: lado(m) * 1.1, h: lado(m) * 0.22 },
        { campos: { texto: "até 60% off em toda a loja", fonte: "poppins", peso: 600, tamanho: lado(m) * 0.05 }, w: lado(m) * 0.9, h: lado(m) * 0.08 },
      ]),
  },
  {
    chave: "elegante",
    nome: "Coleção elegante",
    criar: (m) =>
      combinar(
        m,
        [
          { campos: { texto: "nova", fonte: "great-vibes", peso: 400, tamanho: lado(m) * 0.13, pintura: solida("#D4A373") }, w: lado(m) * 0.6, h: lado(m) * 0.14 },
          { campos: { texto: "COLEÇÃO", fonte: "cinzel", peso: 800, tamanho: lado(m) * 0.11, espaco: 0.18, pintura: solida("#1C1917") }, w: lado(m) * 0.95, h: lado(m) * 0.13 },
          { campos: { texto: "primavera · verão", fonte: "cormorant-garamond", peso: 500, italico: true, tamanho: lado(m) * 0.05, pintura: solida("#57534E") }, w: lado(m) * 0.8, h: lado(m) * 0.07 },
        ],
        0,
      ),
  },
  {
    chave: "frete",
    nome: "Frete grátis",
    criar: (m) =>
      combinar(
        m,
        [
          { campos: { texto: "FRETE", fonte: "unbounded", peso: 800, tamanho: lado(m) * 0.15, linha: 0.9 }, w: lado(m) * 0.9, h: lado(m) * 0.17 },
          {
            campos: { texto: "GRÁTIS", fonte: "unbounded", peso: 800, tamanho: lado(m) * 0.15, linha: 0.9, pintura: { tipo: "nenhuma", cor: "#FFFFFF", cor2: "#FFFFFF", angulo: 0 }, contorno: { cor: "#FFFFFF", largura: Math.max(2, lado(m) * 0.006) } },
            w: lado(m) * 0.9,
            h: lado(m) * 0.17,
          },
          { campos: { texto: "nas compras acima de R$ 199", fonte: "outfit", peso: 600, tamanho: lado(m) * 0.045 }, w: lado(m) * 0.8, h: lado(m) * 0.07 },
        ],
        0.005,
      ),
  },
  {
    chave: "neon",
    nome: "Neon",
    criar: (m) =>
      combinar(m, [
        { campos: { texto: "OPEN", fonte: "monoton", peso: 400, tamanho: lado(m) * 0.18, pintura: solida("#FFE4F3"), sombra: { cor: "#FF2D87", x: 0, y: 0, desfoque: lado(m) * 0.05, opacidade: 1 } }, w: lado(m) * 0.9, h: lado(m) * 0.22 },
        { campos: { texto: "a loja está aberta", fonte: "dancing-script", peso: 700, tamanho: lado(m) * 0.07, pintura: solida("#A5F3FC"), sombra: { cor: "#06B6D4", x: 0, y: 0, desfoque: lado(m) * 0.03, opacidade: 1 } }, w: lado(m) * 0.8, h: lado(m) * 0.1 },
      ]),
  },
  {
    chave: "preco",
    nome: "De / por",
    criar: (m) =>
      combinar(
        m,
        [
          { campos: { texto: "de R$ 89,90", fonte: "outfit", peso: 600, riscado: true, tamanho: lado(m) * 0.05, opacidade: 0.8 }, w: lado(m) * 0.6, h: lado(m) * 0.07 },
          { campos: { texto: "por", fonte: "outfit", peso: 400, tamanho: lado(m) * 0.04 }, w: lado(m) * 0.6, h: lado(m) * 0.05 },
          { campos: { texto: "R$ 59,90", fonte: "kanit", peso: 900, tamanho: lado(m) * 0.16, linha: 0.95, pintura: degrade("#FFE14D", "#FF8A00", 90) }, w: lado(m) * 0.9, h: lado(m) * 0.18 },
        ],
        0,
      ),
  },
  {
    chave: "aviso",
    nome: "Comunicado",
    criar: (m) =>
      combinar(m, [
        { campos: { texto: "COMUNICADO", fonte: "space-grotesk", peso: 700, tamanho: lado(m) * 0.04, espaco: 0.4, pintura: solida("#7C3AED") }, w: lado(m) * 0.8, h: lado(m) * 0.06 },
        { campos: { texto: "Horário especial de feriado", fonte: "sora", peso: 800, tamanho: lado(m) * 0.09, linha: 1.05, pintura: solida("#111827") }, w: lado(m) * 0.9, h: lado(m) * 0.22 },
        { campos: { texto: "Sábado e domingo das 9h às 13h", fonte: "sora", peso: 400, tamanho: lado(m) * 0.045, pintura: solida("#4B5563") }, w: lado(m) * 0.85, h: lado(m) * 0.07 },
      ]),
  },
];

/* ------------------------------------------------- linhas, molduras, dados */

/** Um traço pronto (linha ou seta) atravessando o meio, com a largura dada em fração do lado menor. */
export function traco(m: Medida, campos: Partial<PecaDeTraco> = {}, largura = 0.5, altura = 0.06): PecaDeTraco {
  const w = lado(m) * largura;
  const h = Math.max(lado(m) * altura, 24);
  return {
    id: novoId("tr"),
    tipo: "traco",
    nome: "Linha",
    ...noCentro(m, w, h),
    pontos: [
      { x: 0.04, y: 0.5 },
      { x: 0.96, y: 0.5 },
    ],
    fechado: false,
    suave: false,
    cor: "#141414",
    espessura: Math.max(3, lado(m) * 0.008),
    tracejado: "solido",
    inicio: "nada",
    fim: "nada",
    preenchimento: solida("#FFD400"),
    sombra: null,
    ...campos,
  };
}

export const TRACOS_PRONTOS: PecaPronta<PecaDeTraco>[] = [
  { chave: "linha", nome: "Linha", criar: (m) => traco(m) },
  { chave: "seta", nome: "Seta", criar: (m) => traco(m, { nome: "Seta", fim: "seta" }) },
  { chave: "seta-dupla", nome: "Seta dupla", criar: (m) => traco(m, { nome: "Seta dupla", inicio: "seta", fim: "seta" }) },
  { chave: "seta-aberta", nome: "Seta aberta", criar: (m) => traco(m, { nome: "Seta", fim: "seta-aberta" }) },
  { chave: "tracejada", nome: "Tracejada", criar: (m) => traco(m, { nome: "Linha tracejada", tracejado: "tracejado" }) },
  { chave: "pontilhada", nome: "Pontilhada", criar: (m) => traco(m, { nome: "Linha pontilhada", tracejado: "pontilhado", espessura: Math.max(4, lado(m) * 0.012) }) },
  { chave: "conector", nome: "Conector", criar: (m) => traco(m, { nome: "Conector", inicio: "circulo", fim: "circulo" }) },
  {
    chave: "curva",
    nome: "Seta curva",
    criar: (m) =>
      traco(
        m,
        {
          nome: "Seta curva",
          suave: true,
          fim: "seta",
          pontos: [
            { x: 0.05, y: 0.85 },
            { x: 0.45, y: 0.15 },
            { x: 0.95, y: 0.55 },
          ],
        },
        0.5,
        0.3,
      ),
  },
];

/* A imagem de espera das molduras (antes de soltar uma foto). */
export const FOTO_DA_MOLDURA = "https://ptpstwltddugnnlewvbw.supabase.co/storage/v1/object/public/products/editor-modelos/moldura.webp";

export function moldura(m: Medida, forma: Forma, proporcao = 1): PecaDeImagem {
  const h = lado(m) * 0.5;
  const w = h * proporcao;
  return {
    id: novoId("i"),
    tipo: "imagem",
    nome: "Moldura",
    ...noCentro(m, w, h),
    src: FOTO_DA_MOLDURA,
    papel: "foto",
    ajuste: "cobrir",
    raio: forma === "retangulo" ? lado(m) * 0.04 : 0,
    circulo: false,
    borda: null,
    sombra: null,
    filtros: { ...SEM_FILTROS },
    ...(forma === "retangulo" ? {} : { mascara: forma }),
    moldura: true,
  };
}

export const MOLDURAS_PRONTAS: PecaPronta<PecaDeImagem>[] = [
  { chave: "m-retangulo", nome: "Retângulo", criar: (m) => moldura(m, "retangulo", 0.8) },
  { chave: "m-circulo", nome: "Círculo", criar: (m) => moldura(m, "circulo") },
  { chave: "m-estrela", nome: "Estrela", criar: (m) => moldura(m, "estrela") },
  { chave: "m-coracao", nome: "Coração", criar: (m) => moldura(m, "coracao") },
  { chave: "m-hexagono", nome: "Hexágono", criar: (m) => moldura(m, "hexagono", 1.1) },
  { chave: "m-gota", nome: "Gota", criar: (m) => moldura(m, "gota", 0.85) },
  { chave: "m-nuvem", nome: "Nuvem", criar: (m) => moldura(m, "nuvem", 1.4) },
  { chave: "m-semicirculo", nome: "Arco", criar: (m) => moldura(m, "semicirculo", 1.6) },
  { chave: "m-losango", nome: "Losango", criar: (m) => moldura(m, "losango") },
];

export function qrCode(m: Medida, conteudo = "https://ktalogu.com.br"): PecaDeQr {
  const l = lado(m) * 0.32;
  return { id: novoId("qr"), tipo: "qr", nome: "QR code", ...noCentro(m, l, l), conteudo, cor: "#141414", fundo: "#FFFFFF", arredondado: false };
}

export function tabela(m: Medida): PecaDeTabela {
  return {
    id: novoId("tb"),
    tipo: "tabela",
    nome: "Tabela",
    ...noCentro(m, lado(m) * 0.75, lado(m) * 0.36),
    celulas: [
      ["Produto", "Quantidade", "Preço"],
      ["Item 1", "10", "R$ 29,90"],
      ["Item 2", "5", "R$ 49,90"],
      ["Item 3", "50", "R$ 4,90"],
    ],
    fonte: "manrope",
    tamanho: lado(m) * 0.026,
    corDoTexto: "#141414",
    cabecalho: true,
    corDoCabecalho: "#141414",
    corDoTextoDoCabecalho: "#FFFFFF",
    corDaLinha: "#FFFFFF",
    corDaLinha2: "#F4F4F5",
    corDaBorda: "#E4E4E7",
    alinhamento: "esquerda",
    raio: lado(m) * 0.014,
  };
}

export function grafico(m: Medida, estilo: PecaDeGrafico["estilo"]): PecaDeGrafico {
  const redondo = estilo === "pizza" || estilo === "rosca";
  return {
    id: novoId("gr"),
    tipo: "grafico",
    nome: "Gráfico",
    ...noCentro(m, lado(m) * (redondo ? 0.7 : 0.62), lado(m) * (redondo ? 0.42 : 0.44)),
    estilo,
    dados: [
      { rotulo: "Jan", valor: 12 },
      { rotulo: "Fev", valor: 19 },
      { rotulo: "Mar", valor: 8 },
      { rotulo: "Abr", valor: 24 },
    ],
    cores: ["#7C3AED", "#F59E0B", "#10B981", "#E11D48", "#0EA5E9", "#84CC16"],
    fonte: "manrope",
    corDoTexto: "#141414",
    mostrarValores: true,
    prefixo: "",
    sufixo: "",
  };
}

export const GRAFICOS_PRONTOS: PecaPronta<PecaDeGrafico>[] = [
  { chave: "g-colunas", nome: "Colunas", criar: (m) => grafico(m, "colunas") },
  { chave: "g-barras", nome: "Barras", criar: (m) => grafico(m, "barras") },
  { chave: "g-linha", nome: "Linha", criar: (m) => grafico(m, "linha") },
  { chave: "g-pizza", nome: "Pizza", criar: (m) => grafico(m, "pizza") },
  { chave: "g-rosca", nome: "Rosca", criar: (m) => grafico(m, "rosca") },
];
