/**
 * commerce-storefront blueprint · wiring seam for `@platform-modules/commerce-fulfillment`.
 *
 * Adapter-minimalism: inline fakes for StorageAdapter + CarrierAdapter over the host db.
 */
import {
  pushSchema,
  type Address,
  type BuyLabelArgs,
  type CarrierAdapter,
  type CarrierTrackResult,
  type FulfillmentDbSchema,
  type FulfillmentNotification,
  type FulfillmentPorts,
  type Label,
  type StorageAdapter,
} from '@platform-modules/commerce-fulfillment'
import type { Order, OrderLine } from '@platform-modules/commerce-orders'
import type { TransactionalDatabase } from '@platform-modules/db'

type StoredObject = { key: string; body: Uint8Array | ArrayBuffer }

function createFakeStorage(): StorageAdapter & { objects: Map<string, StoredObject> } {
  const objects = new Map<string, StoredObject>()
  return {
    objects,
    async put(key, body) {
      objects.set(key, { key, body })
    },
    async signedUrl(key, ttlSeconds) {
      return {
        url: `https://storefront.test/files/${encodeURIComponent(key)}`,
        expiresAt: new Date(Date.now() + ttlSeconds * 1000),
      }
    },
  }
}

function createFakeCarrier(): CarrierAdapter {
  return {
    kind: 'fake-carrier',
    capabilities: { webhooks: false, tracking: true },
    async buyLabel(args: BuyLabelArgs): Promise<Label> {
      return {
        id: `label-${args.idempotencyKey}`,
        trackingNumber: `TRK-${args.shipmentId.slice(0, 8)}`,
      }
    },
    async track(trackingNumber: string): Promise<CarrierTrackResult> {
      return {
        trackingNumber,
        status: 'in_transit',
        events: [{ timestamp: new Date(), description: 'stub tracking event' }],
      }
    },
    async verifyWebhook(): Promise<null> {
      return null
    },
  }
}

export type FakeFulfillmentPorts = FulfillmentPorts & {
  storage: StorageAdapter & { objects: Map<string, StoredObject> }
  carrier: CarrierAdapter
  notifications: FulfillmentNotification[]
}

export async function createFakeFulfillmentPorts(
  db: TransactionalDatabase<FulfillmentDbSchema>,
): Promise<FakeFulfillmentPorts> {
  await pushSchema(db)
  const storage = createFakeStorage()
  const carrier = createFakeCarrier()
  const notifications: FulfillmentNotification[] = []

  return {
    db,
    storage,
    carrier,
    notifications,
    carriers: () => carrier,
    resolveBlobKey: async (line: OrderLine) => `blob:${line.id}`,
    resolveShippingAddress: async (_order: Order): Promise<Address> => ({
      name: 'Test Buyer',
      line1: '1 Test St',
      city: 'Tel Aviv',
      country: 'IL',
      postalCode: '6100000',
    }),
    notify: async (notification) => {
      notifications.push(notification)
    },
  }
}
