/**
 * Stripe Pricing Module
 *
 * Handles pricing lookups and calculations for subscriptions.
 */

import Stripe from 'stripe';
import { stripe } from './client';
import { logger } from '@/lib/logger';

// =============================================================================
// Price Lookups
// =============================================================================

/**
 * Get subscription price based on tier, currency, and billing period
 */
export async function getPriceForTier(
  tierId: string,
  currency: string,
  billingPeriod: 'monthly' | 'yearly'
): Promise<Stripe.Price | null> {
  try {
    const prices = await stripe.prices.list({
      limit: 100,
      expand: ['data.product'],
    });

    const matchingPrice = prices.data.find((price) => {
      const product = price.product as Stripe.Product;
      return (
        product.metadata?.tier_id === tierId &&
        price.currency === currency.toLowerCase() &&
        price.recurring?.interval === (billingPeriod === 'monthly' ? 'month' : 'year')
      );
    });

    return matchingPrice || null;
  } catch (error) {
    logger.error('Error finding price for tier', error, { tierId, currency, billingPeriod, service: 'stripe-pricing' });
    return null;
  }
}

/**
 * Find price ID for tier, currency, and billing period
 * Used by subscription upgrade/downgrade flows
 */
export async function findPriceForTier(params: {
  tierId: string;
  currency: string;
  billingPeriod: 'monthly' | 'yearly';
}): Promise<string> {
  const { tierId, currency, billingPeriod } = params;

  const price = await getPriceForTier(tierId, currency, billingPeriod);

  if (!price) {
    throw new Error(
      `Price not found for ${tierId} with currency ${currency} and billing period ${billingPeriod}`
    );
  }

  return price.id;
}

// =============================================================================
// Price Calculations
// =============================================================================

/**
 * Calculate subscription cost with 7% yearly discount
 */
export function calculateSubscriptionCost(
  basePrice: number,
  billingPeriod: 'monthly' | 'yearly',
  currency: string,
  exchangeRates: Record<string, number>
): number {
  let price = basePrice;

  // Apply 7% discount for yearly billing
  if (billingPeriod === 'yearly') {
    price = basePrice * 0.93;
  }

  // Convert to selected currency
  const rate = exchangeRates[currency] || 1;
  return parseFloat((price * rate).toFixed(2));
}

/**
 * Get setup fee for tier
 * Based on pricing table: tier1-4 = £199, tier5 = £299
 */
export function getSetupFee(tierId: string): number {
  const setupFees: Record<string, number> = {
    tier1: 199,
    tier2: 199,
    tier3: 199,
    tier4: 199,
    tier5: 299,
  };

  return setupFees[tierId] || 199;
}

/**
 * Calculate prorated amount for subscription tier changes
 */
export function calculateProration(params: {
  currentPrice: number;
  newPrice: number;
  daysRemaining: number;
  totalDaysInPeriod: number;
}): number {
  const { currentPrice, newPrice, daysRemaining, totalDaysInPeriod } = params;

  // Calculate unused portion of current subscription
  const unusedCurrent = (currentPrice / totalDaysInPeriod) * daysRemaining;

  // Calculate cost of new subscription for remaining period
  const newCost = (newPrice / totalDaysInPeriod) * daysRemaining;

  // Return difference (positive = user pays, negative = user gets credit)
  return Math.round(newCost - unusedCurrent);
}
