import { serve } from "https://deno.land/std@0.190.0/http/server.ts"; 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", }; serve(async (req: Request): Promise => { if (req.method === "OPTIONS") { return new Response(null, { headers: corsHeaders }); } try { const authHeader = req.headers.get("Authorization"); if (!authHeader) { return new Response( JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } const supabase = createClient( Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, { auth: { autoRefreshToken: false, persistSession: false, }, }, ); const token = authHeader.replace("Bearer ", ""); const { data: authData } = await supabase.auth.getUser(token); const user = authData.user; if (!user) { return new Response( JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } const { data: isAdmin } = await supabase .from("user_roles") .select("role") .eq("user_id", user.id) .eq("role", "admin") .maybeSingle(); if (!isAdmin) { return new Response( JSON.stringify({ error: "Forbidden - Admin only" }), { status: 403, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } const { withdrawalId, status, payment_reference, admin_notes, reason } = await req.json(); if (!withdrawalId || !["completed", "rejected"].includes(status)) { return new Response( JSON.stringify({ error: "Invalid payload" }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } const { data: withdrawal } = await supabase .from("withdrawals") .select("*, user:profiles(name, email)") .eq("id", withdrawalId) .maybeSingle(); if (!withdrawal) { return new Response( JSON.stringify({ error: "Withdrawal not found" }), { status: 404, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } if (withdrawal.status !== "pending") { return new Response( JSON.stringify({ error: "Withdrawal already processed" }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } if (status === "completed") { await supabase.rpc("complete_withdrawal", { p_user_id: withdrawal.user_id, p_withdrawal_id: withdrawalId, p_amount: withdrawal.amount, p_payment_reference: payment_reference || "-", }); await supabase .from("withdrawals") .update({ status: "completed", processed_at: new Date().toISOString(), payment_reference: payment_reference || null, admin_notes: admin_notes || null, updated_by: user.id, updated_at: new Date().toISOString(), }) .eq("id", withdrawalId); await supabase.functions.invoke("send-collaboration-notification", { body: { type: "withdrawal_completed", userId: withdrawal.user_id, amount: withdrawal.amount, paymentReference: payment_reference || "-", }, }); } else { await supabase.rpc("reject_withdrawal", { p_user_id: withdrawal.user_id, p_withdrawal_id: withdrawalId, p_amount: withdrawal.amount, p_reason: reason || "Withdrawal rejected by admin", }); await supabase .from("withdrawals") .update({ status: "rejected", processed_at: new Date().toISOString(), admin_notes: admin_notes || reason || null, updated_by: user.id, updated_at: new Date().toISOString(), }) .eq("id", withdrawalId); await supabase.functions.invoke("send-collaboration-notification", { body: { type: "withdrawal_rejected", userId: withdrawal.user_id, amount: withdrawal.amount, reason: admin_notes || reason || "Withdrawal rejected", }, }); } return new Response( JSON.stringify({ success: true }), { status: 200, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } catch (error: unknown) { const message = error instanceof Error ? error.message : "Failed to process withdrawal"; return new Response( JSON.stringify({ error: message }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }, ); } });