import { describe, expect, it } from 'vitest'
import * as fulfillment from './index.js'
import * as digital from './digital.js'
import * as voucher from './voucher.js'
import * as physical from './physical.js'
import * as testing from './testing.js'

describe('@platform-modules/commerce-fulfillment public barrels', () => {
  it('exports every named core symbol from the root barrel', () => {
    for (const name of [
      'fulfillOrder',
      'pushSchema',
      'isFulfillmentMigrateError',
      'FulfillmentMigrateError',
      'accessGrant',
      'voucher',
      'shipment',
      'carrierWebhookEvent',
      'fulfillmentSchema',
      'fulfillmentDbSchema',
      'FulfillmentValidationError',
      'VoucherAlreadyRedeemedError',
      'VoucherExpiredError',
      'VoucherWrongVendorError',
      'LabelPurchaseError',
      'UnfulfillableLineError',
      'DownloadNotFoundError',
      'isFulfillmentValidationError',
      'isVoucherAlreadyRedeemedError',
      'isVoucherExpiredError',
      'isVoucherWrongVendorError',
      'isLabelPurchaseError',
      'isUnfulfillableLineError',
      'isDownloadNotFoundError',
      'UUID_RE',
      'assertUuid',
      'assertPositiveInt',
      'normalizeEmail',
      'ownerKeyOf',
      'VOUCHER_STATES',
      'SHIPMENT_STATUSES',
      'grantDigitalAccess',
      'issueDownloadToken',
      'decideRedemption',
      'issueVoucher',
      'redeemVoucher',
      'createShipment',
      'buyShippingLabel',
      'handleCarrierWebhook',
      'trackShipment',
    ]) {
      expect(fulfillment, `missing export: ${name}`).toHaveProperty(name)
      expect((fulfillment as Record<string, unknown>)[name], `${name} is undefined`).toBeDefined()
    }

    expect(typeof fulfillment.fulfillOrder).toBe('function')
    expect(typeof fulfillment.grantDigitalAccess).toBe('function')
    expect(typeof fulfillment.issueVoucher).toBe('function')
    expect(typeof fulfillment.createShipment).toBe('function')
    expect(
      fulfillment.isUnfulfillableLineError(
        new fulfillment.UnfulfillableLineError({
          orderId: 'o-1',
          lineId: 'l-1',
          kind: 'unknown',
        }),
      ),
    ).toBe(true)
  })

  it('exports digital subpath symbols', () => {
    for (const name of ['grantDigitalAccess', 'issueDownloadToken']) {
      expect(digital, `missing export: ${name}`).toHaveProperty(name)
      expect((digital as Record<string, unknown>)[name], `${name} is undefined`).toBeDefined()
    }
  })

  it('exports voucher subpath symbols', () => {
    for (const name of ['decideRedemption', 'issueVoucher', 'redeemVoucher']) {
      expect(voucher, `missing export: ${name}`).toHaveProperty(name)
      expect((voucher as Record<string, unknown>)[name], `${name} is undefined`).toBeDefined()
    }
  })

  it('exports physical subpath symbols', () => {
    for (const name of [
      'createShipment',
      'buyShippingLabel',
      'handleCarrierWebhook',
      'trackShipment',
    ]) {
      expect(physical, `missing export: ${name}`).toHaveProperty(name)
      expect((physical as Record<string, unknown>)[name], `${name} is undefined`).toBeDefined()
    }
  })

  it('exports testing subpath symbols', () => {
    for (const name of [
      'createMemoryCarrierAdapter',
      'createMemoryStorageAdapter',
      'createMemoryFulfillmentPorts',
      'DEFAULT_MEMORY_ADDRESS',
    ]) {
      expect(testing, `missing export: ${name}`).toHaveProperty(name)
      expect((testing as Record<string, unknown>)[name], `${name} is undefined`).toBeDefined()
    }
  })
})
