import { createHmac } from "node:crypto";
import { enderecosDaLoja } from "@/lib/endereco-da-loja";

/**
 * Avisa a loja virtual que a vitrine de um dono mudou, para a lembrança dos
 * dados dela sumir na hora (ver apps/public/src/lib/loja/dados-da-loja.ts).
 *
 * É "dispara e esquece": nunca atrasa nem derruba a gravação do admin. Se a
 * loja não responder, a mudança aparece sozinha em até dois minutos, que é
 * o prazo da lembrança. A assinatura usa a chave de serviço do Supabase, que
 * os dois apps já têm: nenhuma variável nova no servidor. Onde a loja atende
 * está em lib/endereco-da-loja.ts.
 */
export function avisarLoja(userId: string | null | undefined, request?: Request) {
  void avisarLojaEEsperar(userId, request);
}

/**
 * O mesmo aviso, para quem quer saber se a loja ouviu (a rota
 * /api/loja/avisar, que o admin chama depois de gravar direto do navegador).
 * Nunca lança: devolve `false` quando a loja não respondeu.
 */
export async function avisarLojaEEsperar(userId: string | null | undefined, request?: Request): Promise<boolean> {
  const id = String(userId || "").trim();
  const chave = process.env.SUPABASE_SERVICE_ROLE_KEY || "";
  if (!id || !chave) return false;

  const token = createHmac("sha256", chave).update(`loja:${id}`).digest("hex");
  for (const base of enderecosDaLoja(request)) {
    if (await pedirParaEsquecer(base, id, token)) return true;
  }
  return false;
}

async function pedirParaEsquecer(base: string, userId: string, token: string) {
  const controle = new AbortController();
  const limite = setTimeout(() => controle.abort(), 4000);
  try {
    const resposta = await fetch(`${base}/api/loja/revalidar`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ userId, token }),
      signal: controle.signal,
      cache: "no-store",
      /* Redirecionamento aqui é sempre engano de endereço, e seguir um 301
         transforma o POST em GET: a loja responde 405 e o aviso morre calado. */
      redirect: "manual",
    });
    return resposta.ok;
  } catch {
    return false;
  } finally {
    clearTimeout(limite);
  }
}
