/*
 * Coleção de posts para Instagram (out/2026): artes de referência refeitas
 * peça por peça no editor, para provar que dá para criar no KtaloguDesign o
 * que se vê nas redes: colagem com papel rasgado e retícula, recorte com
 * contorno de adesivo e foto em duas cores, texto em círculo (selo),
 * marca-texto por linha, foto que some no fundo, fita ondulada, curvas de
 * nível e as fontes dessas artes.
 *
 * Cada modelo é desenhado no tamanho de post (1080 × 1350 ou 1080 × 1080);
 * em outro tamanho a composição encaixa inteira (ver `encaixar`). As fotos
 * são do Unsplash (licença livre para uso comercial) e moram no depósito da
 * Ktalogu (products/editor-modelos/).
 */
import {
  ICONES,
  htmlDoTextoLimpo,
  novoId,
  redimensionarDocumento,
  solida,
  sombraSuave,
  type DocumentoDoBanner,
  type Peca,
  type PecaDeForma,
  type PecaDeIcone,
  type PecaDeImagem,
  type PecaDeTexto,
  type PecaDeTextura,
  type Pintura,
} from "./documento";
import { documento, fundoDoBanner, imagem, texto, type CamposDoTexto, type PedidoDoModelo } from "./modelos-base";

const DEPOSITO = "https://ptpstwltddugnnlewvbw.supabase.co/storage/v1/object/public/products/editor-modelos";
const FOTO = {
  estetoscopio: `${DEPOSITO}/estetoscopio.webp`,
  microscopio: `${DEPOSITO}/microscopio.webp`,
  joinha: `${DEPOSITO}/joinha.webp`,
  seringa: `${DEPOSITO}/seringa.webp`,
  boca: `${DEPOSITO}/boca.webp`,
  mulherNotebook: `${DEPOSITO}/mulher-notebook.webp`,
  homemSorrindo: `${DEPOSITO}/homem-sorrindo.webp`,
  rosa: `${DEPOSITO}/rosa.webp`,
  mulherSorrindo: `${DEPOSITO}/mulher-sorrindo-rosa.webp`,
  maosLaco: `${DEPOSITO}/maos-laco-rosa.webp`,
  equipe: `${DEPOSITO}/equipe-comemorando.webp`,
  alongamento: `${DEPOSITO}/alongamento.webp`,
};

/* ------------------------------------------------------------ peças curtas */

type Lugar = { x: number; y: number; w: number; h: number; rot?: number };

function t(nome: string, l: Lugar, campos: CamposDoTexto): PecaDeTexto {
  return texto({ nome, ...l, rot: l.rot ?? 0, ...campos });
}

function f(nome: string, forma: PecaDeForma["forma"], l: Lugar, pintura: Pintura | string, extra: Partial<PecaDeForma> = {}): PecaDeForma {
  return {
    id: novoId("f"),
    tipo: "forma",
    nome,
    ...l,
    rot: l.rot ?? 0,
    opacidade: 1,
    forma,
    pintura: typeof pintura === "string" ? solida(pintura) : pintura,
    raio: 0,
    borda: null,
    sombra: null,
    pontas: 7,
    profundidade: 0.2,
    ...extra,
  };
}

function foto(nome: string, src: string, l: Lugar, extra: Partial<PecaDeImagem> = {}): PecaDeImagem {
  return { ...imagem({ nome, src, ...l, rot: l.rot ?? 0, sombra: false }), ...extra };
}

function ic(nome: string, chave: string, x: number, y: number, lado: number, cor: string, extra: Partial<PecaDeIcone> = {}): PecaDeIcone {
  return { id: novoId("ic"), tipo: "icone", nome, x, y, w: lado, h: lado, rot: 0, opacidade: 1, icone: chave, pintura: solida(cor), espessura: 2, preenchido: false, sombra: null, ...extra };
}

function tex(nome: string, estilo: PecaDeTextura["estilo"], l: Lugar, cor: string, extra: Partial<PecaDeTextura> = {}): PecaDeTextura {
  return { id: novoId("tex"), tipo: "textura", nome, ...l, rot: l.rot ?? 0, opacidade: 0.15, bloqueada: true, estilo, cor, quantidade: 18, tamanho: 0, centroX: 50, centroY: 50, giro: 0, ...extra };
}

const trecho = (estilo: string, conteudo: string) => `<span style="${estilo}">${conteudo}</span>`;
const linear = (cor: string, cor2: string, angulo: number, alfa?: number, alfa2?: number): Pintura => ({ tipo: "linear", cor, cor2, angulo, ...(alfa !== undefined ? { alfa } : {}), ...(alfa2 !== undefined ? { alfa2 } : {}) });

/* O logo da loja; sem logo, o nome no lugar (a pessoa troca). */
function marca(p: PedidoDoModelo, x: number, y: number, h: number, cor: string, alinhamento: PecaDeTexto["alinhamento"] = "esquerda", larguraMaxima = 420): Peca {
  if (p.logo) {
    const w = Math.min(larguraMaxima, h * Math.min(6, Math.max(0.6, p.proporcaoDoLogo || 3)));
    const xx = alinhamento === "direita" ? x + larguraMaxima - w : alinhamento === "centro" ? x + (larguraMaxima - w) / 2 : x;
    return foto("Logo", p.logo, { x: xx, y, w, h }, { papel: "logo" });
  }
  return t("Marca", { x, y, w: larguraMaxima, h }, { texto: "SUA MARCA", fonte: "bricolage-grotesque", peso: 800, tamanho: h * 0.62, cor, espaco: 0.06, alinhamento });
}

/* Recorte de colagem: foto em duas cores com contorno de adesivo. */
function recorte(nome: string, src: string, l: Lugar, escuro = "#4A0D33", claro = "#FFB3D6", contorno = 12): PecaDeImagem {
  return foto(nome, src, l, { duotone: { escuro, claro }, adesivo: { cor: "#FFFFFF", largura: contorno }, sombra: { cor: "#000000", x: 0, y: 10, desfoque: 26, opacidade: 0.35 } });
}

/* Uma tira de papel rasgado com o texto por cima (giram juntos). */
function tira(nome: string, l: Lugar, cor: string, frase: string, tamanho: number, semente: number, corDaLetra = "#1B1E24"): Peca[] {
  return [
    f(`Papel ${nome}`, "rasgado", l, cor, { pontas: semente, profundidade: 0.2, sombra: { cor: "#000000", x: 0, y: 6, desfoque: 14, opacidade: 0.28 } }),
    t(nome, { x: l.x + l.w * 0.04, y: l.y, w: l.w * 0.92, h: l.h, rot: l.rot }, { texto: frase, fonte: "bricolage-grotesque", peso: 800, tamanho, cor: corDaLetra, alinhamento: "centro", espaco: -0.015, linha: 1 }),
  ];
}

/* Fundo de ardósia com retícula (as colagens). */
function fundoDeColagem(W: number, H: number): Peca[] {
  return [
    tex("Retícula de cima", "meio-tom", { x: 0, y: 0, w: W, h: H * 0.55 }, "#FFFFFF", { opacidade: 0.12, tamanho: 26, giro: 180 }),
    tex("Retícula de baixo", "meio-tom", { x: W * 0.35, y: H * 0.66, w: W * 0.65, h: H * 0.34 }, "#FFFFFF", { opacidade: 0.1, tamanho: 22, giro: 0 }),
  ];
}

const ARDOSIA = "#22262D";
const ROSA_PAPEL = "#FF8FC0";
const VERDE_PAPEL = "#A6F05A";
const CINZA_PAPEL = "#ECE9E2";

/* ===================================================== 1. colagem: escolhas */

function colagemEscolhas(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const pecas: Peca[] = [
    ...fundoDeColagem(W, H),
    recorte("Estetoscópio", FOTO.estetoscopio, { x: -30, y: 40, w: 300, h: 470, rot: -16 }),
    recorte("Seringa", FOTO.seringa, { x: 330, y: 120, w: 400, h: 259, rot: -12 }),
    recorte("Microscópio", FOTO.microscopio, { x: 790, y: 50, w: 290, h: 408, rot: 10 }),
    ...tira("Linha 1", { x: 80, y: 430, w: 920, h: 170, rot: -3 }, CINZA_PAPEL, "ESCOLHAS CERTAS", 82, 5),
    ...tira("Linha 2", { x: 170, y: 600, w: 740, h: 150, rot: 2 }, ROSA_PAPEL, "TE LEVAM AO", 92, 11),
    ...tira("Linha 3", { x: 60, y: 755, w: 960, h: 172, rot: -2 }, VERDE_PAPEL, "LUGAR CERTO", 108, 17),
    ic("Brilho verde", "estrela-4", 900, 300, 100, VERDE_PAPEL, { preenchido: true, espessura: 0.5 }),
    ic("Brilho rosa", "estrela-4", 40, 560, 70, ROSA_PAPEL, { preenchido: true, espessura: 0.5 }),
    ic("Seta", "seta-rabisco", 840, 930, 150, "#FFFFFF", { espessura: 1.4, rot: 70 }),
    recorte("Joinha", FOTO.joinha, { x: -40, y: 960, w: 440, h: 248, rot: -10 }),
    recorte("Boca", FOTO.boca, { x: 730, y: 1050, w: 320, h: 250, rot: 8 }),
    t("Escolha a", { x: 330, y: 1150, w: 420, h: 80, rot: -3 }, { texto: "Escolha a", fonte: "caveat", peso: 700, tamanho: 66, cor: "#FFFFFF", alinhamento: "centro" }),
    marca(p, 330, 1232, 74, "#FFFFFF", "centro", 420),
  ];
  return documento(W, H, fundoDoBanner({ cor: ARDOSIA, textura: "nenhuma" }), pecas);
}

/* ======================================================== 2. colagem: quiz */

function colagemQuiz(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const opcoes: Array<[string, string, string]> = [
    ["A", "Medicina", VERDE_PAPEL],
    ["B", "Odontologia", ROSA_PAPEL],
    ["C", "Biomedicina", CINZA_PAPEL],
  ];
  const pecas: Peca[] = [
    ...fundoDeColagem(W, H),
    ...tira("Pergunta", { x: 70, y: 110, w: 940, h: 200, rot: -2 }, ROSA_PAPEL, "QUAL SUA ESCOLHA?", 98, 23),
    t("Convite", { x: 120, y: 318, w: 840, h: 80, rot: -2 }, { texto: "Responde aqui nos comentários", fonte: "caveat", peso: 700, tamanho: 58, cor: "#FFFFFF", alinhamento: "centro" }),
  ];
  opcoes.forEach(([letra, nome, cor], i) => {
    const y = 450 + i * 160;
    pecas.push(
      f(`Cartão ${letra}`, "retangulo", { x: 90, y, w: 660, h: 128 }, "#FFFFFF", { raio: 30, sombra: { cor: "#000000", x: 0, y: 8, desfoque: 20, opacidade: 0.3 } }),
      t(`Letra ${letra}`, { x: 114, y: y + 20, w: 88, h: 88 }, { texto: letra, fonte: "bricolage-grotesque", peso: 800, tamanho: 48, cor: ARDOSIA, alinhamento: "centro", fundo: { forma: "circulo", cor } }),
      t(`Opção ${letra}`, { x: 226, y, w: 500, h: 128 }, { texto: nome, fonte: "bricolage-grotesque", peso: 700, tamanho: 54, cor: ARDOSIA }),
    );
  });
  pecas.push(
    recorte("Microscópio", FOTO.microscopio, { x: 780, y: 420, w: 280, h: 394, rot: 10 }),
    ic("Seta", "seta-rabisco", 640, 930, 150, "#FFFFFF", { espessura: 1.4, rot: 200 }),
    recorte("Estetoscópio", FOTO.estetoscopio, { x: 40, y: 940, w: 230, h: 360, rot: 18 }),
    recorte("Boca", FOTO.boca, { x: 700, y: 990, w: 340, h: 265, rot: -8 }),
    ic("Brilho", "estrela-4", 330, 960, 80, VERDE_PAPEL, { preenchido: true, espessura: 0.5 }),
    ic("Comentário", "comentario", 330, 1150, 64, "#FFFFFF", { espessura: 1.8 }),
    t("Chamada", { x: 410, y: 1146, w: 300, h: 72 }, { texto: "Comente A, B ou C", fonte: "manrope", peso: 700, tamanho: 30, cor: "#FFFFFF" }),
    marca(p, 300, 1250, 60, "#FFFFFF", "centro", 480),
  );
  return documento(W, H, fundoDoBanner({ cor: ARDOSIA, textura: "nenhuma" }), pecas);
}

/* ===================================================== 3. colagem: vestibular */

function colagemVestibular(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const cursos = ["Administração", "Direito", "Enfermagem", "Psicologia", "Pedagogia"];
  const pecas: Peca[] = [
    tex("Retícula", "meio-tom", { x: 0, y: 0, w: 720, h: H }, "#FFFFFF", { opacidade: 0.12, tamanho: 24, giro: 90 }),
    f("Círculo", "circulo", { x: 610, y: 400, w: 520, h: 520 }, ROSA_PAPEL),
    foto("Estudante", FOTO.mulherNotebook, { x: 700, y: 320, w: 380, h: 1115 }, { filtros: { brilho: 104, contraste: 118, saturacao: 0, desfoque: 0 }, adesivo: { cor: "#FFFFFF", largura: 12 }, sombra: { cor: "#000000", x: 0, y: 12, desfoque: 30, opacidade: 0.4 } }),
    marca(p, 60, 56, 56, "#FFFFFF", "esquerda", 360),
    t("Vestibular", { x: 56, y: 130, w: 800, h: 136 }, { texto: "VESTIBULAR", fonte: "bricolage-grotesque", peso: 800, tamanho: 112, cor: "#FFFFFF", espaco: -0.02 }),
    ...tira("Agendado", { x: 46, y: 272, w: 640, h: 140, rot: -3 }, VERDE_PAPEL, "AGENDADO", 92, 29),
    t("Ano", { x: 56, y: 410, w: 520, h: 250 }, { texto: "2027", fonte: "league-gothic", peso: 400, tamanho: 250, linha: 1, pintura: { tipo: "nenhuma", cor: "#FFFFFF", cor2: "#FFFFFF", angulo: 0 }, contorno: { cor: "#FFFFFF", largura: 3 } }),
    f("Papel da lista", "rasgado", { x: 46, y: 690, w: 560, h: 440, rot: 2 }, CINZA_PAPEL, { pontas: 31, profundidade: 0.12, sombra: { cor: "#000000", x: 0, y: 8, desfoque: 18, opacidade: 0.3 } }),
    t("Cursos", { x: 96, y: 716, w: 460, h: 64, rot: 2 }, { texto: "CURSOS", fonte: "bricolage-grotesque", peso: 800, tamanho: 46, cor: ARDOSIA, espaco: 0.04 }),
  ];
  cursos.forEach((c, i) => {
    const y = 794 + i * 62;
    pecas.push(ic(`Certo ${i + 1}`, "check-circulo", 96 + i * 2, y + 6, 42, "#1B8A3A", { espessura: 2.2, rot: 2 }), t(`Curso ${i + 1}`, { x: 152 + i * 2, y, w: 420, h: 56, rot: 2 }, { texto: c, fonte: "manrope", peso: 700, tamanho: 38, cor: ARDOSIA }));
  });
  pecas.push(
    ic("Seta", "seta-rabisco", 540, 1110, 150, "#FFFFFF", { espessura: 1.4, rot: -10 }),
    ic("Brilho", "estrela-4", 960, 170, 84, VERDE_PAPEL, { preenchido: true, espessura: 0.5 }),
    t("Botão", { x: 56, y: 1190, w: 470, h: 100 }, { texto: "INSCREVA-SE JÁ", fonte: "bricolage-grotesque", peso: 800, tamanho: 42, cor: ARDOSIA, alinhamento: "centro", fundo: { forma: "pilula", cor: ROSA_PAPEL } }),
  );
  return documento(W, H, fundoDoBanner({ cor: ARDOSIA, textura: "nenhuma" }), pecas);
}

/* ====================================================== 4. colagem: a boca */

function colagemBoca(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1080;
  const pecas: Peca[] = [
    tex("Retícula", "meio-tom", { x: 0, y: 0, w: W, h: H * 0.6 }, "#FFFFFF", { opacidade: 0.12, tamanho: 24, giro: 180 }),
    ...tira("Vestibular agendado", { x: 80, y: 60, w: 920, h: 150, rot: -2 }, ROSA_PAPEL, "VESTIBULAR AGENDADO", 82, 37),
    recorte("Boca", FOTO.boca, { x: 250, y: 255, w: 580, h: 452, rot: -4 }, "#4A0D33", "#FFB3D6", 14),
    recorte("Seringa", FOTO.seringa, { x: 790, y: 520, w: 270, h: 175, rot: -24 }),
    ic("Seta", "seta-rabisco", 70, 300, 170, "#FFFFFF", { espessura: 1.4, rot: 20 }),
    ic("Brilho verde", "estrela-4", 870, 260, 100, VERDE_PAPEL, { preenchido: true, espessura: 0.5 }),
    ic("Brilho rosa", "estrela-4", 150, 640, 64, ROSA_PAPEL, { preenchido: true, espessura: 0.5 }),
    ...tira("Escolhas certas", { x: 50, y: 760, w: 980, h: 128, rot: 2 }, VERDE_PAPEL, "ESCOLHAS CERTAS TE LEVAM", 54, 41),
    ...tira("Lugar certo", { x: 250, y: 884, w: 580, h: 112, rot: -2 }, CINZA_PAPEL, "AO LUGAR CERTO", 58, 43),
    marca(p, 340, 1006, 54, "#FFFFFF", "centro", 400),
  ];
  return documento(W, H, fundoDoBanner({ cor: ARDOSIA, textura: "nenhuma" }), pecas);
}

/* ======================================================= 5. documentos */

function documentosParaVotar(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const AMARELO = "#FFD21F";
  const ESCURO = "#1A1A1A";
  const itens = ["Título de eleitor", "RG ou CNH", "e-Título no celular", "Carteira de trabalho"];
  const pecas: Peca[] = [
    tex("Retícula", "meio-tom", { x: 480, y: 820, w: 600, h: 530 }, "#FFFFFF", { opacidade: 0.35, tamanho: 26, giro: 315 }),
    ic("Selo de fundo", "check-circulo", 860, 560, 190, "#FFFFFF", { opacidade: 0.5, espessura: 1.6, rot: 12 }),
    t("Etiqueta", { x: 60, y: 84, w: 400, h: 72 }, { texto: "ELEIÇÕES 2026", fonte: "montserrat", peso: 800, tamanho: 32, cor: "#FFFFFF", espaco: 0.08, alinhamento: "centro", fundo: { forma: "pilula", cor: ESCURO } }),
    t("Título", { x: 56, y: 186, w: 980, h: 270 }, {
      texto: "DOCUMENTOS\nPARA VOTAR",
      fonte: "montserrat",
      peso: 900,
      italico: true,
      tamanho: 124,
      linha: 0.98,
      espaco: -0.02,
      cor: "#FFFFFF",
    }),
    t("Subtítulo", { x: 60, y: 470, w: 900, h: 64 }, { texto: "Leve um destes no dia da eleição:", fonte: "montserrat", peso: 700, tamanho: 38, cor: ESCURO }),
  ];
  const titulo = pecas.find((x) => x.nome === "Título") as PecaDeTexto;
  titulo.sombra = { cor: "#B58A00", x: 7, y: 9, desfoque: 0, opacidade: 1 };
  itens.forEach((nome, i) => {
    const y = 572 + i * 148;
    pecas.push(
      f(`Pílula ${i + 1}`, "retangulo", { x: 60, y, w: 780, h: 118 }, "#FFFFFF", { raio: 59, sombra: { cor: "#7A5A00", x: 0, y: 8, desfoque: 18, opacidade: 0.22 } }),
      f(`Bolinha ${i + 1}`, "circulo", { x: 78, y: y + 17, w: 84, h: 84 }, ESCURO),
      ic(`Certo ${i + 1}`, "check", 96, y + 35, 48, AMARELO, { espessura: 3 }),
      t(`Documento ${i + 1}`, { x: 190, y, w: 630, h: 118 }, { texto: nome, fonte: "montserrat", peso: 800, italico: true, tamanho: 44, cor: ESCURO }),
    );
  });
  pecas.push(marca(p, 60, 1222, 72, ESCURO, "esquerda", 400), t("Frase", { x: 500, y: 1222, w: 520, h: 72 }, { texto: "Seu voto, sua voz.", fonte: "montserrat", peso: 800, italico: true, tamanho: 40, cor: ESCURO, alinhamento: "direita" }));
  return documento(W, H, fundoDoBanner({ cor: AMARELO, textura: "nenhuma" }), pecas);
}

/* ==================================================== 6. outubro rosa: foto */

const PINK = "#E91E63";
const PINK_ESCURO = "#AD1457";

function outubroRosaFoto(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const pecas: Peca[] = [
    t("Outubro ao fundo", { x: -20, y: 10, w: 1120, h: 330 }, { texto: "OUTUBRO", fonte: "league-gothic", peso: 400, tamanho: 380, linha: 1, espaco: 0.02, cor: "#F8BBD0", alinhamento: "centro" }),
    foto("Foto", FOTO.mulherSorrindo, { x: 330, y: 280, w: 690, h: 830 }, { ajuste: "cobrir", raio: 40, sombra: { cor: "#AD1457", x: 0, y: 18, desfoque: 40, opacidade: 0.22 } }),
    f("Selo", "circulo", { x: 170, y: 220, w: 280, h: 280 }, "#FFFFFF", { sombra: sombraSuave(0.16) }),
    t("Texto do selo", { x: 184, y: 234, w: 252, h: 252 }, { texto: "OUTUBRO ROSA • PREVENÇÃO É VIDA •", fonte: "manrope", peso: 800, tamanho: 24, cor: PINK, espaco: 0.08, curva: 100 }),
    ic("Laço", "laco", 270, 315, 80, PINK, { espessura: 2.2 }),
    f("Cartão", "retangulo", { x: 60, y: 850, w: 610, h: 340 }, PINK, { raio: 36, sombra: { cor: "#AD1457", x: 0, y: 16, desfoque: 36, opacidade: 0.3 } }),
    t("Frase", { x: 100, y: 880, w: 530, h: 130 }, { texto: "Cuidar de você é um ato de amor.", fonte: "plus-jakarta-sans", peso: 800, tamanho: 48, linha: 1.08, cor: "#FFFFFF", vertical: "topo" }),
    t("Texto", { x: 100, y: 1018, w: 530, h: 100 }, { texto: "Faça o autoexame todo mês e agende a sua mamografia.", fonte: "manrope", peso: 500, tamanho: 30, linha: 1.3, cor: "#FFFFFF", vertical: "topo" }),
    t("Perfil", { x: 100, y: 1124, w: 530, h: 44 }, { texto: "@suamarca", fonte: "manrope", peso: 800, tamanho: 28, cor: "#FFFFFF", opacidade: 0.9 }),
    marca(p, 60, 1226, 64, PINK_ESCURO, "esquerda", 380),
  ];
  (["instagram", "facebook", "whatsapp"] as const).forEach((chave, i) => {
    const x = 790 + i * 82;
    pecas.push(f(`Rede ${i + 1}`, "circulo", { x, y: 1226, w: 66, h: 66 }, PINK), ic(ICONES[chave].nome, chave, x + 15, 1241, 36, "#FFFFFF", { espessura: 1.9 }));
  });
  pecas.push(t("Aviso", { x: 60, y: 1306, w: 960, h: 30 }, { texto: "Imagem meramente ilustrativa.", fonte: "manrope", peso: 500, tamanho: 19, cor: PINK_ESCURO, opacidade: 0.7, alinhamento: "centro" }));
  return documento(W, H, fundoDoBanner({ cor: "#FCE4EC", textura: "nenhuma" }), pecas);
}

/* ==================================================== 7. outubro rosa: flor */

function outubroRosaFlor(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const pecas: Peca[] = [
    foto("Pétala 1", FOTO.rosa, { x: 30, y: 860, w: 170, h: 273, rot: -34 }, { filtros: { brilho: 100, contraste: 100, saturacao: 110, desfoque: 7 }, opacidade: 0.75 }),
    foto("Pétala 2", FOTO.rosa, { x: 890, y: 120, w: 150, h: 241, rot: 38 }, { filtros: { brilho: 100, contraste: 100, saturacao: 110, desfoque: 9 }, opacidade: 0.7 }),
    t("Outubro", { x: 0, y: 6, w: 1080, h: 830 }, { texto: "OUTU\nBRO", fonte: "league-gothic", peso: 400, tamanho: 480, linha: 0.86, espaco: 0.01, cor: "#FFFFFF", alinhamento: "centro" }),
    foto("Rosa", FOTO.rosa, { x: 330, y: 300, w: 420, h: 674, rot: 6 }, { sombra: { cor: "#5A0026", x: 0, y: 24, desfoque: 40, opacidade: 0.45 } }),
    t("Rosa escrito", { x: 440, y: 600, w: 620, h: 300, rot: -8 }, { texto: "rosa", fonte: "allura", peso: 400, tamanho: 290, cor: "#7A0B3C", alinhamento: "centro" }),
    t("Mensagem", { x: 60, y: 1000, w: 820, h: 210 }, {
      texto: "Previna-se.\nO diagnóstico precoce\nsalva vidas.",
      fonte: "manrope",
      peso: 800,
      tamanho: 46,
      linha: 1.5,
      cor: "#C2185B",
      vertical: "topo",
      destaque: { pintura: solida("#FFFFFF"), respiro: 0.28, raio: 6 },
    }),
    ic("Laço", "laco", 60, 1236, 72, "#FFFFFF", { espessura: 2.1 }),
    marca(p, 640, 1240, 62, "#FFFFFF", "direita", 380),
  ];
  return documento(W, H, fundoDoBanner({ cor: "#E2286F", cor2: "#A80F4E", angulo: 180, textura: "nenhuma" }), pecas);
}

/* ==================================================== 8. outubro rosa: mãos */

function outubroRosaMaos(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const MAGENTA = "#B0124F";
  const pecas: Peca[] = [
    foto("Foto", FOTO.maosLaco, { x: 0, y: 0, w: W, h: 880 }, { ajuste: "cobrir", transparencia: { x1: 0.5, y1: 0.5, x2: 0.5, y2: 1, alfa: 1, alfa2: 0 } }),
    t("Título", { x: 60, y: 620, w: 960, h: 150 }, { texto: "Outubro Rosa", fonte: "fraunces", peso: 900, italico: true, tamanho: 128, cor: "#FFFFFF", alinhamento: "centro", sombra: "suave" }),
    t("Subtítulo", { x: 90, y: 772, w: 900, h: 110 }, { texto: "Um mês para lembrar que prevenir é um ato de amor.", fonte: "manrope", peso: 600, tamanho: 36, linha: 1.3, cor: "#FFFFFF", alinhamento: "centro" }),
    f("Cartão", "retangulo", { x: 60, y: 920, w: 960, h: 330 }, "#FFFFFF", { raio: 34, sombra: { cor: "#4A0020", x: 0, y: 18, desfoque: 40, opacidade: 0.3 } }),
    t("Coluna 1 título", { x: 104, y: 960, w: 400, h: 64 }, { texto: "Fique atenta", fonte: "fraunces", peso: 700, tamanho: 46, cor: MAGENTA }),
    t("Coluna 1 texto", { x: 104, y: 1030, w: 400, h: 180 }, { texto: "Faça o autoexame todo mês, a partir dos 20 anos, e conheça o seu corpo.", fonte: "manrope", peso: 500, tamanho: 29, linha: 1.4, cor: "#4A2233", vertical: "topo" }),
    f("Divisória", "retangulo", { x: 538, y: 968, w: 4, h: 234 }, "#F3C1D3"),
    t("Coluna 2 título", { x: 576, y: 960, w: 400, h: 64 }, { texto: "Agende", fonte: "fraunces", peso: 700, tamanho: 46, cor: MAGENTA }),
    t("Coluna 2 texto", { x: 576, y: 1030, w: 400, h: 180 }, { texto: "Mamografia todo ano a partir dos 40, ou antes se o seu médico pedir.", fonte: "manrope", peso: 500, tamanho: 29, linha: 1.4, cor: "#4A2233", vertical: "topo" }),
    marca(p, 60, 1276, 52, "#FFFFFF", "esquerda", 360),
    t("Perfil", { x: 620, y: 1276, w: 400, h: 52 }, { texto: "@suamarca", fonte: "manrope", peso: 700, tamanho: 28, cor: "#FFFFFF", alinhamento: "direita" }),
  ];
  return documento(W, H, fundoDoBanner({ cor: MAGENTA, textura: "nenhuma" }), pecas);
}

/* ======================================================= 9. equipe na foto */

const ROXO = "#5B2EFF";
const LILAS = "#B9A6FF";
const TINTA = "#14112B";

function equipeNaFoto(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const pecas: Peca[] = [
    foto("Foto", FOTO.equipe, { x: 0, y: 0, w: W, h: H }, { ajuste: "cobrir" }),
    f("Sombra de baixo", "retangulo", { x: 0, y: 420, w: W, h: 930 }, linear("#0B0B14", "#0B0B14", 180, 0, 0.94)),
    f("Sombra de cima", "retangulo", { x: 0, y: 0, w: W, h: 280 }, linear("#0B0B14", "#0B0B14", 0, 0, 0.6)),
    ...(p.logo ? [marca(p, 60, 60, 60, "#FFFFFF", "esquerda", 360)] : [ic("Brilho", "estrela-4", 60, 62, 54, "#FFFFFF", { preenchido: true, espessura: 0.5 }), t("Marca", { x: 126, y: 60, w: 500, h: 58 }, { texto: "Sua marca", fonte: "plus-jakarta-sans", peso: 800, tamanho: 38, cor: "#FFFFFF" })]),
    t("Título", { x: 60, y: 830, w: 960, h: 250 }, {
      texto: "Sua equipe merece\nser reconhecida.",
      html: htmlDoTextoLimpo(`Sua equipe merece<br>ser ${trecho(`color:${LILAS}`, "reconhecida.")}`),
      fonte: "plus-jakarta-sans",
      peso: 800,
      tamanho: 94,
      linha: 1.04,
      espaco: -0.02,
      cor: "#FFFFFF",
      vertical: "base",
    }),
    t("Texto", { x: 60, y: 1094, w: 860, h: 96 }, { texto: "Reconhecer é o jeito mais simples de reter os talentos do seu time.", fonte: "manrope", peso: 500, tamanho: 33, linha: 1.35, cor: "#FFFFFF", opacidade: 0.85, vertical: "topo" }),
    f("Botão da seta", "circulo", { x: 60, y: 1216, w: 88, h: 88 }, "#FFFFFF"),
    ic("Seta", "seta-direita", 82, 1238, 44, TINTA, { espessura: 2.4 }),
    t("Arrasta", { x: 168, y: 1220, w: 390, h: 80 }, {
      texto: "Arrasta para o lado",
      fonte: "manrope",
      peso: 700,
      tamanho: 30,
      cor: "#FFFFFF",
      alinhamento: "centro",
      fundo: { forma: "pilula", cor: "#FFFFFF" },
    }),
  ];
  const arrasta = pecas.find((x) => x.nome === "Arrasta") as PecaDeTexto;
  arrasta.fundo = { ...arrasta.fundo!, pintura: { ...solida("#FFFFFF"), alfa: 0.12 }, borda: { cor: "#FFFFFF", largura: 2 } };
  return documento(W, H, fundoDoBanner({ cor: TINTA, textura: "nenhuma" }), pecas);
}

/* ===================================================== 10. pessoas na fita */

function pessoasNaFita(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const etiquetas: Array<[string, number, number]> = [
    ["Reconhecimento", 60, 300],
    ["Cultura", 374, 188],
    ["Resultados", 576, 238],
  ];
  const pecas: Peca[] = etiquetas.map(([nome, x, w]) => {
    const peca = t(nome, { x, y: 70, w, h: 64 }, { texto: nome, fonte: "manrope", peso: 700, tamanho: 26, cor: ROXO, alinhamento: "centro", fundo: { forma: "pilula", cor: "#FFFFFF" } });
    peca.fundo = { ...peca.fundo!, pintura: { tipo: "nenhuma", cor: "#FFFFFF", cor2: "#FFFFFF", angulo: 0 }, borda: { cor: ROXO, largura: 2.5 } };
    return peca;
  });
  pecas.push(
    marca(p, 830, 80, 44, TINTA, "direita", 190),
    t("Título", { x: 60, y: 186, w: 980, h: 250 }, {
      texto: "Pessoas felizes\nentregam mais.",
      html: htmlDoTextoLimpo(`Pessoas felizes<br>${trecho(`color:${ROXO}`, "entregam mais.")}`),
      fonte: "plus-jakarta-sans",
      peso: 800,
      tamanho: 106,
      linha: 1.02,
      espaco: -0.03,
      cor: TINTA,
    }),
    t("Texto", { x: 60, y: 456, w: 540, h: 180 }, { texto: "Programas de reconhecimento aumentam o engajamento e a produtividade do time.", fonte: "manrope", peso: 500, tamanho: 34, linha: 1.38, cor: "#4B4760", vertical: "topo" }),
    f("Fita clara", "fita", { x: -120, y: 880, w: 1320, h: 380, rot: -6 }, LILAS, { profundidade: 0.3 }),
    f("Fita", "fita", { x: -140, y: 730, w: 1360, h: 400, rot: -12 }, ROXO, { profundidade: 0.32 }),
    foto("Pessoa", FOTO.homemSorrindo, { x: 590, y: 420, w: 470, h: 963 }, { sombra: { cor: "#1E0E66", x: 0, y: 20, desfoque: 40, opacidade: 0.3 } }),
    t("Botão", { x: 60, y: 1222, w: 300, h: 84 }, { texto: "Saiba mais", fonte: "plus-jakarta-sans", peso: 800, tamanho: 32, cor: "#FFFFFF", alinhamento: "centro", fundo: { forma: "pilula", cor: TINTA } }),
  );
  return documento(W, H, fundoDoBanner({ cor: "#FFFFFF", textura: "nenhuma" }), pecas);
}

/* ===================================================== 11. cartão no roxo */

function cartaoNoRoxo(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const dicas = ["Agradeça em público e corrija em particular.", "Celebre as pequenas vitórias da semana.", "Dê autonomia e confie nas entregas."];
  const pecas: Peca[] = [
    f("Fita de cima", "fita", { x: -240, y: 40, w: 1560, h: 440, rot: 16 }, "#7B5CFF", { profundidade: 0.3 }),
    f("Fita do meio", "fita", { x: -300, y: 560, w: 1660, h: 320, rot: 8 }, "#9F86FF", { profundidade: 0.26, opacidade: 0.55 }),
    f("Fita de baixo", "fita", { x: -240, y: 930, w: 1560, h: 440, rot: -14 }, "#3A14C9", { profundidade: 0.3 }),
    f("Cartão", "retangulo", { x: 90, y: 160, w: 900, h: 1020 }, "#FFFFFF", { raio: 44, sombra: { cor: "#1A0570", x: 0, y: 24, desfoque: 60, opacidade: 0.35 } }),
    t("Etiqueta", { x: 150, y: 224, w: 250, h: 58 }, { texto: "DICA DO DIA", fonte: "manrope", peso: 800, tamanho: 24, espaco: 0.08, cor: ROXO, alinhamento: "centro", fundo: { forma: "pilula", cor: "#EDE7FF" } }),
    t("Título", { x: 150, y: 310, w: 780, h: 260 }, {
      texto: "3 formas de valorizar o seu time",
      html: htmlDoTextoLimpo(`3 formas de ${trecho(`color:${ROXO}`, "valorizar")} o seu time`),
      fonte: "plus-jakarta-sans",
      peso: 800,
      tamanho: 74,
      linha: 1.08,
      espaco: -0.02,
      cor: TINTA,
      vertical: "topo",
    }),
  ];
  dicas.forEach((d, i) => {
    const y = 608 + i * 146;
    pecas.push(
      t(`Número ${i + 1}`, { x: 150, y, w: 78, h: 78 }, { texto: String(i + 1), fonte: "plus-jakarta-sans", peso: 800, tamanho: 36, cor: "#FFFFFF", alinhamento: "centro", fundo: { forma: "circulo", cor: ROXO } }),
      t(`Dica ${i + 1}`, { x: 254, y: y - 6, w: 680, h: 92 }, { texto: d, fonte: "manrope", peso: 600, tamanho: 34, linha: 1.3, cor: "#2B2840" }),
    );
  });
  pecas.push(
    f("Linha", "retangulo", { x: 150, y: 1052, w: 780, h: 2 }, "#E6E1F5"),
    marca(p, 150, 1084, 56, TINTA, "esquerda", 420),
    ic("Seta", "seta-direita", 880, 1086, 52, ROXO, { espessura: 2.4 }),
    t("Salve", { x: 90, y: 1226, w: 700, h: 60 }, { texto: "Salve para lembrar depois", fonte: "manrope", peso: 700, tamanho: 30, cor: "#FFFFFF" }),
    ic("Salvar", "salvar", 934, 1226, 56, "#FFFFFF", { espessura: 2 }),
  );
  return documento(W, H, fundoDoBanner({ cor: ROXO, textura: "nenhuma" }), pecas);
}

/* ===================================================== 12. movimento (saúde) */

function movimento(p: PedidoDoModelo): DocumentoDoBanner {
  const W = 1080;
  const H = 1350;
  const TEAL = "#0E4F52";
  const pecas: Peca[] = [
    foto("Foto", FOTO.alongamento, { x: 0, y: 0, w: W, h: H }, { ajuste: "cobrir" }),
    f("Véu", "retangulo", { x: 0, y: 0, w: W, h: H }, linear(TEAL, "#08363A", 180, 0.3, 0.94)),
    tex("Curvas de nível", "topografia", { x: 0, y: 0, w: W, h: H }, "#FFFFFF", { opacidade: 0.16, quantidade: 18, centroX: 82, centroY: 18, giro: 40 }),
    f("Perfil", "retangulo", { x: 60, y: 70, w: 340, h: 72 }, "#FFFFFF", { raio: 36 }),
    ic("Instagram", "instagram", 80, 86, 40, TEAL, { espessura: 2 }),
    t("Usuário", { x: 132, y: 70, w: 260, h: 72 }, { texto: "@seuperfil", fonte: "manrope", peso: 700, tamanho: 28, cor: TEAL }),
    t("Título", { x: 60, y: 660, w: 960, h: 420 }, {
      texto: "Movimento\né o melhor\nremédio.",
      html: htmlDoTextoLimpo(`Movimento<br>é o ${trecho("font-family:'Fraunces';font-style:italic", "melhor")}<br>remédio.`),
      fonte: "libre-caslon-display",
      peso: 400,
      tamanho: 132,
      linha: 1.02,
      cor: "#FFFFFF",
      vertical: "base",
    }),
    t("Texto", { x: 60, y: 1100, w: 780, h: 110 }, { texto: "Alongar 10 minutos por dia melhora a postura, a respiração e o humor.", fonte: "manrope", peso: 500, tamanho: 32, linha: 1.38, cor: "#FFFFFF", opacidade: 0.92, vertical: "topo" }),
    f("Linha", "retangulo", { x: 60, y: 1244, w: 960, h: 2 }, { ...solida("#FFFFFF"), alfa: 0.45 }),
    marca(p, 60, 1268, 52, "#FFFFFF", "esquerda", 380),
    t("Especialidades", { x: 560, y: 1268, w: 460, h: 52 }, { texto: "Fisioterapia • Pilates", fonte: "manrope", peso: 600, tamanho: 26, cor: "#FFFFFF", alinhamento: "direita" }),
  ];
  return documento(W, H, fundoDoBanner({ cor: TEAL, textura: "nenhuma" }), pecas);
}

/* ============================================================ outros tamanhos */

/*
 * Desenhado num tamanho, pedido em outro: a composição inteira encaixa no
 * meio (nada se separa: a tira de papel continua com o texto em cima) e o
 * que encosta na borda (fundo, véu, foto inteira, retícula, fita) estica até
 * a borda nova. A releitura genérica (reorganizar.ts) desmontava as colagens.
 */
export function encaixar(doc: DocumentoDoBanner, W2: number, H2: number): DocumentoDoBanner {
  const { largura: W, altura: H } = doc;
  const pecas = doc.pecas.map((p): Peca => {
    const escalada = redimensionarDocumento({ ...doc, pecas: [p] }, W2, H2).pecas[0];
    /* Só estica o que não deforma: retângulo (fundo, véu, linha), retícula, foto que preenche e a fita (feita para atravessar). */
    const estica = (p.tipo === "forma" && (p.forma === "retangulo" || p.forma === "fita")) || p.tipo === "textura" || (p.tipo === "imagem" && p.ajuste === "cobrir");
    const f = escalada.w / p.w;
    /* A fita girada que atravessa a arte de lado a lado continua atravessando. */
    if (p.tipo === "forma" && p.forma === "fita" && p.x <= 1 && p.x + p.w >= W - 1) {
      const esquerda = p.x * f;
      return { ...escalada, x: esquerda, w: W2 - (W - p.x - p.w) * f - esquerda } as Peca;
    }
    if (!estica || p.rot) {
      /* Recorte que sangra de verdade por UMA borda (a pessoa cortada na cintura) continua preso a ela, sem flutuar. */
      let { x, y } = escalada;
      /* Recorte de foto cortado na borda prende sempre; forma só quando sai bastante (o círculo atrás da pessoa fica com ela). */
      const fora = (quanto: number, lado: number) => quanto > (p.tipo === "imagem" ? 1 : lado * 0.2);
      const [esquerda, direita, cima, baixo] = [fora(-p.x, p.w), fora(p.x + p.w - W, p.w), fora(-p.y, p.h), fora(p.y + p.h - H, p.h)];
      if (baixo && !cima) y = H2 - (H - p.y) * f;
      else if (cima && !baixo) y = p.y * f;
      if (direita && !esquerda) x = W2 - (W - p.x) * f;
      else if (esquerda && !direita) x = p.x * f;
      return { ...escalada, x, y } as Peca;
    }
    /* Presa numa borda: a distância até ela (o que sangra para fora) acompanha a escala; a borda é a nova. */
    let [esquerda, direita] = [escalada.x, escalada.x + escalada.w];
    let [cima, baixo] = [escalada.y, escalada.y + escalada.h];
    if (p.x <= 1) esquerda = p.x * f;
    if (p.x + p.w >= W - 1) direita = W2 - (W - p.x - p.w) * f;
    if (p.y <= 1) cima = p.y * f;
    if (p.y + p.h >= H - 1) baixo = H2 - (H - p.y - p.h) * f;
    return { ...escalada, x: esquerda, y: cima, w: direita - esquerda, h: baixo - cima } as Peca;
  });
  return { ...doc, largura: W2, altura: H2, pecas };
}

function emQualquerTamanho(montar: (p: PedidoDoModelo) => DocumentoDoBanner) {
  return (p: PedidoDoModelo): DocumentoDoBanner => {
    const doc = montar(p);
    const W = p.largura;
    const H = p.altura;
    if (W === doc.largura && H === doc.altura) return doc;
    return encaixar(doc, W, H);
  };
}

export const MODELOS_DA_COLECAO = [
  { chave: "post-colagem", nome: "Colagem", descricao: "Papel rasgado, retícula e recortes", montar: colagemEscolhas },
  { chave: "post-quiz", nome: "Enquete", descricao: "Pergunta com opções A, B e C", montar: colagemQuiz },
  { chave: "post-vestibular", nome: "Vestibular", descricao: "Recorte em preto e branco e lista", montar: colagemVestibular },
  { chave: "post-boca", nome: "Colagem quadrada", descricao: "Recorte grande e tiras de papel", montar: colagemBoca },
  { chave: "post-documentos", nome: "Lista com checks", descricao: "Amarelo, itálico e pílulas", montar: documentosParaVotar },
  { chave: "post-rosa-foto", nome: "Campanha com selo", descricao: "Foto, selo circular e redes", montar: outubroRosaFoto },
  { chave: "post-rosa-flor", nome: "Letra gigante", descricao: "Flor recortada e marca-texto", montar: outubroRosaFlor },
  { chave: "post-rosa-maos", nome: "Foto que some", descricao: "Foto no fundo e cartão em duas colunas", montar: outubroRosaMaos },
  { chave: "post-equipe", nome: "Foto inteira", descricao: "Foto escurecida e chamada para arrastar", montar: equipeNaFoto },
  { chave: "post-fita", nome: "Fita ondulada", descricao: "Etiquetas, título e pessoa recortada", montar: pessoasNaFita },
  { chave: "post-cartao", nome: "Cartão de dicas", descricao: "Cartão branco sobre fitas roxas", montar: cartaoNoRoxo },
  { chave: "post-saude", nome: "Curvas de nível", descricao: "Foto com véu, serifa e perfil", montar: movimento },
].map((m) => ({ ...m, montar: emQualquerTamanho(m.montar) }));
