import type { SupabaseClient } from "@supabase/supabase-js";
import webpush from "web-push";

/**
 * Aviso de produção para quem responde pela empresa.
 *
 * Usa os mesmos aparelhos registrados para os lembretes da agenda: quem
 * ligou o push recebe também "perda registrada no pedido #56". Sem chave
 * VAPID configurada, ou sem aparelho, não faz nada e não reclama — o aviso
 * é conveniência, o registro é o que importa.
 */

function configurar() {
  const publica = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY || process.env.VAPID_PUBLIC_KEY;
  const privada = process.env.VAPID_PRIVATE_KEY;
  const contato = process.env.VAPID_SUBJECT || "mailto:contato@ktalogu.com.br";
  if (!publica || !privada) return false;
  webpush.setVapidDetails(contato, publica, privada);
  return true;
}

export async function avisarProducao(
  admin: SupabaseClient,
  params: {
    /* Os ids da empresa e de quem a compõe: a assinatura guarda um deles. */
    tenantIds: string[];
    /* Quem causou o aviso não precisa recebê-lo. */
    exceto?: string | null;
    titulo: string;
    corpo: string;
    rota: string;
    tag?: string;
  }
): Promise<{ enviados: number }> {
  if (!configurar()) return { enviados: 0 };

  const { data: assinaturas } = await admin
    .from("push_subscriptions")
    .select("id,user_id,endpoint,p256dh,auth,failures")
    .in("company_id", params.tenantIds)
    .lt("failures", 5)
    .limit(200);

  let enviados = 0;
  for (const a of assinaturas ?? []) {
    if (params.exceto && String(a.user_id) === params.exceto) continue;
    try {
      await webpush.sendNotification(
        { endpoint: String(a.endpoint), keys: { p256dh: String(a.p256dh), auth: String(a.auth) } },
        JSON.stringify({ titulo: params.titulo, corpo: params.corpo, rota: params.rota, tag: params.tag ?? "producao" })
      );
      enviados += 1;
      await admin
        .from("push_subscriptions")
        .update({ last_sent_at: new Date().toISOString(), failures: 0 })
        .eq("id", a.id);
    } catch (erro) {
      const status = (erro as { statusCode?: number })?.statusCode;
      if (status === 404 || status === 410) {
        await admin.from("push_subscriptions").delete().eq("id", a.id);
      } else {
        await admin
          .from("push_subscriptions")
          .update({ failures: Number(a.failures ?? 0) + 1 })
          .eq("id", a.id);
      }
    }
  }
  return { enviados };
}
