/*
 * A aparência da área de membros: a loja escolhe a letra dos títulos, a cor
 * de destaque, o fundo e o formato das capas dos módulos (prévias 15 a 17).
 * Tudo vira variáveis CSS (--m-*) num invólucro da área; as telas só leem as
 * variáveis. Este arquivo é igual nos dois apps (loja e painel): mexeu num,
 * copie no outro.
 */

export type IdDaFonte =
  | "cinema"
  | "impacto"
  | "esportivo"
  | "retro"
  | "estudio"
  | "futurista"
  | "criativo"
  | "grotesca"
  | "classico"
  | "revista"
  | "elegante"
  | "editorial";

export type FonteDosTitulos = {
  id: IdDaFonte;
  nome: string;
  descricao: string;
  /* O pedaço `family=` do Google Fonts. */
  google: string;
  familia: string;
  peso: number;
  /* Largura (só a Archivo tem o eixo). */
  largura: number;
  caixaAlta: boolean;
  italico: boolean;
  espaco: string;
  altura: number;
  /* As letras largas pedem título menor; as estreitas aguentam maior. */
  escala: number;
};

export const FONTES_DOS_TITULOS: FonteDosTitulos[] = [
  { id: "cinema", nome: "Cinema", descricao: "Condensada e forte, como pôster de filme", google: "Archivo:wdth,wght@62..125,100..900", familia: "Archivo", peso: 900, largura: 62, caixaAlta: true, italico: false, espaco: "-0.01em", altura: 0.92, escala: 1 },
  { id: "impacto", nome: "Impacto", descricao: "Alta e grossa, chama atenção de longe", google: "Anton", familia: "Anton", peso: 400, largura: 100, caixaAlta: true, italico: false, espaco: "0.005em", altura: 0.95, escala: 0.94 },
  { id: "esportivo", nome: "Esportivo", descricao: "Estreita e firme, jeito de academia", google: "Big+Shoulders+Display:wght@700..900", familia: "Big Shoulders Display", peso: 900, largura: 100, caixaAlta: true, italico: false, espaco: "0.01em", altura: 0.9, escala: 1.02 },
  { id: "retro", nome: "Retrô", descricao: "Gordinha e divertida", google: "Bowlby+One", familia: "Bowlby One", peso: 400, largura: 100, caixaAlta: true, italico: false, espaco: "0em", altura: 0.98, escala: 0.62 },
  { id: "estudio", nome: "Estúdio", descricao: "Moderna, com personalidade", google: "Bricolage+Grotesque:opsz,wdth,wght@12..96,75..100,200..800", familia: "Bricolage Grotesque", peso: 800, largura: 100, caixaAlta: false, italico: false, espaco: "-0.035em", altura: 0.98, escala: 0.74 },
  { id: "futurista", nome: "Futurista", descricao: "Larga e geométrica, cara de tecnologia", google: "Unbounded:wght@600..900", familia: "Unbounded", peso: 800, largura: 100, caixaAlta: false, italico: false, espaco: "-0.03em", altura: 1.02, escala: 0.58 },
  { id: "criativo", nome: "Criativo", descricao: "Diferente, para quem cria", google: "Syne:wght@700..800", familia: "Syne", peso: 800, largura: 100, caixaAlta: false, italico: false, espaco: "-0.03em", altura: 1, escala: 0.7 },
  { id: "grotesca", nome: "Grotesca", descricao: "Limpa e segura, vai com tudo", google: "Familjen+Grotesk:wght@600..700", familia: "Familjen Grotesk", peso: 700, largura: 100, caixaAlta: false, italico: false, espaco: "-0.035em", altura: 1, escala: 0.76 },
  { id: "classico", nome: "Clássico", descricao: "Serifada em itálico, sofisticada", google: "Fraunces:ital,opsz,wght@0,9..144,600..900;1,9..144,600..900", familia: "Fraunces", peso: 800, largura: 100, caixaAlta: false, italico: true, espaco: "-0.02em", altura: 1, escala: 0.74 },
  { id: "revista", nome: "Revista", descricao: "Serifa de capa de revista", google: "DM+Serif+Display:ital@0;1", familia: "DM Serif Display", peso: 400, largura: 100, caixaAlta: false, italico: false, espaco: "-0.01em", altura: 1, escala: 0.78 },
  { id: "elegante", nome: "Elegante", descricao: "Fina e delicada, para beleza e moda", google: "Instrument+Serif:ital@0;1", familia: "Instrument Serif", peso: 400, largura: 100, caixaAlta: false, italico: true, espaco: "-0.01em", altura: 0.98, escala: 0.86 },
  { id: "editorial", nome: "Editorial", descricao: "Serifa marcante, de jornal", google: "Gloock", familia: "Gloock", peso: 400, largura: 100, caixaAlta: false, italico: false, espaco: "-0.015em", altura: 1, escala: 0.74 },
];

export type IdDoFundo = "preto" | "grafite" | "azul" | "claro";

export const FUNDOS_DA_AREA: Array<{ id: IdDoFundo; nome: string; escuro: boolean; cores: [string, string, string] }> = [
  { id: "preto", nome: "Preto profundo", escuro: true, cores: ["#07070A", "#101016", "#18181F"] },
  { id: "grafite", nome: "Grafite", escuro: true, cores: ["#121014", "#1B181E", "#242028"] },
  { id: "azul", nome: "Azul-noite", escuro: true, cores: ["#070B18", "#0E1426", "#151D33"] },
  { id: "claro", nome: "Claro", escuro: false, cores: ["#F4F2EE", "#FFFFFF", "#E9E6E0"] },
];

export type FormatoDasCapas = "em_pe" | "deitada";

/* As cores vivas sugeridas (a da loja vem marcada antes delas). */
export const CORES_SUGERIDAS = ["#FF5A1F", "#FF2E88", "#7C3AED", "#2563FF", "#00C2A8", "#22C55E", "#FFC21A", "#E11D48"];

export type AparenciaGuardada = { fonte: IdDaFonte; fundo: IdDoFundo; capas: FormatoDasCapas };

/* O que veio do banco (area da digital_settings) vira escolhas válidas. */
export function lerAparencia(area: Record<string, unknown>): AparenciaGuardada {
  const fonte = FONTES_DOS_TITULOS.some((f) => f.id === area.fonte) ? (area.fonte as IdDaFonte) : "cinema";
  const fundo = FUNDOS_DA_AREA.some((f) => f.id === area.fundo)
    ? (area.fundo as IdDoFundo)
    : area.aparencia === "clara"
      ? "claro"
      : "preto";
  const capas: FormatoDasCapas = area.capas === "deitada" ? "deitada" : "em_pe";
  return { fonte, fundo, capas };
}

export function fonteDosTitulos(id: IdDaFonte): FonteDosTitulos {
  return FONTES_DOS_TITULOS.find((f) => f.id === id) ?? FONTES_DOS_TITULOS[0];
}

/* O endereço do Google Fonts com a letra do texto (Archivo) e a dos títulos. */
export function enderecoDasFontes(ids: IdDaFonte[]): string {
  const familias = new Set<string>(["Archivo:wdth,wght@62..125,100..900"]);
  for (const id of ids) familias.add(fonteDosTitulos(id).google);
  return `https://fonts.googleapis.com/css2?${Array.from(familias).map((f) => `family=${f}`).join("&")}&display=swap`;
}

function canais(hex: string): [number, number, number] {
  const limpo = hex.replace("#", "");
  return [0, 2, 4].map((i) => parseInt(limpo.slice(i, i + 2), 16) || 0) as [number, number, number];
}

function luminancia(hex: string): number {
  const [r, g, b] = canais(hex).map((c) => {
    const v = c / 255;
    return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
  });
  return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}

/* Texto em cima da cor: branco, a não ser que a cor seja clara. */
export function textoSobre(hex: string): string {
  return luminancia(hex) > 0.42 ? "#111014" : "#FFFFFF";
}

/* Cor muito apagada (cinza, quase preto ou quase branco) não serve de destaque: vira a laranja viva. */
export function corDeDestaque(hex: string | null | undefined): string {
  const valor = typeof hex === "string" && /^#[0-9a-fA-F]{6}$/.test(hex.trim()) ? hex.trim().toUpperCase() : "#FF5A1F";
  const [r, g, b] = canais(valor);
  const maior = Math.max(r, g, b);
  const menor = Math.min(r, g, b);
  const saturacao = maior === 0 ? 0 : (maior - menor) / maior;
  if (saturacao < 0.18 || maior < 40) return "#FF5A1F";
  return valor;
}

/* As variáveis CSS da área (vão no style do invólucro). */
export function variaveisDaArea(params: { aparencia: AparenciaGuardada; cor: string }): Record<string, string> {
  const fonte = fonteDosTitulos(params.aparencia.fonte);
  const fundo = FUNDOS_DA_AREA.find((f) => f.id === params.aparencia.fundo) ?? FUNDOS_DA_AREA[0];
  const acento = corDeDestaque(params.cor);
  const [f1, f2, f3] = fundo.cores;
  const emPe = params.aparencia.capas === "em_pe";
  return {
    "--m-acento": acento,
    "--m-acento-texto": textoSobre(acento),
    "--m-fundo": f1,
    "--m-fundo-2": f2,
    "--m-fundo-3": f3,
    "--m-texto": fundo.escuro ? "#F5F5F7" : "#16131C",
    "--m-texto-2": fundo.escuro ? "rgba(245,245,247,0.68)" : "rgba(22,19,28,0.68)",
    "--m-texto-3": fundo.escuro ? "rgba(245,245,247,0.44)" : "rgba(22,19,28,0.48)",
    "--m-linha": fundo.escuro ? "rgba(255,255,255,0.09)" : "rgba(22,19,28,0.1)",
    "--m-realce": fundo.escuro ? "rgba(255,255,255,0.06)" : "rgba(22,19,28,0.05)",
    "--m-vidro": fundo.escuro ? "rgba(255,255,255,0.12)" : "rgba(22,19,28,0.07)",
    "--m-titulo-familia": `"${fonte.familia}", "Archivo", sans-serif`,
    "--m-titulo-peso": String(fonte.peso),
    "--m-titulo-largura": String(fonte.largura),
    "--m-titulo-caixa": fonte.caixaAlta ? "uppercase" : "none",
    "--m-titulo-estilo": fonte.italico ? "italic" : "normal",
    "--m-titulo-espaco": fonte.espaco,
    "--m-titulo-altura": String(fonte.altura),
    "--m-escala": String(fonte.escala),
    "--m-raio": emPe ? "10px" : "16px",
    "--m-capa-proporcao": emPe ? "2 / 3" : "16 / 10",
    "--m-capa-largura": emPe ? "210px" : "300px",
    "--m-capa-largura-celular": emPe ? "148px" : "250px",
  };
}

/* Título de pôster com palavra comprida ou muito texto: letra menor, sem quebrar palavra no meio. */
export function nomeLongo(texto: string): boolean {
  const palavras = texto.trim().split(/\s+/);
  return texto.length > 24 || palavras.some((p) => p.length > 9);
}
