import { eq } from 'drizzle-orm'
import type { Database, Transaction } from '@platform-modules/db'
import { describe, expect, it } from 'vitest'
import { debit } from './debit.js'
import { debitWithRead } from './debit-with-read.js'
import { type TestSchema, walletBuckets } from './test-fixture.js'

/**
 * Type-negative enforcement of the in-tx precondition (spec Divergence-1,
 * amended 2026-06-15): `debit`/`debitWithRead` are correct ONLY inside a
 * transaction — the throw-on-insufficient must roll the just-inserted ledger
 * row back, and `FOR UPDATE` only spans a tx. A non-transactional `Database`
 * handle autocommits the −amount entry while the balance is never decremented
 * → silent ledger corruption (data-loss floor). Enforced at the TYPE, not the
 * JSDoc (tenancy "enforce, don't document" lesson).
 *
 * This function is never executed; it exists so `tsc --noEmit` (which covers
 * `src/**` incl. `*.test.ts`) pins the contract. Each `@ts-expect-error` must
 * swallow exactly ONE error — the handle-type mismatch. The positive case
 * (no directive) compiling clean proves the input/fn args are well-formed, so
 * the directive isolates the handle and nothing else.
 */
async function _enforceTransactionPrecondition(): Promise<void> {
  const db = null as unknown as Database<TestSchema>
  const tx = null as unknown as Transaction<TestSchema>

  // --- debit ---
  // @ts-expect-error debit requires Transaction<S>, not a non-tx Database handle
  await debit(db, { key: 'k', target: { kind: 'wallet', ownerId: 'o' }, amount: 1n, reason: 'r' })
  await debit(tx, { key: 'k', target: { kind: 'wallet', ownerId: 'o' }, amount: 1n, reason: 'r' })

  // --- debitWithRead --- (S-agnostic plan so the SOLE error is the handle)
  // @ts-expect-error debitWithRead requires Transaction<S>, not a non-tx Database handle
  await debitWithRead(db, { key: 'k', reason: 'r', lock: { table: walletBuckets, where: eq(walletBuckets.ownerId, 'o') } }, () => ({ delta: 0n, apply: async () => {} }))
  await debitWithRead(tx, { key: 'k', reason: 'r', lock: { table: walletBuckets, where: eq(walletBuckets.ownerId, 'o') } }, () => ({ delta: 0n, apply: async () => {} }))
}

void _enforceTransactionPrecondition

describe('tx-enforcement (type-negative)', () => {
  it('compiles: debit/debitWithRead reject a non-tx handle, accept a Transaction', () => {
    // The contract is pinned by tsc above; this keeps vitest from failing on an
    // empty file. Reverting a param to Querier<S> makes a @ts-expect-error
    // unused (TS2578) → typecheck goes RED.
    expect(typeof _enforceTransactionPrecondition).toBe('function')
  })
})
