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 CoinbaseConfig {
  api_key: string;
  webhook_secret?: 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 getCoinbaseConfig(supabase: any): Promise<{ config: CoinbaseConfig; isTestMode: boolean } | null> {
  const { data, error } = await supabase
    .from("payment_gateway_configs")
    .select("*")
    .eq("gateway", "coinbase")
    .single();

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

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

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

async function createCoinbaseCharge(
  apiKey: string,
  amount: number,
  currency: string,
  name: string,
  description: string,
  metadata: Record<string, string>,
  successUrl: string,
  cancelUrl: string
): Promise<{ id: string; hostedUrl: string }> {
  const response = await fetch("https://api.commerce.coinbase.com/charges", {
    method: "POST",
    headers: {
      "X-CC-Api-Key": apiKey,
      "X-CC-Version": "2018-03-22",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name,
      description,
      pricing_type: "fixed_price",
      local_price: {
        amount: amount.toFixed(2),
        currency: currency.toUpperCase(),
      },
      metadata,
      redirect_url: successUrl,
      cancel_url: cancelUrl,
    }),
  });

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

  const data = await response.json();
  return {
    id: data.data.id,
    hostedUrl: data.data.hosted_url,
  };
}

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 Coinbase config
    const coinbaseResult = await getCoinbaseConfig(supabaseAdmin);
    if (!coinbaseResult) {
      return new Response(
        JSON.stringify({ error: "Coinbase Commerce is not configured or enabled" }),
        {
          status: 400,
          headers: { ...corsHeaders, "Content-Type": "application/json" },
        }
      );
    }

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

    let amount: number;
    let name: string;
    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");
      }

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

    } 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;
      name = pack.name;
      description = `${pack.credits} Credits`;
      transactionType = "credit_purchase";
      referenceId = pack.id;

    } 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;
      name = `Invoice #${invoice.invoice_number}`;
      description = `Payment for Invoice #${invoice.invoice_number}`;
      transactionType = "invoice_payment";
      referenceId = invoice.id;

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

    // Create Coinbase charge
    const charge = await createCoinbaseCharge(
      config.api_key,
      amount,
      "USD",
      name,
      description,
      {
        user_id: user.id,
        transaction_type: transactionType,
        reference_id: referenceId || "",
        billing_cycle: body.billing_cycle || "",
        is_test_mode: String(isTestMode),
      },
      body.success_url,
      body.cancel_url
    );

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

    return new Response(
      JSON.stringify({
        chargeId: charge.id,
        hostedUrl: charge.hostedUrl,
      }),
      {
        status: 200,
        headers: { ...corsHeaders, "Content-Type": "application/json" },
      }
    );
  } catch (error) {
    console.error("Coinbase 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" },
      }
    );
  }
});
