const fs = require('fs');
const Stripe = require('stripe');

class StripeService {
  constructor(configPath = './config.json') {
    this.config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
    
    if (!this.config.stripe || !this.config.stripe.secret_key) {
      throw new Error('Stripe configuration is missing in config.json');
    }
    
    // Trim the secret key to remove any whitespace
    const secretKey = this.config.stripe.secret_key.trim();
    
    console.log('[STRIPE] Secret key length:', secretKey.length);
    console.log('[STRIPE] Secret key starts with:', secretKey.substring(0, 20) + '...');
    console.log('[STRIPE] Secret key ends with:', '...' + secretKey.substring(secretKey.length - 10));
    
    this.stripe = new Stripe(secretKey);
    this.successUrl = this.config.stripe.success_url || 'https://example.com/success';
    this.cancelUrl = this.config.stripe.cancel_url || 'https://example.com/cancel';
    
    console.log('[STRIPE] Service initialized');
  }

  /**
   * Extract price from various formats
   * Examples: "$730.10 USD", "$730.10", "730.10", "730.10 USD"
   */
  extractPrice(priceString) {
    if (!priceString) return null;
    
    // Convert to string if not already
    const str = String(priceString);
    
    // Remove currency symbols and letters, keep only digits and decimal point
    const cleanPrice = str.replace(/[^0-9.]/g, '');
    
    // Parse to float
    const price = parseFloat(cleanPrice);
    
    if (isNaN(price) || price <= 0) {
      return null;
    }
    
    return price;
  }

  /**
   * Create Stripe Checkout Session
   * @param {Object} bookingData - Booking information
   * @param {string} bookingData.totalPrice - Total price (e.g., "$730.10 USD")
   * @param {string} bookingData.cruiseTitle - Cruise title
   * @param {string} bookingData.shipName - Ship name
   * @param {string} bookingData.sailDate - Sail date
   * @param {string} bookingData.guestName - Primary guest name
   * @param {string} bookingData.guestEmail - Primary guest email
   * @returns {Promise<string>} Checkout session URL
   */
  async createCheckoutSession(bookingData) {
    try {
      console.log('[STRIPE] Creating checkout session...');
      console.log('[STRIPE] Booking data:', JSON.stringify(bookingData, null, 2));
      
      // Extract price
      const priceInDollars = this.extractPrice(bookingData.totalPrice);
      
      if (!priceInDollars) {
        throw new Error(`Invalid price format: ${bookingData.totalPrice}`);
      }
      
      // Convert to cents (Stripe uses smallest currency unit)
      const priceInCents = Math.round(priceInDollars * 100);
      
      console.log('[STRIPE] Price extracted: $' + priceInDollars + ' (' + priceInCents + ' cents)');
      
      // Build product description
      const description = [
        bookingData.cruiseTitle,
        bookingData.shipName ? `Ship: ${bookingData.shipName}` : null,
        bookingData.sailDate ? `Sail Date: ${bookingData.sailDate}` : null,
        bookingData.guestName ? `Guest: ${bookingData.guestName}` : null
      ].filter(Boolean).join(' | ');
      
      // Create Stripe Checkout Session
      const session = await this.stripe.checkout.sessions.create({
        payment_method_types: ['card'],
        line_items: [
          {
            price_data: {
              currency: 'usd',
              product_data: {
                name: bookingData.cruiseTitle || 'Cruise Booking',
                description: description,
              },
              unit_amount: priceInCents,
            },
            quantity: 1,
          },
        ],
        mode: 'payment',
        success_url: this.successUrl + '?session_id={CHECKOUT_SESSION_ID}',
        cancel_url: this.cancelUrl,
        customer_email: bookingData.guestEmail || undefined,
        metadata: {
          cruise_title: bookingData.cruiseTitle || '',
          ship_name: bookingData.shipName || '',
          sail_date: bookingData.sailDate || '',
          guest_name: bookingData.guestName || '',
          package_id: bookingData.packageId || '',
        },
      });
      
      console.log('[STRIPE] Checkout session created successfully');
      console.log('[STRIPE] Session ID:', session.id);
      console.log('[STRIPE] Checkout URL:', session.url);
      
      return session.url;
    } catch (error) {
      console.error('[STRIPE] Error creating checkout session:', error.message);
      console.error('[STRIPE] Error details:', error);
      throw error;
    }
  }

  /**
   * Retrieve checkout session details
   * @param {string} sessionId - Stripe session ID
   * @returns {Promise<Object>} Session details
   */
  async getSession(sessionId) {
    try {
      const session = await this.stripe.checkout.sessions.retrieve(sessionId);
      return session;
    } catch (error) {
      console.error('[STRIPE] Error retrieving session:', error.message);
      throw error;
    }
  }
}

module.exports = StripeService;

