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

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

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

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

    // Verify admin/manager
    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 supabase.auth.getUser(token);
    if (authError || !user) {
      return new Response(JSON.stringify({ error: "Unauthorized" }), {
        status: 401,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const { data: roles } = await supabase
      .from("user_roles")
      .select("role")
      .eq("user_id", user.id);

    const isAdmin = roles?.some((r: any) =>
      ["admin", "manager"].includes(r.role)
    );
    if (!isAdmin) {
      return new Response(JSON.stringify({ error: "Forbidden" }), {
        status: 403,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const body = await req.json();
    const { association_id, amount_cents, description, enrollment_ids } = body;

    if (!association_id || !amount_cents || amount_cents <= 0) {
      return new Response(
        JSON.stringify({
          error: "association_id and valid amount_cents are required",
        }),
        {
          status: 400,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }

    // Get Stripe mapping
    const { data: mapping } = await supabase
      .from("stripe_account_mappings")
      .select("*")
      .eq("association_id", association_id)
      .eq("is_active", true)
      .maybeSingle();

    if (!mapping?.stripe_secret_key) {
      return new Response(
        JSON.stringify({ error: "No Stripe configuration for this association" }),
        {
          status: 400,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }

    // Get active enrollments
    let enrollmentQuery = supabase
      .from("autopay_enrollments")
      .select("*")
      .eq("association_id", association_id)
      .eq("is_active", true);

    if (enrollment_ids?.length) {
      enrollmentQuery = enrollmentQuery.in("id", enrollment_ids);
    }

    const { data: enrollments, error: enrollError } = await enrollmentQuery;
    if (enrollError) throw enrollError;

    if (!enrollments || enrollments.length === 0) {
      return new Response(
        JSON.stringify({ error: "No active autopay enrollments found", results: [] }),
        {
          status: 200,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }

    const stripeSecretKey = mapping.stripe_secret_key;
    const results: any[] = [];

    for (const enrollment of enrollments) {
      try {
        // Calculate fees if applicable
        let feeCents = 0;
        const isAch = enrollment.payment_method_type === "us_bank_account";
        if (mapping.pass_processing_fee) {
          if (isAch) {
            feeCents = Math.min(Math.ceil(amount_cents * 0.008), 500);
          } else {
            const feePercent = Number(mapping.processing_fee_percent) || 0.029;
            const feeFixed = Number(mapping.processing_fee_fixed_cents) || 30;
            const grossed = Math.ceil(
              (amount_cents + feeFixed) / (1 - feePercent)
            );
            feeCents = grossed - amount_cents;
          }
        }

        const totalCents = amount_cents + feeCents;

        // Create PaymentIntent with saved payment method
        const params = new URLSearchParams();
        params.append("amount", String(totalCents));
        params.append("currency", "usd");
        params.append("customer", enrollment.stripe_customer_id);
        params.append("payment_method", enrollment.stripe_payment_method_id);
        params.append("off_session", "true");
        params.append("confirm", "true");
        params.append(
          "description",
          description || "HOA Autopay Assessment"
        );
        params.append("metadata[association_id]", association_id);
        params.append("metadata[enrollment_id]", enrollment.id);
        params.append("metadata[autopay]", "true");
        if (enrollment.owner_id)
          params.append("metadata[owner_id]", enrollment.owner_id);
        if (enrollment.unit_id)
          params.append("metadata[unit_id]", enrollment.unit_id);

        if (isAch) {
          params.append("payment_method_types[]", "us_bank_account");
        }

        const stripeRes = await fetch(
          "https://api.stripe.com/v1/payment_intents",
          {
            method: "POST",
            headers: {
              Authorization: `Bearer ${stripeSecretKey}`,
              "Content-Type": "application/x-www-form-urlencoded",
            },
            body: params.toString(),
          }
        );

        const stripeData = await stripeRes.json();

        // Record payment
        await supabase.from("stripe_payments").insert({
          association_id,
          owner_id: enrollment.owner_id || null,
          unit_id: enrollment.unit_id || null,
          stripe_payment_intent_id: stripeData.id,
          amount_cents,
          fee_cents: feeCents,
          total_cents: totalCents,
          payment_method_type: isAch ? "us_bank_account" : "card",
          status: stripeRes.ok ? "succeeded" : "failed",
          description: description || "HOA Autopay Assessment",
        });

        results.push({
          enrollment_id: enrollment.id,
          owner_id: enrollment.owner_id,
          success: stripeRes.ok,
          payment_intent_id: stripeData.id,
          amount_cents: totalCents,
          error: stripeRes.ok ? null : stripeData.error?.message,
        });
      } catch (chargeErr: any) {
        results.push({
          enrollment_id: enrollment.id,
          owner_id: enrollment.owner_id,
          success: false,
          error: chargeErr.message,
        });
      }
    }

    const succeeded = results.filter((r) => r.success).length;
    const failed = results.filter((r) => !r.success).length;

    return new Response(
      JSON.stringify({ results, summary: { total: results.length, succeeded, failed } }),
      {
        status: 200,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      }
    );
  } catch (err: unknown) {
    console.error("Error in process-autopay:", err);
    const message =
      err instanceof Error ? err.message : "Internal server error";
    return new Response(JSON.stringify({ error: message }), {
      status: 500,
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  }
});
