/**
 * commerce-storefront blueprint · wiring seam for `@platform-modules/commerce-checkout` + billing.
 *
 * Adapter-minimalism: assemble CheckoutDeps (billing provider + ledger seam + intent store +
 * fulfillment ports) and expose startCheckout/settleCheckout bound to that bag. A real host injects
 * its Stripe/Sumit provider and durable intent/ledger stores.
 */
import { type LedgerSeam, type PaymentProvider } from '@platform-modules/billing'
import {
  settleCheckout as settleCheckoutFn,
  startCheckout as startCheckoutFn,
  type CheckoutDeps,
  type CheckoutInput,
} from '@platform-modules/commerce-checkout'
import type { FulfillmentPorts } from '@platform-modules/commerce-fulfillment'
import type { OrdersSchema } from '@platform-modules/commerce-orders'
import type { TransactionalDatabase } from '@platform-modules/db'
import type { AppendEntryInput } from '@platform-modules/ledger'
import { createCommerceIntentStore } from '../../commerce/wiring/intent.js'

export type LedgerEntryRecord = {
  key: string
  delta: bigint
  reason: string
  ref?: AppendEntryInput['ref']
}

export type TrackingLedger = LedgerSeam & {
  entries: LedgerEntryRecord[]
}

export type StorefrontCheckout = {
  deps: CheckoutDeps
  ledger: TrackingLedger
  startCheckout: (input: CheckoutInput) => ReturnType<typeof startCheckoutFn>
  settleCheckout: (orderId: string, providerRef: string) => ReturnType<typeof settleCheckoutFn>
}

function createTrackingLedger(): TrackingLedger {
  const insertedKeys = new Set<string>()
  const entries: LedgerEntryRecord[] = []
  return {
    entries,
    async appendEntry(_db, input) {
      if (insertedKeys.has(input.key)) {
        return { inserted: false, id: null }
      }
      insertedKeys.add(input.key)
      entries.push({
        key: input.key,
        delta: input.delta,
        reason: input.reason,
        ref: input.ref,
      })
      return { inserted: true, id: `le-${input.key}` }
    },
  }
}

export function createStorefrontCheckout(
  db: TransactionalDatabase<OrdersSchema>,
  paymentProvider: PaymentProvider,
  fulfillmentPorts: FulfillmentPorts,
): StorefrontCheckout {
  const ledger = createTrackingLedger()
  const intentStore = createCommerceIntentStore()
  const deps: CheckoutDeps = {
    db,
    provider: paymentProvider,
    ledger,
    intentStore,
    fulfillment: fulfillmentPorts,
  }
  return {
    deps,
    ledger,
    startCheckout: (input) => startCheckoutFn(deps, input),
    settleCheckout: (orderId, providerRef) => settleCheckoutFn(deps, orderId, providerRef),
  }
}
