import {
  isCheckoutValidationError,
  isOrderNotChargeableError,
  isPaymentFailedError,
  isFulfillmentIncompleteError,
  isOrderIdempotencyConflictError,
  OrderIdempotencyConflictError,
  type StaleSplit,
} from '@platform-modules/commerce-checkout'
import { isPaymentConfirmError, type PaymentConfirmError } from '@platform-modules/billing-react'

/** Thrown when a checkout hook is used outside <CheckoutProvider> (§2). */
export class CheckoutProviderError extends Error {
  override readonly name = 'CheckoutProviderError'
  constructor(hook: string) {
    super(`${hook} must be used within <CheckoutProvider>`)
  }
}
export function isCheckoutProviderError(e: unknown): e is CheckoutProviderError {
  return typeof e === 'object' && e !== null && (e as { name?: string }).name === 'CheckoutProviderError'
}

/**
 * Thrown by the host's CheckoutClient on a non-typed wire failure, and by the stale
 * path carrying a revived StaleSplit (§4). `code` is stable for cross-package branching.
 */
export class CheckoutWireError extends Error {
  override readonly name = 'CheckoutWireError'
  readonly code = 'CHECKOUT_WIRE' as const
  readonly stale?: StaleSplit
  constructor(message: string, opts?: { stale?: StaleSplit }) {
    super(message)
    this.stale = opts?.stale
  }
}
export function isCheckoutWireError(e: unknown): e is CheckoutWireError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { name?: string }).name === 'CheckoutWireError' &&
    (e as { code?: string }).code === 'CHECKOUT_WIRE'
  )
}

// Re-export core structural guards + the idempotency-conflict class so consumers branch
// on error kind without instanceof across deduped copies (§4 / CLAUDE.md dep classification).
export {
  isCheckoutValidationError,
  isOrderNotChargeableError,
  isPaymentFailedError,
  isFulfillmentIncompleteError,
  isOrderIdempotencyConflictError,
  OrderIdempotencyConflictError,
}
// Re-export billing-react confirm-error TYPE + guard so a consumer annotates the
// useCheckout error union from ONE import (advisor-caught — type not just guard).
export { isPaymentConfirmError, type PaymentConfirmError }