import { NextResponse } from "next/server";
import sharp from "sharp";
import { createAdminClient } from "@/lib/supabase-server";
import { BannerDemorou, GeradorOcupado, imprimirImagem } from "@/lib/assistentes/ferramentas/gerador-de-banner";
import { documentoLimpo, paginasDoDocumento } from "@/lib/banner-editor/documento";
import { htmlComAsImagens, quemPodeCriarArtes } from "@/lib/banner-editor/servidor";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export const maxDuration = 90;

/**
 * A foto (miniatura) de um design da empresa, para a galeria mostrar uma
 * imagem em vez de montar a arte peça por peça. Fotografa a primeira página
 * no Chrome do servidor (o mesmo desenho do download), guarda em
 * editor-artes/<id>/<carimbo>.webp (carimbo = hora da última gravação) e
 * apaga as fotos das versões antigas.
 */

const LADO = 640;

function erro(texto: string, status: number) {
  return NextResponse.json({ error: texto }, { status, headers: { "Cache-Control": "no-store" } });
}

export async function POST(request: Request) {
  const acesso = await quemPodeCriarArtes();
  if ("falha" in acesso && acesso.falha) return erro(acesso.falha.texto, acesso.falha.status);
  const corpo = (await request.json().catch(() => ({}))) as { id?: unknown };
  const id = typeof corpo.id === "string" && /^[0-9a-f-]{36}$/i.test(corpo.id) ? corpo.id : "";
  if (!id) return erro("Escolha o design.", 400);

  /* A arte pelo cliente da pessoa: o RLS só deixa ler as da empresa dela. */
  const { data: arte, error: erroDaArte } = await acesso.supabase.from("artes_do_editor").select("id,largura,altura,documento,updated_at").eq("id", id).eq("user_id", acesso.dono).maybeSingle();
  if (erroDaArte || !arte) return erro("Esse design não foi encontrado.", 404);
  const linha = arte as { id: string; largura: number; altura: number; documento: unknown; updated_at: string };
  const pasta = `editor-artes/${id}`;
  const caminho = `${pasta}/${Date.parse(linha.updated_at) || 0}.webp`;
  const admin = createAdminClient();
  const deposito = admin.storage.from("products");
  const endereco = deposito.getPublicUrl(caminho).data.publicUrl;

  /* Já tirada (outra aba pediu antes): devolve a mesma. */
  const { data: existentes } = await deposito.list(pasta, { limit: 20 });
  const nomes = (existentes || []).map((f) => f.name);
  if (nomes.includes(caminho.slice(pasta.length + 1))) return NextResponse.json({ src: endereco }, { headers: { "Cache-Control": "no-store" } });

  /*
   * A foto é a última da fila: o Chrome do servidor é um só (baixar a arte,
   * gerar banner, publicar na comunidade). Com qualquer um deles rodando ou
   * esperando, responde "ocupado" e a galeria tenta de novo mais tarde.
   */
  if ((globalThis.__filaDosBanners?.esperando ?? 0) > 0) return erro("Ocupado, tente de novo.", 503);

  try {
    const primeira = paginasDoDocumento(documentoLimpo(linha.documento, linha.largura, linha.altura))[0];
    const escala = Math.min(1, LADO / Math.max(primeira.largura, primeira.altura));
    const html = await htmlComAsImagens(primeira, { escala: Math.max(0.2, escala) });
    const png = await imprimirImagem(html, primeira.largura, primeira.altura, { escala: Math.max(0.2, escala) });
    const webp = await sharp(png).resize(LADO, LADO, { fit: "inside", withoutEnlargement: true }).webp({ quality: 80 }).toBuffer();
    const { error: erroDoEnvio } = await deposito.upload(caminho, webp, { contentType: "image/webp", upsert: true, cacheControl: "31536000" });
    if (erroDoEnvio) return erro("Não deu para guardar a miniatura.", 500);
    const velhas = nomes.filter((n) => n !== caminho.slice(pasta.length + 1)).map((n) => `${pasta}/${n}`);
    if (velhas.length) await deposito.remove(velhas);
    return NextResponse.json({ src: endereco }, { headers: { "Cache-Control": "no-store" } });
  } catch (falha) {
    if (falha instanceof GeradorOcupado || falha instanceof BannerDemorou) return erro("Ocupado, tente de novo.", 503);
    console.error("[artes] miniatura", falha instanceof Error ? falha.message : falha);
    return erro("Não deu para fazer a miniatura.", 500);
  }
}
