import Stripe from 'stripe';
import { supabase } from './supabase';

// Main platform Stripe instance
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: '2023-10-16',
});

// Interface for payment processing options
interface PaymentOptions {
  eventId: string;
  userId: string;
  amount: number;
  currency: string;
  customerId?: string;
  metadata?: Record<string, string>;
}

// Interface for platform fee calculation
interface FeeCalculation {
  platformFee: number;
  feeType: 'percentage' | 'fixed' | 'none';
  feePercentage?: number;
  feeFixed?: number;
  useCustomStripe: boolean;
  stripeAccountId?: string;
}

/**
 * Determines the appropriate Stripe account and fee structure for an event
 */
export async function getPaymentConfiguration(eventId: string, userId: string): Promise<FeeCalculation> {
  try {
    // Check if user has custom pricing profile
    const { data: profile } = await supabase
      .from('custom_pricing_profiles')
      .select('*')
      .eq('user_id', userId)
      .single();

    if (!profile) {
      // Use default platform settings
      return {
        platformFee: 0,
        feeType: 'percentage',
        feePercentage: 2.9, // Default platform fee
        useCustomStripe: false
      };
    }

    // Check for event-specific overrides
    const { data: override } = await supabase
      .from('event_pricing_overrides')
      .select('*')
      .eq('event_id', eventId)
      .eq('custom_pricing_profile_id', profile.id)
      .single();

    if (override) {
      // Use event-specific override
      const platformFee = calculatePlatformFee(100, override.platform_fee_type, override.platform_fee_percentage, override.platform_fee_fixed);
      
      return {
        platformFee,
        feeType: override.platform_fee_type || 'percentage',
        feePercentage: override.platform_fee_percentage,
        feeFixed: override.platform_fee_fixed,
        useCustomStripe: override.use_custom_stripe_account && !!profile.stripe_account_id,
        stripeAccountId: override.use_custom_stripe_account ? profile.stripe_account_id : undefined
      };
    }

    // Use profile defaults
    const platformFee = calculatePlatformFee(100, profile.custom_platform_fee_type, profile.custom_platform_fee_percentage, profile.custom_platform_fee_fixed);
    
    return {
      platformFee,
      feeType: profile.custom_platform_fee_type || 'percentage',
      feePercentage: profile.custom_platform_fee_percentage,
      feeFixed: profile.custom_platform_fee_fixed,
      useCustomStripe: profile.use_personal_stripe && !!profile.stripe_account_id,
      stripeAccountId: profile.use_personal_stripe ? profile.stripe_account_id : undefined
    };

  } catch (error) {

    // Return default configuration on error
    return {
      platformFee: 0,
      feeType: 'percentage',
      feePercentage: 2.9,
      useCustomStripe: false
    };
  }
}

/**
 * Calculates platform fee based on type and configuration
 */
function calculatePlatformFee(
  amount: number,
  feeType?: string,
  feePercentage?: number,
  feeFixed?: number
): number {
  switch (feeType) {
    case 'percentage':
      return Math.round((amount * (feePercentage || 0)) / 100);
    case 'fixed':
      return feeFixed || 0;
    case 'none':
      return 0;
    default:
      return Math.round((amount * 2.9) / 100); // Default 2.9%
  }
}

/**
 * Creates a payment intent with the appropriate Stripe account
 */
export async function createPaymentIntent(options: PaymentOptions): Promise<Stripe.PaymentIntent> {
  const config = await getPaymentConfiguration(options.eventId, options.userId);
  
  const platformFee = calculatePlatformFee(options.amount, config.feeType, config.feePercentage, config.feeFixed);
  
  if (config.useCustomStripe && config.stripeAccountId) {
    // Use custom Stripe account - payment goes directly to organizer
    const customStripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
      apiVersion: '2023-10-16',
      stripeAccount: config.stripeAccountId
    });

    return await customStripe.paymentIntents.create({
      amount: options.amount,
      currency: options.currency,
      customer: options.customerId,
      metadata: {
        event_id: options.eventId,
        user_id: options.userId,
        platform_fee: platformFee.toString(),
        custom_stripe_account: 'true',
        ...options.metadata
      }
    });
  } else {
    // Use platform Stripe account with application fee
    const applicationFee = platformFee > 0 ? platformFee : undefined;
    
    return await stripe.paymentIntents.create({
      amount: options.amount,
      currency: options.currency,
      customer: options.customerId,
      application_fee_amount: applicationFee,
      metadata: {
        event_id: options.eventId,
        user_id: options.userId,
        platform_fee: platformFee.toString(),
        custom_stripe_account: 'false',
        ...options.metadata
      }
    });
  }
}

/**
 * Creates a checkout session with the appropriate Stripe account
 */
export async function createCheckoutSession(options: {
  eventId: string;
  userId: string;
  lineItems: Stripe.Checkout.SessionCreateParams.LineItem[];
  successUrl: string;
  cancelUrl: string;
  metadata?: Record<string, string>;
}): Promise<Stripe.Checkout.Session> {
  const config = await getPaymentConfiguration(options.eventId, options.userId);
  
  const sessionParams: Stripe.Checkout.SessionCreateParams = {
    payment_method_types: ['card'],
    line_items: options.lineItems,
    mode: 'payment',
    success_url: options.successUrl,
    cancel_url: options.cancelUrl,
    metadata: {
      event_id: options.eventId,
      user_id: options.userId,
      custom_stripe_account: config.useCustomStripe ? 'true' : 'false',
      ...options.metadata
    }
  };

  if (config.useCustomStripe && config.stripeAccountId) {
    // Use custom Stripe account
    const customStripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
      apiVersion: '2023-10-16',
      stripeAccount: config.stripeAccountId
    });

    return await customStripe.checkout.sessions.create(sessionParams);
  } else {
    // Use platform Stripe account
    const totalAmount = options.lineItems.reduce((sum, item) => {
      return sum + (item.price_data?.unit_amount || 0) * (item.quantity || 1);
    }, 0);

    const platformFee = calculatePlatformFee(totalAmount, config.feeType, config.feePercentage, config.feeFixed);
    
    if (platformFee > 0) {
      sessionParams.payment_intent_data = {
        application_fee_amount: platformFee
      };
    }

    return await stripe.checkout.sessions.create(sessionParams);
  }
}

/**
 * Validates that a custom Stripe account is properly set up
 */
export async function validateStripeAccount(stripeAccountId: string): Promise<boolean> {
  try {
    const account = await stripe.accounts.retrieve(stripeAccountId);
    return account.charges_enabled && account.payouts_enabled;
  } catch (error) {

    return false;
  }
}

/**
 * Gets the display name for a Stripe account
 */
export async function getStripeAccountName(stripeAccountId: string): Promise<string> {
  try {
    const account = await stripe.accounts.retrieve(stripeAccountId);
    return account.display_name || account.email || 'Custom Account';
  } catch (error) {

    return 'Custom Account';
  }
}