import { describe, expect, it } from 'vitest'
import {
  isPromoQuotaExhaustedError,
  PromoQuotaExhaustedError,
  PromoValidationError,
} from './errors.js'

describe('PromoQuotaExhaustedError', () => {
  it('carries name + code + reason for the global gate', () => {
    const e = new PromoQuotaExhaustedError('global')
    expect(e.name).toBe('PromoQuotaExhaustedError')
    expect(e.code).toBe('PROMO_QUOTA_EXHAUSTED')
    expect(e.reason).toBe('global')
  })

  it('carries reason for the per-user gate', () => {
    expect(new PromoQuotaExhaustedError('per_user').reason).toBe('per_user')
  })
})

describe('isPromoQuotaExhaustedError', () => {
  it('returns true on a thrown PromoQuotaExhaustedError', () => {
    expect(isPromoQuotaExhaustedError(new PromoQuotaExhaustedError('global'))).toBe(true)
  })

  it('returns true on a STRUCTURAL match (no instanceof — cross-package dedup floor)', () => {
    const structural = { name: 'PromoQuotaExhaustedError', code: 'PROMO_QUOTA_EXHAUSTED' }
    expect(isPromoQuotaExhaustedError(structural)).toBe(true)
  })

  it('discriminates by code — returns false on a sibling PromoValidationError', () => {
    expect(isPromoQuotaExhaustedError(new PromoValidationError('field'))).toBe(false)
  })

  it('returns false on a plain Error', () => {
    expect(isPromoQuotaExhaustedError(new Error('nope'))).toBe(false)
  })

  it('returns false on null and on a non-object', () => {
    expect(isPromoQuotaExhaustedError(null)).toBe(false)
    expect(isPromoQuotaExhaustedError('PROMO_QUOTA_EXHAUSTED')).toBe(false)
  })
})
