import { getSupabaseClient } from "@/lib/supabase";
import { corValida, fonteDaMarcaLimpa, type FonteDaMarca } from "./documento";

/*
 * O kit da marca do editor de artes (migration 223, kit_da_marca): as cores,
 * as fontes enviadas pela loja e os logos, uma linha por empresa. Sem a
 * tabela (migration ainda não aplicada), o kit vale só nesta visita: nada
 * quebra, a arte continua levando as fontes que usa dentro dela.
 */

export type KitDaMarca = { cores: string[]; fontes: FonteDaMarca[]; logos: string[] };

export const KIT_VAZIO: KitDaMarca = { cores: [], fontes: [], logos: [] };

export class KitIndisponivel extends Error {}

function faltaATabela(erro: { code?: string; message?: string } | null) {
  return Boolean(erro && (erro.code === "42P01" || erro.code === "PGRST205" || /kit_da_marca/.test(erro.message || "")));
}

const ENDERECO = /^https:\/\/[a-z0-9-]+\.supabase\.co\/storage\/v1\/object\/public\/[^\s"'<>()]+$/i;

/** O kit conferido (cor válida, fonte do depósito, logo do depósito). */
export function kitLimpo(bruto: unknown): KitDaMarca {
  const x = (bruto ?? {}) as Record<string, unknown>;
  const cores = (Array.isArray(x.cores) ? x.cores : []).map((c) => corValida(c, "")).filter(Boolean);
  const fontes = (Array.isArray(x.fontes) ? x.fontes : []).map(fonteDaMarcaLimpa).filter((f): f is FonteDaMarca => Boolean(f));
  const logos = (Array.isArray(x.logos) ? x.logos : []).filter((l): l is string => typeof l === "string" && ENDERECO.test(l));
  return { cores: [...new Set(cores)].slice(0, 30), fontes: fontes.slice(0, 20), logos: [...new Set(logos)].slice(0, 30) };
}

export async function lerKit(dono: string): Promise<KitDaMarca> {
  const { data, error } = await getSupabaseClient().from("kit_da_marca").select("cores,fontes,logos").eq("user_id", dono).maybeSingle();
  if (faltaATabela(error)) throw new KitIndisponivel("O kit da marca ainda não está ligado.");
  if (error) throw new Error("Não deu para abrir o kit da marca.");
  return data ? kitLimpo(data) : KIT_VAZIO;
}

export async function salvarKit(dono: string, kit: KitDaMarca) {
  const limpo = kitLimpo(kit);
  const { error } = await getSupabaseClient().from("kit_da_marca").upsert({ user_id: dono, cores: limpo.cores, fontes: limpo.fontes, logos: limpo.logos }, { onConflict: "user_id" });
  if (faltaATabela(error)) throw new KitIndisponivel("O kit da marca ainda não está ligado.");
  if (error) throw new Error("Não deu para guardar o kit da marca.");
}

const EXTENSOES_DE_FONTE = /\.(woff2?|ttf|otf)$/i;

/**
 * Sobe um arquivo de fonte (TTF, OTF, WOFF, WOFF2, até 4 MB) para o depósito
 * e confere se o navegador consegue usar. Devolve a fonte pronta para o kit.
 */
export async function enviarFonte(arquivo: File): Promise<FonteDaMarca> {
  if (!EXTENSOES_DE_FONTE.test(arquivo.name)) throw new Error("Use um arquivo de fonte TTF, OTF, WOFF ou WOFF2.");
  if (arquivo.size > 4 * 1024 * 1024) throw new Error("A fonte passa de 4 MB. Use a versão WOFF2 (bem menor).");
  const extensao = (EXTENSOES_DE_FONTE.exec(arquivo.name)?.[1] || "ttf").toLowerCase();
  const chave = `kit-${Math.random().toString(36).slice(2, 10)}${Date.now().toString(36)}`;
  /* Antes de subir: o navegador lê a fonte? (arquivo quebrado não entra no kit) */
  try {
    const teste = new FontFace(chave, await arquivo.arrayBuffer());
    await teste.load();
  } catch {
    throw new Error("Esse arquivo não abriu como fonte. Confira se é a fonte certa.");
  }
  const supabase = getSupabaseClient();
  const caminho = `catalog/sections/pagina-inicial/editor/fontes/${chave}.${extensao}`;
  const tipo = extensao === "woff2" ? "font/woff2" : extensao === "woff" ? "font/woff" : extensao === "otf" ? "font/otf" : "font/ttf";
  const { error } = await supabase.storage.from("products").upload(caminho, arquivo, { contentType: tipo, cacheControl: "31536000" });
  if (error) throw new Error("Não deu para enviar a fonte agora. Tente de novo.");
  const url = supabase.storage.from("products").getPublicUrl(caminho).data.publicUrl;
  const nome = arquivo.name.replace(EXTENSOES_DE_FONTE, "").replace(/[-_]+/g, " ").replace(/[<>"'`]/g, "").trim().slice(0, 60) || "Fonte da marca";
  const fonte = fonteDaMarcaLimpa({ chave, nome, url });
  if (!fonte) throw new Error("Não deu para usar essa fonte.");
  return fonte;
}
