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 the calling user
    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 body = await req.json();
    const { association_id, owner_id, unit_id, payment_method_type } = body;

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

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

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

    const stripeSecretKey = mapping.stripe_secret_key;

    // Get or create Stripe customer
    // Check if there's already an enrollment with a customer ID for this user+association
    const { data: existingEnrollment } = await supabase
      .from("autopay_enrollments")
      .select("stripe_customer_id")
      .eq("association_id", association_id)
      .eq("enrolled_by", user.id)
      .not("stripe_customer_id", "is", null)
      .limit(1)
      .maybeSingle();

    let stripeCustomerId = existingEnrollment?.stripe_customer_id;

    if (!stripeCustomerId) {
      // Create a new Stripe customer
      const customerParams = new URLSearchParams();
      customerParams.append("email", user.email || "");
      customerParams.append("metadata[user_id]", user.id);
      customerParams.append("metadata[association_id]", association_id);

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

      const customerData = await customerRes.json();
      if (!customerRes.ok) {
        console.error("Stripe customer error:", customerData);
        return new Response(
          JSON.stringify({
            error:
              customerData.error?.message || "Failed to create Stripe customer",
          }),
          {
            status: 400,
            headers: { ...corsHeaders, "Content-Type": "application/json" },
          }
        );
      }
      stripeCustomerId = customerData.id;
    }

    // Create a SetupIntent to save a payment method
    const setupParams = new URLSearchParams();
    setupParams.append("customer", stripeCustomerId!);
    setupParams.append("usage", "off_session");

    const isAch = payment_method_type === "us_bank_account";
    if (isAch) {
      setupParams.append("payment_method_types[]", "us_bank_account");
      setupParams.append(
        "payment_method_options[us_bank_account][financial_connections][permissions][]",
        "payment_method"
      );
    } else {
      setupParams.append("automatic_payment_methods[enabled]", "true");
    }

    setupParams.append("metadata[association_id]", association_id);
    setupParams.append("metadata[user_id]", user.id);
    if (owner_id) setupParams.append("metadata[owner_id]", owner_id);
    if (unit_id) setupParams.append("metadata[unit_id]", unit_id);

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

    const setupData = await setupRes.json();
    if (!setupRes.ok) {
      console.error("Stripe SetupIntent error:", setupData);
      return new Response(
        JSON.stringify({
          error:
            setupData.error?.message || "Failed to create SetupIntent",
        }),
        {
          status: 400,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }

    return new Response(
      JSON.stringify({
        clientSecret: setupData.client_secret,
        setupIntentId: setupData.id,
        customerId: stripeCustomerId,
        publishableKey: mapping.stripe_publishable_key,
      }),
      {
        status: 200,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      }
    );
  } catch (err: unknown) {
    console.error("Error in setup-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" },
    });
  }
});
