const Stripe = require("stripe");

let stripeClient = null;

/**
 * Get or create a Stripe client.
 * Reuses client across Lambda invocations for better performance.
 */
function getStripeClient() {
  if (!stripeClient) {
    const secretKey = process.env.STRIPE_SECRET_KEY;
    if (!secretKey) {
      throw new Error("STRIPE_SECRET_KEY environment variable is required");
    }
    stripeClient = new Stripe(secretKey);
  }
  return stripeClient;
}

/**
 * Create a Stripe transfer to a connected account.
 * @param {Object} params - Transfer parameters
 * @param {number} params.amount - Amount in dollars (will be converted to cents)
 * @param {string} params.destination - Stripe connected account ID
 * @param {string} [params.currency='usd'] - Currency code
 * @param {Object} [params.metadata={}] - Additional metadata for the transfer
 * @returns {Promise<Object>} Stripe transfer object
 */
async function createTransfer({ amount, destination, currency = "usd", metadata = {} }) {
  const stripe = getStripeClient();

  // Generate idempotency key from rental ID to prevent duplicate transfers
  const idempotencyKey = metadata?.rentalId
    ? `transfer_rental_${metadata.rentalId}`
    : undefined;

  const transfer = await stripe.transfers.create(
    {
      amount: Math.round(amount * 100), // Convert to cents
      currency,
      destination,
      metadata,
    },
    idempotencyKey ? { idempotencyKey } : undefined
  );

  return transfer;
}

/**
 * Check if an error indicates the connected account is disconnected.
 * Used as fallback detection when webhook was missed.
 * @param {Error} error - Stripe error object
 * @returns {boolean} True if error indicates disconnected account
 */
function isAccountDisconnectedError(error) {
  // Stripe returns these error codes when account is disconnected or invalid
  const disconnectedCodes = ["account_invalid", "platform_api_key_expired"];

  // Error messages that indicate disconnection
  const disconnectedMessages = [
    "cannot transfer",
    "not connected",
    "no longer connected",
    "account has been deauthorized",
  ];

  if (disconnectedCodes.includes(error.code)) {
    return true;
  }

  const message = (error.message || "").toLowerCase();
  return disconnectedMessages.some((msg) => message.includes(msg));
}

module.exports = {
  getStripeClient,
  createTransfer,
  isAccountDisconnectedError,
};
