import { serve } from "https://deno.land/std@0.190.0/http/server.ts";
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",
};

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);

    const body = await req.json();
    const {
      association_id,
      amenity_id,
      pin_id,
      pin_label,
      guest_name,
      guest_email,
      guest_phone,
      booking_date,
      signature_data,
      amount_cents,
      success_url,
      cancel_url,
      form_data,
      booking_type,
      title,
      start_time,
      end_time,
      notes,
    } = body;

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

    // Save the reservation as pending
    const { data: booking, error: bookingError } = await supabase
      .from("amenity_bookings")
      .insert({
        amenity_id,
        association_id,
        guest_name,
        guest_email: guest_email || null,
        guest_phone: guest_phone || null,
        booking_date,
        booking_type: booking_type || "rental",
        title: title || `Reservation: ${pin_label || "Amenity"}`,
        start_time: start_time || null,
        end_time: end_time || null,
        form_data: form_data || {},
        notes: notes || JSON.stringify({
          pin_id,
          pin_label,
          signature: signature_data || null,
          form_data: form_data || null,
        }),
        status: amount_cents > 0 ? "pending_payment" : "confirmed",
      })
      .select()
      .single();

    if (bookingError) {
      return new Response(
        JSON.stringify({ error: bookingError.message }),
        { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Create form inbox entry
    await supabase.from("form_inbox").insert({
      source_type: "reservation",
      source_id: booking.id,
      association_id,
      title: `Reservation: ${pin_label || "Amenity Spot"}`,
      submitter_name: guest_name,
      submitter_email: guest_email || null,
      summary: `${pin_label || "Spot"} | Date: ${booking_date} | Fee: ${amount_cents > 0 ? "$" + (amount_cents / 100).toFixed(2) : "Free"}`,
      status: "new",
    });

    // Send in-app notifications to admin/manager users
    try {
      const { data: adminRoles } = await supabase
        .from("user_roles")
        .select("user_id")
        .in("role", ["admin", "manager"]);

      if (adminRoles && adminRoles.length > 0) {
        for (const role of adminRoles) {
          await supabase.rpc("insert_notification", {
            p_user_id: role.user_id,
            p_type: "reservation",
            p_title: `New Reservation: ${pin_label || "Amenity Spot"}`,
            p_message: `${guest_name} submitted a reservation for ${pin_label || "a spot"} on ${booking_date}.`,
            p_related_item_id: booking.id,
            p_related_item_type: "amenity_booking",
          });
        }
      }
    } catch (notifErr) {
      console.error("Failed to send admin notifications:", notifErr);
    }

    // If no fee — mark pin as rented immediately
    if (!amount_cents || amount_cents <= 0) {
      await markPinAsRented(supabase, amenity_id, pin_id);
      return new Response(
        JSON.stringify({ success: true, booking_id: booking.id }),
        { headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

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

    let mapping = stripeMapping;
    if (!mapping) {
      const { data: companyMapping } = await supabase
        .from("stripe_account_mappings")
        .select("*")
        .is("association_id", null)
        .eq("is_active", true)
        .maybeSingle();
      mapping = companyMapping;
    }

    if (!mapping?.stripe_secret_key) {
      return new Response(
        JSON.stringify({
          success: true,
          booking_id: booking.id,
          payment_note: "No payment gateway configured. Reservation saved as pending.",
        }),
        { headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Calculate fee — always pass processing fees to the payer for reservations
    let totalCents = Math.round((amount_cents + 30) / (1 - 0.029));

    // Create Stripe Checkout Session
    const stripeParams = new URLSearchParams();
    stripeParams.append("mode", "payment");
    stripeParams.append("line_items[0][price_data][currency]", "usd");
    stripeParams.append("line_items[0][price_data][unit_amount]", String(totalCents));
    stripeParams.append("line_items[0][price_data][product_data][name]", `Reservation: ${pin_label || "Amenity"}`);
    stripeParams.append("line_items[0][quantity]", "1");
    stripeParams.append("customer_email", guest_email || "");
    stripeParams.append("success_url", `${success_url}?session_id={CHECKOUT_SESSION_ID}&booking_id=${booking.id}`);
    stripeParams.append("cancel_url", cancel_url || success_url);
    stripeParams.append("metadata[booking_id]", booking.id);
    stripeParams.append("metadata[association_id]", association_id);
    stripeParams.append("metadata[amenity_id]", amenity_id);
    stripeParams.append("metadata[pin_id]", pin_id || "");

    const stripeResp = await fetch("https://api.stripe.com/v1/checkout/sessions", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${mapping.stripe_secret_key}`,
        "Content-Type": "application/x-www-form-urlencoded",
      },
      body: stripeParams.toString(),
    });

    const session = await stripeResp.json();

    if (!stripeResp.ok) {
      console.error("Stripe error:", session);
      return new Response(
        JSON.stringify({ error: session.error?.message || "Stripe checkout failed" }),
        { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    return new Response(
      JSON.stringify({
        success: true,
        booking_id: booking.id,
        checkout_url: session.url,
      }),
      { headers: { ...corsHeaders, "Content-Type": "application/json" } }
    );
  } catch (err) {
    console.error("Error in create-reservation-checkout:", err);
    return new Response(
      JSON.stringify({ error: err.message || "Internal server error" }),
      { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
    );
  }
});

// Helper: update the pin status to "rented" in the amenity's map_config
async function markPinAsRented(supabase: any, amenityId: string, pinId: string) {
  try {
    const { data: amenity } = await supabase
      .from("amenities")
      .select("map_config")
      .eq("id", amenityId)
      .single();

    if (!amenity?.map_config?.pins) return;

    const updatedPins = amenity.map_config.pins.map((pin: any) =>
      pin.id === pinId ? { ...pin, status: "rented" } : pin
    );

    await supabase
      .from("amenities")
      .update({
        map_config: { ...amenity.map_config, pins: updatedPins },
        updated_at: new Date().toISOString(),
      })
      .eq("id", amenityId);
  } catch (err) {
    console.error("Failed to mark pin as rented:", err);
  }
}
