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",
};

interface PayPalConfig {
  client_id: string;
  client_secret: string;
  webhook_id?: string;
}

interface CheckoutRequest {
  type: "subscription" | "credits" | "invoice";
  plan_id?: string;
  billing_cycle?: "monthly" | "yearly";
  credit_pack_id?: string;
  invoice_id?: string;
  success_url: string;
  cancel_url: string;
}

async function getPayPalConfig(supabase: any): Promise<{ config: PayPalConfig; isTestMode: boolean } | null> {
  const { data, error } = await supabase
    .from("payment_gateway_configs")
    .select("*")
    .eq("gateway", "paypal")
    .single();

  if (error || !data || !data.is_enabled) {
    return null;
  }

  const configData = data.is_test_mode ? data.sandbox_config : data.live_config;
  
  if (!configData?.client_id || !configData?.client_secret) {
    return null;
  }

  return {
    config: configData as PayPalConfig,
    isTestMode: data.is_test_mode,
  };
}

async function getPayPalAccessToken(config: PayPalConfig, isTestMode: boolean): Promise<string> {
  const baseUrl = isTestMode
    ? "https://api-m.sandbox.paypal.com"
    : "https://api-m.paypal.com";

  const auth = btoa(`${config.client_id}:${config.client_secret}`);

  const response = await fetch(`${baseUrl}/v1/oauth2/token`, {
    method: "POST",
    headers: {
      Authorization: `Basic ${auth}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: "grant_type=client_credentials",
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`PayPal auth failed: ${error}`);
  }

  const data = await response.json();
  return data.access_token;
}

async function createPayPalOrder(
  accessToken: string,
  isTestMode: boolean,
  amount: number,
  currency: string,
  description: string,
  successUrl: string,
  cancelUrl: string
): Promise<{ id: string; approvalUrl: string }> {
  const baseUrl = isTestMode
    ? "https://api-m.sandbox.paypal.com"
    : "https://api-m.paypal.com";

  const response = await fetch(`${baseUrl}/v2/checkout/orders`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      intent: "CAPTURE",
      purchase_units: [
        {
          amount: {
            currency_code: currency.toUpperCase(),
            value: amount.toFixed(2),
          },
          description,
        },
      ],
      application_context: {
        return_url: successUrl,
        cancel_url: cancelUrl,
        brand_name: "AppForge",
        user_action: "PAY_NOW",
      },
    }),
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`PayPal order creation failed: ${error}`);
  }

  const data = await response.json();
  const approvalLink = data.links.find((l: any) => l.rel === "approve");

  return {
    id: data.id,
    approvalUrl: approvalLink?.href || "",
  };
}

async function createPayPalSubscription(
  accessToken: string,
  isTestMode: boolean,
  planId: string,
  successUrl: string,
  cancelUrl: string
): Promise<{ id: string; approvalUrl: string }> {
  const baseUrl = isTestMode
    ? "https://api-m.sandbox.paypal.com"
    : "https://api-m.paypal.com";

  const response = await fetch(`${baseUrl}/v1/billing/subscriptions`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      plan_id: planId,
      application_context: {
        return_url: successUrl,
        cancel_url: cancelUrl,
        brand_name: "AppForge",
        user_action: "SUBSCRIBE_NOW",
      },
    }),
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`PayPal subscription creation failed: ${error}`);
  }

  const data = await response.json();
  const approvalLink = data.links.find((l: any) => l.rel === "approve");

  return {
    id: data.id,
    approvalUrl: approvalLink?.href || "",
  };
}

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 supabaseAnonKey = Deno.env.get("SUPABASE_ANON_KEY")!;

    // Get user from auth header
    const authHeader = req.headers.get("Authorization");
    if (!authHeader) {
      return new Response(JSON.stringify({ error: "Unauthorized" }), {
        status: 401,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    const supabaseClient = createClient(supabaseUrl, supabaseAnonKey, {
      global: { headers: { Authorization: authHeader } },
    });

    const {
      data: { user },
    } = await supabaseClient.auth.getUser();

    if (!user) {
      return new Response(JSON.stringify({ error: "Unauthorized" }), {
        status: 401,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      });
    }

    // Use service role for admin operations
    const supabaseAdmin = createClient(supabaseUrl, supabaseServiceKey);

    // Get PayPal config
    const paypalResult = await getPayPalConfig(supabaseAdmin);
    if (!paypalResult) {
      return new Response(
        JSON.stringify({ error: "PayPal is not configured or enabled" }),
        {
          status: 400,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }

    const { config, isTestMode } = paypalResult;
    const body: CheckoutRequest = await req.json();

    const accessToken = await getPayPalAccessToken(config, isTestMode);

    let orderId: string;
    let approvalUrl: string;
    let amount: number;
    let description: string;
    let transactionType: string;
    let referenceId: string | null = null;

    if (body.type === "subscription" && body.plan_id) {
      // Get plan details
      const { data: plan } = await supabaseAdmin
        .from("subscription_plans")
        .select("*")
        .eq("id", body.plan_id)
        .single();

      if (!plan) {
        throw new Error("Plan not found");
      }

      // Check if PayPal recurring plan exists
      const paypalPlanId = body.billing_cycle === "yearly" 
        ? (plan as any).paypal_yearly_plan_id 
        : (plan as any).paypal_plan_id;

      amount = body.billing_cycle === "yearly" ? plan.price_yearly : plan.price_monthly;
      description = `${plan.name} Subscription (${body.billing_cycle})`;
      transactionType = "subscription";
      referenceId = plan.id;

      if (paypalPlanId) {
        // Create PayPal subscription (recurring)
        const result = await createPayPalSubscription(
          accessToken,
          isTestMode,
          paypalPlanId,
          body.success_url,
          body.cancel_url
        );
        orderId = result.id;
        approvalUrl = result.approvalUrl;

        // Store as subscription transaction
        await supabaseAdmin.from("payment_transactions").insert({
          user_id: user.id,
          amount,
          currency: "USD",
          payment_method: "paypal",
          transaction_type: transactionType,
          status: "pending",
          paypal_subscription_id: orderId,
          reference_id: referenceId,
          metadata: {
            billing_cycle: body.billing_cycle,
            is_test_mode: isTestMode,
            is_recurring: true,
          },
        });

        return new Response(
          JSON.stringify({
            subscriptionId: orderId,
            approvalUrl,
            isRecurring: true,
          }),
          {
            status: 200,
            headers: { ...corsHeaders, "Content-Type": "application/json" },
          }
        );
      }

      // Fallback to one-time order if no PayPal plan configured
      const result = await createPayPalOrder(
        accessToken,
        isTestMode,
        amount,
        "USD",
        description,
        body.success_url,
        body.cancel_url
      );
      orderId = result.id;
      approvalUrl = result.approvalUrl;

    } else if (body.type === "credits" && body.credit_pack_id) {
      // Get credit pack details
      const { data: pack } = await supabaseAdmin
        .from("credit_packs")
        .select("*")
        .eq("id", body.credit_pack_id)
        .single();

      if (!pack) {
        throw new Error("Credit pack not found");
      }

      amount = pack.price;
      description = `${pack.name} - ${pack.credits} Credits`;
      transactionType = "credit_purchase";
      referenceId = pack.id;

      const result = await createPayPalOrder(
        accessToken,
        isTestMode,
        amount,
        "USD",
        description,
        body.success_url,
        body.cancel_url
      );
      orderId = result.id;
      approvalUrl = result.approvalUrl;

    } else if (body.type === "invoice" && body.invoice_id) {
      // Get invoice details
      const { data: invoice } = await supabaseAdmin
        .from("invoices")
        .select("*")
        .eq("id", body.invoice_id)
        .eq("user_id", user.id)
        .single();

      if (!invoice || invoice.status === "paid") {
        throw new Error("Invoice not found or already paid");
      }

      amount = invoice.amount;
      description = `Invoice #${invoice.invoice_number}`;
      transactionType = "invoice_payment";
      referenceId = invoice.id;

      const result = await createPayPalOrder(
        accessToken,
        isTestMode,
        amount,
        invoice.currency || "USD",
        description,
        body.success_url,
        body.cancel_url
      );
      orderId = result.id;
      approvalUrl = result.approvalUrl;

    } else {
      throw new Error("Invalid checkout request");
    }

    // Create pending transaction
    await supabaseAdmin.from("payment_transactions").insert({
      user_id: user.id,
      amount,
      currency: "USD",
      payment_method: "paypal",
      transaction_type: transactionType,
      status: "pending",
      paypal_order_id: orderId,
      reference_id: referenceId,
      metadata: {
        billing_cycle: body.billing_cycle,
        is_test_mode: isTestMode,
      },
    });

    return new Response(
      JSON.stringify({
        orderId,
        approvalUrl,
      }),
      {
        status: 200,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      }
    );
  } catch (error) {
    console.error("PayPal checkout error:", error);
    const errorMessage = error instanceof Error ? error.message : "Internal server error";
    return new Response(
      JSON.stringify({ error: errorMessage }),
      {
        status: 500,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      }
    );
  }
});
