export class InsufficientBalanceError extends Error {
  readonly code = 'INSUFFICIENT_BALANCE' as const
  readonly _affiliateError = 'InsufficientBalanceError' as const

  constructor(
    message: string,
    readonly detail?: {
      requiredMinor: bigint
      availableMinor: bigint
      bucket: 'matured' | 'withdrawable'
    },
  ) {
    super(message)
    this.name = 'InsufficientBalanceError'
  }
}

export function isInsufficientBalanceError(e: unknown): e is InsufficientBalanceError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { _affiliateError?: unknown })._affiliateError === 'InsufficientBalanceError'
  )
}

export class InvalidPayoutAmountError extends Error {
  readonly code = 'INVALID_PAYOUT_AMOUNT' as const
  readonly _affiliateError = 'InvalidPayoutAmountError' as const

  constructor(readonly amountMinor: bigint) {
    super(`payout amount must be positive; got: ${amountMinor}`)
    this.name = 'InvalidPayoutAmountError'
  }
}

export function isInvalidPayoutAmountError(e: unknown): e is InvalidPayoutAmountError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { _affiliateError?: unknown })._affiliateError === 'InvalidPayoutAmountError'
  )
}

export class FraudHoldError extends Error {
  readonly code = 'FRAUD_HOLD' as const
  readonly _affiliateError = 'FraudHoldError' as const

  constructor(
    message: string,
    readonly detail?: { point: string; reason: string },
  ) {
    super(message)
    this.name = 'FraudHoldError'
  }
}

export function isFraudHoldError(e: unknown): e is FraudHoldError {
  return (
    typeof e === 'object' &&
    e !== null &&
    (e as { _affiliateError?: unknown })._affiliateError === 'FraudHoldError'
  )
}
