import { randomUUID } from "node:crypto";
import { NextResponse } from "next/server";
import sharp from "sharp";
import { createAdminClient } from "@/lib/supabase-server";
import { imprimirImagem } from "@/lib/assistentes/ferramentas/gerador-de-banner";
import { documentoLimpo, documentoDasPaginas, paginasDoDocumento } from "@/lib/banner-editor/documento";
import { tipoDaArte } from "@/lib/banner-editor/comunidade-tipos";
import { htmlComAsImagens, quemPodeCriarArtes } from "@/lib/banner-editor/servidor";

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

/**
 * Publicar uma arte como modelo da comunidade (migration 227): confere a
 * arte (da empresa de quem pede), o tipo pelo tamanho, tira o nome e o
 * avatar de quem fez (o perfil da pessoa ou, sem ele, a loja), faz a
 * miniatura da primeira página e guarda PENDENTE. Quem aprova é o dono da
 * plataforma, no Owner.
 */

const RAMOS = new Set(["sublimacao", "grafica", "personalizados"]);
const PENDENTES_POR_EMPRESA = 10;

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

const texto = (valor: unknown, maximo: number) => (typeof valor === "string" ? valor.replace(/\s+/g, " ").trim().slice(0, maximo) : "");

export async function POST(req: Request) {
  const acesso = await quemPodeCriarArtes();
  if (acesso.falha) return erro(acesso.falha.texto, acesso.falha.status);
  const corpo = (await req.json().catch(() => null)) as Record<string, unknown> | null;
  if (!corpo) return erro("Pedido inválido.", 400);
  if (corpo.aceite !== true) return erro("Confirme que a arte pode ser usada por outras empresas.", 400);
  const arteId = texto(corpo.arteId, 60);
  const nome = texto(corpo.nome, 80);
  const descricao = texto(corpo.descricao, 200) || null;
  const ramo = typeof corpo.ramo === "string" && RAMOS.has(corpo.ramo) ? corpo.ramo : null;
  if (!arteId) return erro("Escolha a arte.", 400);
  if (!nome) return erro("Dê um nome ao modelo.", 400);

  /* A arte vem 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,formato,documento").eq("id", arteId).eq("user_id", acesso.dono).maybeSingle();
  if (erroDaArte || !arte) return erro("Essa arte não foi encontrada.", 404);
  const linha = arte as { id: string; largura: number; altura: number; formato: string | null; documento: unknown };
  const paginas = paginasDoDocumento(documentoLimpo(linha.documento, linha.largura, linha.altura));
  const documento = documentoDasPaginas(paginas);
  if (!paginas.some((pagina) => pagina.pecas.some((p) => !p.oculta))) return erro("A arte está vazia.", 400);
  const tipo = tipoDaArte(documento);
  if (!tipo) return erro("Esse tamanho ainda não tem categoria de modelos. Use post, carrossel, story, banner da loja ou caneca.", 400);

  const admin = createAdminClient();
  const { data: jaEnviados, error: erroDosEnvios } = await admin.from("modelos_da_comunidade").select("id,status,arte_id").eq("user_id", acesso.dono).in("status", ["pendente", "aprovado"]);
  if (erroDosEnvios) {
    if (erroDosEnvios.code === "42P01" || erroDosEnvios.code === "PGRST205") return erro("A comunidade de modelos ainda não foi ligada no banco (falta a migration 227).", 503);
    return erro("Não deu para enviar agora. Tente de novo.", 500);
  }
  const enviados = (jaEnviados || []) as Array<{ id: string; status: string; arte_id: string | null }>;
  if (enviados.some((e) => e.arte_id === arteId)) return erro("Essa arte já foi enviada para a comunidade.", 409);
  if (enviados.filter((e) => e.status === "pendente").length >= PENDENTES_POR_EMPRESA) return erro(`Você já tem ${PENDENTES_POR_EMPRESA} modelos em análise. Espere a resposta para mandar mais.`, 429);

  /* Quem fez: o perfil da pessoa (funcionário) ou, sem ele, a loja. */
  const [{ data: pessoa }, { data: perfil }] = await Promise.all([
    admin.from("employee_profiles").select("full_name,avatar_url").eq("user_id", acesso.usuario).maybeSingle(),
    admin.from("profiles").select("store_name,catalog_name,logo_url,catalog_logo_url,avatar_url").eq("id", acesso.dono).maybeSingle(),
  ]);
  const p = (perfil || {}) as { store_name?: string | null; catalog_name?: string | null; logo_url?: string | null; catalog_logo_url?: string | null; avatar_url?: string | null };
  const f = (pessoa || {}) as { full_name?: string | null; avatar_url?: string | null };
  const loja = (p.catalog_name || p.store_name || "").trim() || null;
  const autorNome = ((f.full_name || "").trim() || loja || "Assinante Ktalogu").slice(0, 80);
  const autorAvatar = f.avatar_url || p.avatar_url || p.catalog_logo_url || p.logo_url || null;

  const id = randomUUID();
  /* A miniatura da primeira página (a galeria e o Owner mostram sem montar a arte). */
  let miniatura: string | null = null;
  try {
    const primeira = paginas[0];
    const escala = Math.min(1, 900 / Math.max(primeira.largura, primeira.altura));
    const html = await htmlComAsImagens(primeira, { escala: 1 });
    const png = await imprimirImagem(html, primeira.largura, primeira.altura, { escala: Math.max(0.3, escala) });
    const webp = await sharp(png).resize(900, 900, { fit: "inside", withoutEnlargement: true }).webp({ quality: 84 }).toBuffer();
    const caminho = `editor-comunidade/${id}.webp`;
    const { error: erroDoEnvio } = await admin.storage.from("products").upload(caminho, webp, { contentType: "image/webp", upsert: true, cacheControl: "31536000" });
    if (!erroDoEnvio) miniatura = admin.storage.from("products").getPublicUrl(caminho).data.publicUrl;
  } catch (falha) {
    console.error("[comunidade] miniatura", falha instanceof Error ? falha.message : falha);
  }

  const { error } = await admin.from("modelos_da_comunidade").insert({
    id,
    user_id: acesso.dono,
    enviado_por: acesso.usuario,
    arte_id: arteId,
    nome,
    descricao,
    tipo,
    ramo,
    largura: documento.largura,
    altura: documento.altura,
    formato: linha.formato,
    paginas: paginas.length,
    documento,
    miniatura,
    autor_nome: autorNome,
    autor_avatar: autorAvatar,
    autor_loja: loja,
  });
  if (error) {
    if (error.code === "42P01" || error.code === "PGRST205") return erro("A comunidade de modelos ainda não foi ligada no banco (falta a migration 227).", 503);
    console.error("[comunidade] envio", error.message);
    return erro(error.message?.includes("grande demais") ? error.message : "Não deu para enviar agora. Tente de novo.", 400);
  }
  return NextResponse.json({ id }, { headers: { "Cache-Control": "no-store" } });
}
