interface StripeInstance {
  redirectToCheckout: (opts: { sessionId: string }) => Promise<{ error?: { message: string } }>
}

declare global {
  interface Window {
    Stripe?: (key: string) => StripeInstance
  }
}

const SCRIPT_ID = 'stripe-js'

/**
 * Carga Stripe.js (una vez) y redirige al Checkout con el session_id dado.
 * Rechaza si Stripe no carga o devuelve error.
 */
export function redirectToStripeCheckout(publicKey: string, sessionId: string): Promise<void> {
  return new Promise((resolve, reject) => {
    function go() {
      if (!window.Stripe) return reject(new Error('Stripe no está disponible'))
      const stripe = window.Stripe(publicKey)
      stripe
        .redirectToCheckout({ sessionId })
        .then((r) => (r.error ? reject(new Error(r.error.message)) : resolve()))
        .catch(reject)
    }

    if (window.Stripe) return go()

    if (!document.getElementById(SCRIPT_ID)) {
      const s = document.createElement('script')
      s.id = SCRIPT_ID
      s.src = 'https://js.stripe.com/v3/'
      document.head.appendChild(s)
    }
    let waited = 0
    const iv = window.setInterval(() => {
      if (window.Stripe) {
        window.clearInterval(iv)
        go()
      } else if ((waited += 150) > 8000) {
        window.clearInterval(iv)
        reject(new Error('No se pudo cargar Stripe.'))
      }
    }, 150)
  })
}
