import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};

// Minimal Web Push implementation using Deno crypto
async function sendWebPush(
  subscription: { endpoint: string; keys: { p256dh: string; auth: string } },
  payload: string,
  vapidPrivateKeyB64: string,
  vapidPublicKeyB64: string,
): Promise<number> {
  const endpoint = subscription.endpoint;
  const audience = new URL(endpoint).origin;

  const header = { alg: 'ES256', typ: 'JWT' };
  const now = Math.floor(Date.now() / 1000);
  const claims = {
    aud: audience,
    exp: now + 12 * 3600,
    sub: 'mailto:admin@oskolkam.net',
  };

  const encode = (obj: object) =>
    btoa(JSON.stringify(obj))
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');

  const headerB64 = encode(header);
  const claimsB64 = encode(claims);
  const signingInput = `${headerB64}.${claimsB64}`;

  // Import private key from raw 32-byte scalar
  const privKeyBytes = Uint8Array.from(
    atob(vapidPrivateKeyB64.replace(/-/g, '+').replace(/_/g, '/')),
    (c) => c.charCodeAt(0),
  );
  const cryptoKey = await crypto.subtle.importKey(
    'raw',
    privKeyBytes,
    { name: 'ECDSA', namedCurve: 'P-256' },
    false,
    ['sign'],
  );

  const encoder = new TextEncoder();
  const sig = await crypto.subtle.sign(
    { name: 'ECDSA', hash: 'SHA-256' },
    cryptoKey,
    encoder.encode(signingInput),
  );
  const sigB64 = btoa(String.fromCharCode(...new Uint8Array(sig)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
  const jwt = `${signingInput}.${sigB64}`;

  const res = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Authorization': `vapid t=${jwt},k=${vapidPublicKeyB64}`,
      'Content-Type': 'application/octet-stream',
      'TTL': '86400',
    },
    body: encoder.encode(payload),
  });
  return res.status;
}

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders });
  }

  const body = await req.json().catch(() => ({}));
  const order = body.record;

  const supabaseAdmin = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!,
  );

  const { data: subs } = await supabaseAdmin
    .from('push_subscriptions')
    .select('subscription');

  if (!subs?.length) {
    return new Response(
      JSON.stringify({ sent: 0 }),
      { headers: { ...corsHeaders, 'Content-Type': 'application/json' } },
    );
  }

  const payload = JSON.stringify({
    title: 'Новая заявка',
    body: `${order?.name || 'Клиент'} — ${order?.phone || ''}`,
    url: '/admin/kanban',
  });

  const vapidPriv = Deno.env.get('VAPID_PRIVATE_KEY')!;
  const vapidPub = Deno.env.get('VITE_VAPID_PUBLIC_KEY')!;

  let sent = 0;
  for (const row of subs) {
    try {
      const status = await sendWebPush(row.subscription, payload, vapidPriv, vapidPub);
      if (status === 200 || status === 201) sent++;
      // Clean up expired/invalid subscriptions
      if (status === 404 || status === 410) {
        await supabaseAdmin
          .from('push_subscriptions')
          .delete()
          .eq('subscription->>endpoint', row.subscription.endpoint);
      }
    } catch (_) {
      // Ignore individual push failures — don't abort the whole batch
    }
  }

  return new Response(
    JSON.stringify({ sent }),
    { headers: { ...corsHeaders, 'Content-Type': 'application/json' } },
  );
});
