import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
import { createEdgeFunction, type EdgeFunctionContext } from '../_shared/edgeFunctionWrapper.ts';
import { corsHeaders } from '../_shared/cors.ts';
import { addSpanEvent } from '../_shared/logger.ts';

serve(createEdgeFunction({
  name: 'novu-webhook',
  requireAuth: false, // Webhooks don't use standard auth
  useServiceRole: true, // Need service role to update notification_logs
  corsHeaders,
}, async (req, { span, supabase, requestId }: EdgeFunctionContext) => {
  const event = await req.json();

  addSpanEvent(span, 'received_webhook_event', { 
    eventType: event.type 
  });

  // Handle different webhook events
  switch (event.type) {
    case 'notification.sent':
      await handleNotificationSent(supabase, event, span);
      break;
    case 'notification.delivered':
      await handleNotificationDelivered(supabase, event, span);
      break;
    case 'notification.read':
      await handleNotificationRead(supabase, event, span);
      break;
    case 'notification.failed':
      await handleNotificationFailed(supabase, event, span);
      break;
    default:
      addSpanEvent(span, 'unhandled_event_type', { 
        eventType: event.type 
      });
  }

  return new Response(
    JSON.stringify({ success: true, requestId }),
    {
      headers: { 
        'Content-Type': 'application/json'
      },
      status: 200,
    }
  );
}));

async function handleNotificationSent(supabase: any, event: any, span: any) {
  const { transactionId, channel } = event.data;
  
  addSpanEvent(span, 'notification_sent_update', { 
    transactionId, 
    channel 
  });
  
  await supabase
    .from('notification_logs')
    .update({ status: 'sent' })
    .eq('novu_transaction_id', transactionId);
}

async function handleNotificationDelivered(supabase: any, event: any, span: any) {
  const { transactionId } = event.data;
  
  addSpanEvent(span, 'notification_delivered_update', { 
    transactionId 
  });
  
  await supabase
    .from('notification_logs')
    .update({ 
      status: 'delivered',
      delivered_at: new Date().toISOString(),
    })
    .eq('novu_transaction_id', transactionId);
}

async function handleNotificationRead(supabase: any, event: any, span: any) {
  const { transactionId } = event.data;
  
  addSpanEvent(span, 'notification_read_update', { 
    transactionId 
  });
  
  await supabase
    .from('notification_logs')
    .update({ 
      read_at: new Date().toISOString(),
    })
    .eq('novu_transaction_id', transactionId);
}

async function handleNotificationFailed(supabase: any, event: any, span: any) {
  const { transactionId, error } = event.data;
  
  addSpanEvent(span, 'notification_failed_update', { 
    transactionId, 
    error 
  });
  
  await supabase
    .from('notification_logs')
    .update({ 
      status: 'failed',
      error_message: error,
    })
    .eq('novu_transaction_id', transactionId);
}
