/**
 * Stripe payment gateway integration
 */

import Stripe from 'stripe';
import { getEnv } from '@the-order/shared';

export interface PaymentIntent {
  id: string;
  amount: number;
  currency: string;
  status: string;
  client_secret?: string;
}

export interface PaymentResult {
  success: boolean;
  transactionId: string;
  status: string;
  gatewayResponse: unknown;
}

export class StripePaymentGateway {
  private stripe: Stripe;

  constructor() {
    const env = getEnv();
    const apiKey = env.PAYMENT_GATEWAY_API_KEY;
    
    if (!apiKey) {
      throw new Error('PAYMENT_GATEWAY_API_KEY is required');
    }

    this.stripe = new Stripe(apiKey, {
      apiVersion: '2023-10-16',
    });
  }

  async createPaymentIntent(
    amount: number,
    currency: string,
    paymentMethod: string,
    metadata?: Record<string, string>
  ): Promise<PaymentIntent> {
    const paymentIntent = await this.stripe.paymentIntents.create({
      amount: Math.round(amount * 100), // Convert to cents
      currency: currency.toLowerCase(),
      payment_method_types: [paymentMethod === 'credit_card' ? 'card' : paymentMethod],
      metadata,
    });

    return {
      id: paymentIntent.id,
      amount: paymentIntent.amount / 100,
      currency: paymentIntent.currency.toUpperCase(),
      status: paymentIntent.status,
      client_secret: paymentIntent.client_secret || undefined,
    };
  }

  async confirmPayment(paymentIntentId: string): Promise<PaymentResult> {
    const paymentIntent = await this.stripe.paymentIntents.retrieve(paymentIntentId);

    return {
      success: paymentIntent.status === 'succeeded',
      transactionId: paymentIntent.id,
      status: paymentIntent.status,
      gatewayResponse: paymentIntent,
    };
  }

  async processPayment(
    amount: number,
    currency: string,
    paymentMethod: string,
    metadata?: Record<string, string>
  ): Promise<PaymentResult> {
    const paymentIntent = await this.createPaymentIntent(amount, currency, paymentMethod, metadata);
    
    // For immediate payment, confirm the intent
    if (paymentIntent.status === 'requires_payment_method') {
      const confirmed = await this.stripe.paymentIntents.confirm(paymentIntent.id);
      return {
        success: confirmed.status === 'succeeded',
        transactionId: confirmed.id,
        status: confirmed.status,
        gatewayResponse: confirmed,
      };
    }

    return {
      success: paymentIntent.status === 'succeeded',
      transactionId: paymentIntent.id,
      status: paymentIntent.status,
      gatewayResponse: paymentIntent,
    };
  }

  async verifyWebhook(payload: string | Buffer, signature: string): Promise<Stripe.Event> {
    const env = getEnv();
    const webhookSecret = env.PAYMENT_GATEWAY_WEBHOOK_SECRET;

    if (!webhookSecret) {
      throw new Error('PAYMENT_GATEWAY_WEBHOOK_SECRET is required for webhook verification');
    }

    return this.stripe.webhooks.constructEvent(payload, signature, webhookSecret);
  }
}

