import { getSupabaseClient } from "@/lib/supabase";
import { baixarArte, type VinculoComOrcamento } from "./artes";
import type { DocumentoDoBanner } from "./documento";

/*
 * A arte do KtaloguDesign ligada a um item do orçamento (o "Criar no
 * KtaloguDesign" do item): o editor mostra para qual orçamento ela vai e
 * "Enviar para o orçamento" transforma as páginas em imagens da arte do item
 * (as mesmas do "Adicionar arte": quote_item_arts, depósito quote-arts), que
 * aparecem no orçamento, no PDF e no link do cliente.
 */

export type DadosDoVinculo = { numero: number | null; item: string | null; dono: string };

/** O número do orçamento e o nome do item (para o editor mostrar). */
export async function dadosDoVinculo(v: VinculoComOrcamento): Promise<DadosDoVinculo | null> {
  const supabase = getSupabaseClient();
  const [{ data: orcamento }, { data: item }] = await Promise.all([
    supabase.from("quotes").select("number,user_id").eq("id", v.orcamento).maybeSingle(),
    v.item ? supabase.from("quote_items").select("title").eq("id", v.item).eq("quote_id", v.orcamento).maybeSingle() : Promise.resolve({ data: null }),
  ]);
  if (!orcamento) return null;
  const o = orcamento as { number: number | null; user_id: string };
  return { numero: o.number ?? null, item: (item as { title?: string | null } | null)?.title?.trim() || null, dono: o.user_id };
}

/* A página exportada (PNG do servidor) vira WebP, como as fotos do "Adicionar arte". */
async function emWebp(arquivo: Blob, maximo = 2000, qualidade = 0.88): Promise<Blob> {
  const imagem = await createImageBitmap(arquivo);
  const escala = Math.min(1, maximo / Math.max(imagem.width, imagem.height));
  const tela = document.createElement("canvas");
  tela.width = Math.max(1, Math.round(imagem.width * escala));
  tela.height = Math.max(1, Math.round(imagem.height * escala));
  const ctx = tela.getContext("2d");
  if (!ctx) throw new Error("Não deu para preparar a imagem.");
  ctx.fillStyle = "#FFFFFF";
  ctx.fillRect(0, 0, tela.width, tela.height);
  ctx.drawImage(imagem, 0, 0, tela.width, tela.height);
  imagem.close();
  const webp = await new Promise<Blob | null>((resolve) => tela.toBlob(resolve, "image/webp", qualidade));
  if (!webp) throw new Error("Não deu para preparar a imagem.");
  return webp;
}

/**
 * Manda as páginas para a arte do item (uma imagem por página, até 10). Arte
 * reprovada pelo cliente ou `substituir` (uma versão nova mandada para
 * aprovar): as imagens novas entram no lugar e a aprovação volta para
 * pendente; senão, somam às que já estavam.
 */
export async function enviarParaOOrcamento(pedido: { vinculo: VinculoComOrcamento; paginas: DocumentoDoBanner[]; nome: string; substituir?: boolean; aoAndar?: (feitas: number, total: number) => void }): Promise<{ imagens: number; numero: number | null }> {
  const { vinculo, nome } = pedido;
  if (!vinculo.item) throw new Error("Esta arte não está ligada a um item do orçamento.");
  const dados = await dadosDoVinculo(vinculo);
  if (!dados) throw new Error("O orçamento desta arte não foi encontrado (pode ter sido apagado).");
  const paginas = pedido.paginas.slice(0, 10);
  const supabase = getSupabaseClient();
  const enderecos: string[] = [];
  for (const [i, pagina] of paginas.entries()) {
    const feita = await baixarArte({ documento: pagina, largura: pagina.largura, altura: pagina.altura, nome: paginas.length > 1 ? `${nome} ${String(i + 1).padStart(2, "0")}` : nome, formato: "png", escala: 1, qualidade: 0.92, transparente: false }, true);
    const webp = await emWebp(feita.arquivo);
    const caminho = `${dados.dono}/quotes/${vinculo.orcamento}/items/${vinculo.item}/${crypto.randomUUID()}.webp`;
    const { error } = await supabase.storage.from("quote-arts").upload(caminho, webp, { contentType: "image/webp" });
    if (error) throw new Error("Não deu para guardar a imagem no orçamento.");
    enderecos.push(supabase.storage.from("quote-arts").getPublicUrl(caminho).data.publicUrl);
    pedido.aoAndar?.(i + 1, paginas.length);
  }
  const { data: atual } = await supabase.from("quote_item_arts").select("image_urls,approval_status,title").eq("quote_item_id", vinculo.item).maybeSingle();
  const antes = atual as { image_urls?: string[] | null; approval_status?: string | null; title?: string | null } | null;
  const reprovada = antes?.approval_status === "rejected" || Boolean(pedido.substituir);
  const { error } = await supabase.from("quote_item_arts").upsert(
    {
      quote_id: vinculo.orcamento,
      quote_item_id: vinculo.item,
      title: antes?.title?.trim() || dados.item || nome,
      image_urls: [...(reprovada ? [] : antes?.image_urls || []), ...enderecos],
      ...(reprovada ? { approval_status: "pending", approval_notes: null, approved_at: null, reviewed_at: null } : {}),
    },
    { onConflict: "quote_item_id" },
  );
  if (error) throw new Error("As imagens subiram, mas não deu para ligar ao item do orçamento.");
  return { imagens: enderecos.length, numero: dados.numero };
}
