type StripeIntentType = 'payment_intent' | 'setup_intent' | string;

type RecoveryResult = { action: 'complete' } | { action: 'pending' } | { action: 'failed'; message: string };

const NETWORK_ERROR_PATTERN = /timeout|timed out|network|failed to fetch|connection/i;

function getErrorMessage(error: unknown): string {
  return error instanceof Error ? error.message : String(error);
}

export async function recoverStripeConfirmResult(
  stripe: any,
  intentType: StripeIntentType,
  clientSecret: string,
  confirmError: unknown
): Promise<RecoveryResult> {
  const message = getErrorMessage(confirmError);
  if (!NETWORK_ERROR_PATTERN.test(message)) {
    return { action: 'failed', message };
  }

  const retrieveMethod = intentType === 'payment_intent' ? 'retrievePaymentIntent' : 'retrieveSetupIntent';
  try {
    const result = await stripe[retrieveMethod](clientSecret);
    const intent = result.paymentIntent || result.setupIntent;
    if (intent && ['succeeded', 'processing'].includes(intent.status)) {
      return { action: 'complete' };
    }
    return { action: 'failed', message };
  } catch {
    // The confirm and the follow-up lookup both have an ambiguous network result.
    // Continue backend verification rather than inviting a duplicate payment.
    return { action: 'pending' };
  }
}
