import Stripe from 'stripe';

// Stripe configuration for Connect integration
export const STRIPE_CONFIG = {
  // Stripe Connect settings
  CONNECT_CLIENT_ID: import.meta.env.STRIPE_CONNECT_CLIENT_ID,
  PUBLISHABLE_KEY: import.meta.env.STRIPE_PUBLISHABLE_KEY,
  SECRET_KEY: import.meta.env.STRIPE_SECRET_KEY,
  WEBHOOK_SECRET: import.meta.env.STRIPE_WEBHOOK_SECRET,
};

// Validate required environment variables (only warn in development)
if (!STRIPE_CONFIG.SECRET_KEY && typeof window === 'undefined') {
  if (import.meta.env.DEV) {
    console.warn('Missing STRIPE_SECRET_KEY environment variable - Stripe functionality will be disabled');
  }
}

if (!STRIPE_CONFIG.PUBLISHABLE_KEY) {
  if (import.meta.env.DEV) {
    console.warn('Missing STRIPE_PUBLISHABLE_KEY environment variable - Stripe functionality will be disabled');
  }
}

// Initialize Stripe instance (server-side only)
export const stripe = typeof window === 'undefined' && STRIPE_CONFIG.SECRET_KEY
  ? new Stripe(STRIPE_CONFIG.SECRET_KEY, {
      apiVersion: '2024-06-20'
    })
  : null;

// Fee structure types
export type FeeType = 'percentage' | 'fixed' | 'percentage_plus_fixed';
export type FeeModel = 'customer_pays' | 'absorbed_in_price';

export interface FeeStructure {
  fee_type: FeeType;
  fee_percentage: number; // decimal (0.03 = 3%)
  fee_fixed: number; // cents
  fee_model: FeeModel;
  absorb_fee_in_price: boolean;
}

// Default BCT platform fee structure
export const DEFAULT_FEE_STRUCTURE: FeeStructure = {
  fee_type: 'percentage_plus_fixed',
  fee_percentage: 0.025, // 2.5% BCT platform fee
  fee_fixed: 150, // $1.50 BCT platform fee
  fee_model: 'customer_pays',
  absorb_fee_in_price: false,
};

// Stripe processing fee structure (for total cost calculation)
export const STRIPE_FEE_STRUCTURE: FeeStructure = {
  fee_type: 'percentage_plus_fixed',
  fee_percentage: 0.0299, // 2.99% Stripe fee
  fee_fixed: 30, // $0.30 Stripe fee
  fee_model: 'customer_pays',
  absorb_fee_in_price: false,
};

// Calculate platform fee for a given ticket price and fee structure
export function calculatePlatformFee(ticketPrice: number, feeStructure?: FeeStructure): number {
  const priceInCents = Math.round(ticketPrice * 100);
  const fees = feeStructure || DEFAULT_FEE_STRUCTURE;
  
  let fee = 0;
  
  switch (fees.fee_type) {
    case 'percentage':
      fee = Math.round(priceInCents * fees.fee_percentage);
      break;
    case 'fixed':
      fee = fees.fee_fixed;
      break;
    case 'percentage_plus_fixed':
      fee = Math.round(priceInCents * fees.fee_percentage) + fees.fee_fixed;
      break;
    default:
      fee = Math.round(priceInCents * DEFAULT_FEE_STRUCTURE.fee_percentage) + DEFAULT_FEE_STRUCTURE.fee_fixed;
  }
  
  return Math.max(0, fee); // Ensure fee is never negative
}

// Calculate net amount organizer receives
export function calculateOrganizerNet(ticketPrice: number, feeStructure?: FeeStructure): number {
  const priceInCents = Math.round(ticketPrice * 100);
  const fee = calculatePlatformFee(ticketPrice, feeStructure);
  return Math.max(0, priceInCents - fee); // Ensure net is never negative
}

// Format fee structure for display
export function formatFeeStructure(feeStructure: FeeStructure): string {
  switch (feeStructure.fee_type) {
    case 'percentage':
      return `${(feeStructure.fee_percentage * 100).toFixed(2)}%`;
    case 'fixed':
      return `$${(feeStructure.fee_fixed / 100).toFixed(2)}`;
    case 'percentage_plus_fixed':
      return `${(feeStructure.fee_percentage * 100).toFixed(2)}% + $${(feeStructure.fee_fixed / 100).toFixed(2)}`;
    default:
      return 'Unknown fee structure';
  }
}

// Calculate the display price shown to customers
export function calculateDisplayPrice(ticketPrice: number, feeStructure?: FeeStructure): number {
  const fees = feeStructure || DEFAULT_FEE_STRUCTURE;
  
  if (fees.fee_model === 'absorbed_in_price') {
    // If fee is absorbed, the display price includes the platform fee
    // to maintain the same organizer net, we need to add the fee to the display price
    const platformFee = calculatePlatformFee(ticketPrice, feeStructure);
    return Math.round(ticketPrice * 100) + platformFee;
  } else {
    // Customer pays fee separately, so display price is just the base ticket price
    return Math.round(ticketPrice * 100);
  }
}

// Calculate total amount customer actually pays
export function calculateCustomerTotal(ticketPrice: number, feeStructure?: FeeStructure): number {
  const fees = feeStructure || DEFAULT_FEE_STRUCTURE;
  const priceInCents = Math.round(ticketPrice * 100);
  
  if (fees.fee_model === 'absorbed_in_price') {
    // Customer pays only the display price (fee is included)
    return calculateDisplayPrice(ticketPrice, feeStructure);
  } else {
    // Customer pays base price + platform fee
    const platformFee = calculatePlatformFee(ticketPrice, feeStructure);
    return priceInCents + platformFee;
  }
}

// Calculate Stripe processing fee separately
export function calculateStripeFee(amount: number): number {
  const amountInCents = Math.round(amount * 100);
  return Math.round(amountInCents * STRIPE_FEE_STRUCTURE.fee_percentage) + STRIPE_FEE_STRUCTURE.fee_fixed;
}

// Calculate complete transaction breakdown including BCT and Stripe fees
export function calculateCompleteTransactionBreakdown(ticketPrice: number, quantity: number, feeStructure?: FeeStructure) {
  const fees = feeStructure || DEFAULT_FEE_STRUCTURE;
  const bctFeePerTicket = calculatePlatformFee(ticketPrice, feeStructure);
  const customerTotalPerTicket = calculateCustomerTotal(ticketPrice, feeStructure);
  const totalCustomerPays = customerTotalPerTicket * quantity;
  
  // Calculate Stripe fee on the total amount customer pays
  const stripeFeeTotal = calculateStripeFee(totalCustomerPays / 100);
  
  // Calculate what organizer actually receives after both BCT and Stripe fees
  const bctFeeTotal = bctFeePerTicket * quantity;
  const organizerGrossRevenue = (Math.round(ticketPrice * 100) * quantity);
  const organizerNetAfterBCT = organizerGrossRevenue - bctFeeTotal;
  const organizerNetAfterAllFees = organizerNetAfterBCT - stripeFeeTotal;
  
  return {
    // Customer perspective
    ticketPricePerTicket: Math.round(ticketPrice * 100),
    bctFeePerTicket: bctFeePerTicket,
    customerTotalPerTicket: customerTotalPerTicket,
    totalCustomerPays: totalCustomerPays,
    
    // Breakdown for quantity
    subtotalBeforeFees: organizerGrossRevenue,
    bctFeeTotal: bctFeeTotal,
    stripeFeeTotal: stripeFeeTotal,
    
    // Organizer perspective  
    organizerGrossRevenue: organizerGrossRevenue,
    organizerNetAfterBCT: organizerNetAfterBCT,
    organizerNetAfterAllFees: organizerNetAfterAllFees,
    
    // Fee model info
    feeModel: fees.fee_model,
    feeAbsorbed: fees.absorb_fee_in_price,
    
    // Formatted strings
    ticketPricePerTicketFormatted: `$${(Math.round(ticketPrice * 100) / 100).toFixed(2)}`,
    bctFeePerTicketFormatted: `$${(bctFeePerTicket / 100).toFixed(2)}`,
    customerTotalPerTicketFormatted: `$${(customerTotalPerTicket / 100).toFixed(2)}`,
    totalCustomerPaysFormatted: `$${(totalCustomerPays / 100).toFixed(2)}`,
    subtotalBeforeFeesFormatted: `$${(organizerGrossRevenue / 100).toFixed(2)}`,
    bctFeeTotalFormatted: `$${(bctFeeTotal / 100).toFixed(2)}`,
    stripeFeeTotalFormatted: `$${(stripeFeeTotal / 100).toFixed(2)}`,
    organizerGrossRevenueFormatted: `$${(organizerGrossRevenue / 100).toFixed(2)}`,
    organizerNetAfterBCTFormatted: `$${(organizerNetAfterBCT / 100).toFixed(2)}`,
    organizerNetAfterAllFeesFormatted: `$${(organizerNetAfterAllFees / 100).toFixed(2)}`,
  };
}

// Calculate fee breakdown for display (legacy function, kept for compatibility)
export function calculateFeeBreakdown(ticketPrice: number, quantity: number, feeStructure?: FeeStructure) {
  const fees = feeStructure || DEFAULT_FEE_STRUCTURE;
  const subtotal = ticketPrice * quantity;
  const subtotalCents = Math.round(subtotal * 100);
  const platformFeePerTicket = calculatePlatformFee(ticketPrice, feeStructure);
  const totalPlatformFee = platformFeePerTicket * quantity;
  const organizerNetPerTicket = calculateOrganizerNet(ticketPrice, feeStructure);
  const totalOrganizerNet = organizerNetPerTicket * quantity;
  const displayPricePerTicket = calculateDisplayPrice(ticketPrice, feeStructure);
  const totalDisplayPrice = displayPricePerTicket * quantity;
  const customerTotalPerTicket = calculateCustomerTotal(ticketPrice, feeStructure);
  const totalCustomerPays = customerTotalPerTicket * quantity;
  
  return {
    // Base amounts
    subtotal: subtotalCents,
    platformFeePerTicket,
    totalPlatformFee,
    organizerNetPerTicket,
    totalOrganizerNet,
    
    // Display and customer totals
    displayPricePerTicket,
    totalDisplayPrice,
    customerTotalPerTicket,
    totalCustomerPays,
    
    // Fee model info
    feeModel: fees.fee_model,
    feeAbsorbed: fees.absorb_fee_in_price,
    
    // Formatted strings
    subtotalFormatted: `$${(subtotalCents / 100).toFixed(2)}`,
    platformFeePerTicketFormatted: `$${(platformFeePerTicket / 100).toFixed(2)}`,
    totalPlatformFeeFormatted: `$${(totalPlatformFee / 100).toFixed(2)}`,
    organizerNetPerTicketFormatted: `$${(organizerNetPerTicket / 100).toFixed(2)}`,
    totalOrganizerNetFormatted: `$${(totalOrganizerNet / 100).toFixed(2)}`,
    displayPricePerTicketFormatted: `$${(displayPricePerTicket / 100).toFixed(2)}`,
    totalDisplayPriceFormatted: `$${(totalDisplayPrice / 100).toFixed(2)}`,
    customerTotalPerTicketFormatted: `$${(customerTotalPerTicket / 100).toFixed(2)}`,
    totalCustomerPaysFormatted: `$${(totalCustomerPays / 100).toFixed(2)}`,
  };
}

// Generate Stripe Connect onboarding URL
export function generateConnectOnboardingUrl(organizationId: string): string {
  if (!STRIPE_CONFIG.CONNECT_CLIENT_ID) {
    throw new Error('Stripe Connect not configured');
  }
  
  const params = new URLSearchParams({
    client_id: STRIPE_CONFIG.CONNECT_CLIENT_ID,
    state: organizationId,
    scope: 'read_write',
    response_type: 'code',
    'stripe_user[email]': '', // Will be filled by the form
    'stripe_user[url]': 'https://portal.blackcanyontickets.com',
    'stripe_user[country]': 'US',
    'stripe_user[business_type]': 'individual', // or 'company'
  });
  
  return `https://connect.stripe.com/oauth/authorize?${params.toString()}`;
}

// Types for Stripe Connect
export interface StripeConnectAccount {
  id: string;
  email: string;
  details_submitted: boolean;
  charges_enabled: boolean;
  payouts_enabled: boolean;
}