import { NextResponse } from "next/server";
import { quemPodeCriarArtes } from "@/lib/banner-editor/servidor";

/*
 * Banco de imagens grátis do editor: busca no Openverse (acervo aberto, sem
 * chave) só o que é CC0 ou domínio público (uso comercial sem crédito). GET
 * busca; POST traz a imagem escolhida (o endereço vem do próprio Openverse
 * pelo id, nunca do navegador) para o editor subir no depósito da loja.
 */

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

const API = "https://api.openverse.org/v1/images";
const TIPOS = new Set(["image/jpeg", "image/png", "image/webp"]);
const MAXIMO = 15 * 1024 * 1024;

/* O acervo é em inglês: as palavras comuns em português viram a busca em inglês (o resto vai como está). */
const EM_INGLES: Record<string, string> = {
  natal: "christmas", "papai noel": "santa claus", presente: "gift", presentes: "gifts", arvore: "tree", "árvore": "tree", neve: "snow", estrela: "star", "black friday": "black friday", promocao: "sale", "promoção": "sale", desconto: "discount",
  mae: "mother", "mãe": "mother", "dia das maes": "mother flowers", "dia das mães": "mother flowers", pai: "father", flores: "flowers", flor: "flower", rosa: "rose", coracao: "heart", "coração": "heart", amor: "love", casal: "couple", pascoa: "easter", "páscoa": "easter", chocolate: "chocolate", ovo: "egg",
  cafe: "coffee", "café": "coffee", caneca: "mug", camiseta: "t-shirt", roupa: "clothes", moda: "fashion", sapato: "shoes", bolsa: "bag", loja: "store", compras: "shopping", dinheiro: "money", escritorio: "office", "escritório": "office", trabalho: "work", equipe: "team",
  praia: "beach", mar: "sea", ceu: "sky", "céu": "sky", "por do sol": "sunset", "pôr do sol": "sunset", montanha: "mountain", floresta: "forest", cidade: "city", rua: "street", noite: "night", luz: "light", luzes: "lights", fumaca: "smoke", "fumaça": "smoke", brilho: "glitter", textura: "texture", papel: "paper", madeira: "wood", "mármore": "marble", marmore: "marble", fundo: "background",
  comida: "food", bolo: "cake", pizza: "pizza", fruta: "fruit", frutas: "fruits", bebida: "drink", cerveja: "beer", vinho: "wine", cachorro: "dog", gato: "cat", crianca: "child", "criança": "child", bebe: "baby", "bebê": "baby", festa: "party", aniversario: "birthday", "aniversário": "birthday", casamento: "wedding",
  saude: "health", "saúde": "health", academia: "gym", esporte: "sport", futebol: "soccer", carro: "car", tecnologia: "technology", celular: "phone", computador: "computer", livro: "book", escola: "school", musica: "music", "música": "music", beleza: "beauty", maquiagem: "makeup", cabelo: "hair",
};

function traduzir(q: string) {
  const limpo = q.trim().toLowerCase();
  return EM_INGLES[limpo] || limpo.split(/\s+/).map((p) => EM_INGLES[p] || p).join(" ");
}

type Resultado = { id: string; titulo: string; miniatura: string; largura: number; altura: number; fonte: string; autor: string; licenca: string };

/* Busca guardada por 1 h (o acervo não muda a toda hora e o Openverse limita as buscas sem chave). */
const guardadas = ((globalThis as { __bancoDoEditor?: Map<string, { quando: number; lista: Resultado[]; total: number }> }).__bancoDoEditor ??= new Map());

function erro(texto: string, status: number) {
  return NextResponse.json({ error: texto }, { status });
}

export async function GET(pedido: Request) {
  const acesso = await quemPodeCriarArtes();
  if (acesso.falha) return erro(acesso.falha.texto, acesso.falha.status);
  const url = new URL(pedido.url);
  const q = (url.searchParams.get("q") || "").slice(0, 80);
  const pagina = Math.max(1, Math.min(20, Number(url.searchParams.get("pagina")) || 1));
  if (!q.trim()) return NextResponse.json({ lista: [], total: 0 });
  const busca = traduzir(q);
  const chave = `${busca}|${pagina}`;
  const guardada = guardadas.get(chave);
  if (guardada && Date.now() - guardada.quando < 3_600_000) return NextResponse.json({ lista: guardada.lista, total: guardada.total, busca });
  try {
    /* O Openverse às vezes leva mais de 10 s numa busca e responde em 0,2 s na seguinte: tenta de novo uma vez. */
    const endereco = `${API}/?q=${encodeURIComponent(busca)}&license=cc0,pdm&page_size=20&page=${pagina}&mature=false&size=medium,large`;
    const buscar = (espera: number) => fetch(endereco, { headers: { "User-Agent": "KtaloguDesign/1.0 (editor de artes)" }, signal: AbortSignal.timeout(espera) });
    let resposta = await buscar(10000).catch(() => null);
    if (!resposta || (!resposta.ok && resposta.status !== 429)) resposta = await buscar(15000);
    if (resposta.status === 429) return erro("O banco de imagens está ocupado. Tente de novo em um minuto.", 429);
    if (!resposta.ok) return erro("Não deu para buscar agora. Tente de novo.", 502);
    const dados = (await resposta.json()) as { result_count?: number; results?: Array<Record<string, unknown>> };
    const lista: Resultado[] = (dados.results || [])
      .filter((r) => typeof r.id === "string" && (r.license === "cc0" || r.license === "pdm"))
      .map((r) => ({
        id: String(r.id),
        titulo: String(r.title || "").slice(0, 120),
        miniatura: `${API}/${r.id}/thumb/`,
        largura: Number(r.width) || 0,
        altura: Number(r.height) || 0,
        fonte: String(r.source || ""),
        autor: String(r.creator || "").slice(0, 80),
        licenca: r.license === "cc0" ? "CC0" : "Domínio público",
      }));
    guardadas.set(chave, { quando: Date.now(), lista, total: Number(dados.result_count) || lista.length });
    if (guardadas.size > 300) guardadas.delete(guardadas.keys().next().value as string);
    return NextResponse.json({ lista, total: Number(dados.result_count) || lista.length, busca });
  } catch {
    return erro("Não deu para buscar agora. Confira a internet e tente de novo.", 502);
  }
}

export async function POST(pedido: Request) {
  const acesso = await quemPodeCriarArtes();
  if (acesso.falha) return erro(acesso.falha.texto, acesso.falha.status);
  const corpo = (await pedido.json().catch(() => ({}))) as { id?: unknown };
  const id = String(corpo.id || "");
  if (!/^[0-9a-f-]{36}$/i.test(id)) return erro("Imagem inválida.", 400);
  try {
    /* O endereço vem do registro do Openverse (confere de novo a licença). */
    const registro = await fetch(`${API}/${id}/`, { headers: { "User-Agent": "KtaloguDesign/1.0 (editor de artes)" }, signal: AbortSignal.timeout(15000) });
    if (!registro.ok) return erro("Não achei essa imagem no banco.", 404);
    const r = (await registro.json()) as Record<string, unknown>;
    if (r.license !== "cc0" && r.license !== "pdm") return erro("Essa imagem não é livre para uso comercial.", 400);
    const endereco = String(r.url || "");
    if (!/^https:\/\//.test(endereco)) return erro("Essa imagem não dá para usar.", 400);
    const arquivo = await fetch(endereco, { headers: { "User-Agent": "Mozilla/5.0 (KtaloguDesign)" }, redirect: "follow", signal: AbortSignal.timeout(30000) });
    const tipo = (arquivo.headers.get("content-type") || "").split(";")[0].trim().toLowerCase();
    if (!arquivo.ok || !TIPOS.has(tipo)) return erro("Essa imagem não dá para usar (formato ou endereço). Escolha outra.", 415);
    const bytes = new Uint8Array(await arquivo.arrayBuffer());
    if (bytes.length > MAXIMO) return erro("Essa imagem é grande demais. Escolha outra.", 413);
    return new NextResponse(bytes, { headers: { "Content-Type": tipo, "Cache-Control": "no-store", "X-Credito": encodeURIComponent(`${r.title || ""} · ${r.creator || ""} · ${r.license === "cc0" ? "CC0" : "domínio público"}`) } });
  } catch {
    return erro("Não deu para trazer essa imagem agora. Tente outra.", 502);
  }
}
