import { serve } from "https://deno.land/std@0.190.0/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.49.1";

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

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

  const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
  const supabaseServiceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
  const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey);

  try {
    // Verify the caller is an admin
    const authHeader = req.headers.get("Authorization");
    if (!authHeader) {
      return new Response(JSON.stringify({ error: "Unauthorized" }), {
        status: 401,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const token = authHeader.replace("Bearer ", "");
    const { data: { user }, error: authError } = await supabaseAdmin.auth.getUser(token);
    if (authError || !user) {
      return new Response(JSON.stringify({ error: "Unauthorized" }), {
        status: 401,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const { data: isAdmin } = await supabaseAdmin.rpc("has_role", {
      _user_id: user.id,
      _role: "admin",
    });
    if (!isAdmin) {
      return new Response(JSON.stringify({ error: "Forbidden" }), {
        status: 403,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const { webhook_log_id } = await req.json();
    if (!webhook_log_id) {
      return new Response(JSON.stringify({ error: "webhook_log_id is required" }), {
        status: 400,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Fetch the original webhook log
    const { data: log, error: logError } = await supabaseAdmin
      .from("webhook_event_logs")
      .select("*")
      .eq("id", webhook_log_id)
      .single();

    if (logError || !log) {
      return new Response(JSON.stringify({ error: "Webhook log not found" }), {
        status: 404,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Determine the target webhook function
    const gatewayFunctionMap: Record<string, string> = {
      stripe: "stripe-webhook",
      paypal: "paypal-webhook",
      coinbase: "coinbase-webhook",
    };

    const functionName = gatewayFunctionMap[log.gateway];
    if (!functionName) {
      return new Response(JSON.stringify({ error: `Unknown gateway: ${log.gateway}` }), {
        status: 400,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Re-invoke the webhook function with the original payload
    const webhookUrl = `${supabaseUrl}/functions/v1/${functionName}`;
    const startTime = Date.now();

    const retryResponse = await fetch(webhookUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${supabaseServiceKey}`,
        // Skip signature verification by adding a retry header
        "X-Webhook-Retry": "true",
      },
      body: JSON.stringify(log.payload),
    });

    const retryStatus = retryResponse.status;
    const retryBody = await retryResponse.text();
    const processingTime = Date.now() - startTime;

    // Log the retry attempt
    await supabaseAdmin.from("webhook_event_logs").insert({
      gateway: log.gateway,
      event_type: `retry:${log.event_type}`,
      event_id: log.event_id,
      status: retryStatus >= 200 && retryStatus < 300 ? "processed" : "failed",
      payload: {
        ...log.payload,
        _retry: {
          original_log_id: webhook_log_id,
          retried_at: new Date().toISOString(),
        },
      },
      response_status: retryStatus,
      error_message: retryStatus >= 400 ? retryBody : null,
      processing_time_ms: processingTime,
    });

    return new Response(
      JSON.stringify({
        success: retryStatus >= 200 && retryStatus < 300,
        response_status: retryStatus,
        processing_time_ms: processingTime,
      }),
      {
        status: 200,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      }
    );
  } catch (error) {
    console.error("Retry webhook error:", error);
    return new Response(
      JSON.stringify({ error: error instanceof Error ? error.message : "Internal error" }),
      {
        status: 500,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      }
    );
  }
});
