// src/server/payments/get-provider.ts
import type { MultidealEnv } from '../env.js';
import type { PaymentProvider } from './provider.js';

/**
 * Minimal env shape required by getPaymentProvider.
 * Both MultidealEnv and CronEnv satisfy this structurally.
 * Stripe fields are optional here — StripePaymentProvider will throw at
 * runtime if STRIPE_SECRET_KEY is missing when PAYMENT_PROVIDER='stripe'.
 */
export interface PaymentProviderEnv {
  DATABASE_URL: string;
  PAYMENT_PROVIDER: 'stripe' | 'mock';
  STRIPE_SECRET_KEY?: string;
  STRIPE_API_VERSION?: string;
  STRIPE_PUBLISHABLE_KEY?: string;
  STRIPE_WEBHOOK_SECRET?: string;
  STRIPE_VENDOR_KEY_ENCRYPTION_KEY?: string;
  PLATFORM_FEE_PCT?: string;
}

/**
 * Single switch point. PAYMENT_PROVIDER var selects the whole-site payment service.
 *
 * Uses dynamic import() so provider modules (and the Stripe Node SDK) are only
 * evaluated when a payment route is first invoked — never at SSR cold-start.
 */
export async function getPaymentProvider(env: PaymentProviderEnv): Promise<PaymentProvider> {
  // Cast to MultidealEnv internally — callers guarantee the full binding set at runtime.
  const fullEnv = env as unknown as MultidealEnv;
  switch (env.PAYMENT_PROVIDER as string) {
    case 'stripe': {
      const { StripePaymentProvider } = await import('./stripe-provider.js');
      return new StripePaymentProvider(fullEnv);
    }
    case 'mock': {
      const { MockPaymentProvider } = await import('./mock-provider.js');
      return new MockPaymentProvider(fullEnv);
    }
    default:
      throw new Error(`Unknown PAYMENT_PROVIDER: ${env.PAYMENT_PROVIDER}`);
  }
}
