// Supabase Edge Function — fan-out push notifications via Web Push (VAPID).
//
// Trigger: server-side (e.g. database trigger on messages INSERT calling
// pg_net.http_post → this function), or app-level after sendEncryptedMessage
// resolves successfully.
//
// Required environment variables (set via supabase secrets):
//   VAPID_PUBLIC_KEY
//   VAPID_PRIVATE_KEY
//   VAPID_SUBJECT             e.g. "mailto:admin@example.com"
//   PUSH_FANOUT_SHARED_SECRET shared header secret to authenticate caller
//
// Request body:
//   { conversationId: string, senderUserId: string, senderName: string, kind?: "message" | "call" }
//
// The function:
//   1. Looks up conversation_members minus sender.
//   2. Joins to push_tokens via devices.
//   3. Sends a Web Push to each token using web-push npm via npm: specifier.
//
// Note: this is a skeleton — wire web-push library and verify against the
// chosen Deno deploy runtime.

// deno-lint-ignore-file no-explicit-any
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
import webPush from 'npm:web-push@3.6.7';

const SUPABASE_URL = Deno.env.get('SUPABASE_URL') ?? '';
const SERVICE_ROLE_KEY = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '';
const VAPID_PUBLIC_KEY = Deno.env.get('VAPID_PUBLIC_KEY') ?? '';
const VAPID_PRIVATE_KEY = Deno.env.get('VAPID_PRIVATE_KEY') ?? '';
const VAPID_SUBJECT = Deno.env.get('VAPID_SUBJECT') ?? 'mailto:admin@example.com';
const SHARED_SECRET = Deno.env.get('PUSH_FANOUT_SHARED_SECRET') ?? '';

if (VAPID_PUBLIC_KEY && VAPID_PRIVATE_KEY) {
  webPush.setVapidDetails(VAPID_SUBJECT, VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY);
}

interface Payload {
  conversationId: string;
  senderUserId: string;
  senderName: string;
  kind?: 'message' | 'call';
}

Deno.serve(async (req) => {
  if (req.method !== 'POST') return new Response('method', { status: 405 });

  // Shared-secret gate. Cheap, replaces user JWT here because the trigger has
  // no authenticated session.
  const auth = req.headers.get('x-shared-secret');
  if (!SHARED_SECRET || auth !== SHARED_SECRET) {
    return new Response('unauthorized', { status: 401 });
  }

  let body: Payload;
  try {
    body = await req.json();
  } catch {
    return new Response('bad json', { status: 400 });
  }

  const client = createClient(SUPABASE_URL, SERVICE_ROLE_KEY);

  const { data: members, error: mErr } = await client
    .from('conversation_members')
    .select('user_id')
    .eq('conversation_id', body.conversationId);
  if (mErr) return new Response('members lookup failed', { status: 500 });
  const recipientIds = (members ?? [])
    .map((m: any) => m.user_id as string)
    .filter((id: string) => id !== body.senderUserId);
  if (recipientIds.length === 0) return new Response('no recipients', { status: 200 });

  const { data: tokens, error: tErr } = await client
    .from('push_tokens')
    .select('token, devices!inner(user_id)')
    .in('devices.user_id', recipientIds);
  if (tErr) return new Response('tokens lookup failed', { status: 500 });

  const payload = JSON.stringify({
    title: body.senderName,
    body: body.kind === 'call' ? 'Eingehender Anruf' : 'Neue Nachricht',
    conversationId: body.conversationId,
    kind: body.kind ?? 'message',
  });

  const results = await Promise.allSettled(
    (tokens ?? []).map(async (row: any) => {
      try {
        const sub = JSON.parse(row.token);
        await webPush.sendNotification(sub, payload);
      } catch (err) {
        console.warn('push send failed', err);
      }
    }),
  );

  return new Response(JSON.stringify({ sent: results.length }), {
    headers: { 'content-type': 'application/json' },
  });
});
