import type { NeonHttpQueryResult } from 'drizzle-orm/neon-http'
import type { RowList } from 'postgres'
import type { Querier, TransactionalDatabase } from './index.js'
import { createNeonHttpClient } from './postgres/neon-http.js'
import { createNeonServerlessClient } from './postgres/neon-serverless.js'
import { createPgliteClient } from './postgres/pglite.js'
import { createD1Client, type D1BatchItem } from './sqlite/d1.js'
import { createPostgresJsClient } from './postgres/postgres-js.js'

type S = Record<string, unknown>
type RowShape = { x: number }

// (a) execute-flows-typed — concrete HKT preserves execute<T> row typing
{
  const neonHttp = createNeonHttpClient({ connectionString: '' })
  type NeonHttpExecute = Awaited<ReturnType<typeof neonHttp.execute<RowShape>>>
  const neonHttpResult: NeonHttpQueryResult<RowShape> = null as unknown as NeonHttpExecute
  void neonHttpResult
}

{
  const neonServerless = createNeonServerlessClient({ connectionString: '' })
  type NeonExecute = Awaited<ReturnType<typeof neonServerless.execute<RowShape>>>
  // Fail-closed direct assignment: `unknown` (abstract-HKT regression) is NOT
  // assignable to `{ rows: RowShape[] }`, and a dropped <RowShape> generic
  // (rows typed loosely) also fails the row-type pin. No `?: never` escape.
  const neonResult: { rows: RowShape[] } = null as unknown as NeonExecute
  void neonResult
}

{
  const postgresJs = createPostgresJsClient({ connectionString: '' })
  type PostgresExecute = Awaited<ReturnType<typeof postgresJs.execute<RowShape>>>
  const postgresResult: RowList<RowShape[]> = null as unknown as PostgresExecute
  void postgresResult
}

{
  const pglite = createPgliteClient()
  type PgliteExecute = Awaited<ReturnType<typeof pglite.execute<RowShape>>>
  // Pin the <RowShape> generic, not just the `Results` shape: `unknown` fails,
  // and a dropped generic (rows typed loosely) fails the `rows: RowShape[]` pin.
  const pgliteResult: { rows: RowShape[] } = null as unknown as PgliteExecute
  void pgliteResult
}

// (b) concrete-assignable-to-agnostic — swap-survival on consumer params
const q: Querier<S> = createNeonHttpClient({ connectionString: '' })
const neonServerlessTx: TransactionalDatabase<S> = createNeonServerlessClient({ connectionString: '' })
const postgresJsTx: TransactionalDatabase<S> = createPostgresJsClient({ connectionString: '' })
const pgliteTx: TransactionalDatabase<S> = createPgliteClient()
void q
void neonServerlessTx
void postgresJsTx
void pgliteTx

// (c) D1 capability truthfulness — public D1 has query + atomic batch, never callback transactions.
declare const d1Binding: unknown
const d1 = createD1Client(d1Binding)
type D1HasNoTransaction = 'transaction' extends keyof typeof d1 ? false : true
const d1HasNoTransaction: D1HasNoTransaction = true
const d1Items: readonly [D1BatchItem<{ id: string }>, D1BatchItem<{ count: number }>] = null as unknown as readonly [D1BatchItem<{ id: string }>, D1BatchItem<{ count: number }>]
type D1BatchRows = Awaited<ReturnType<typeof d1.batch<typeof d1Items>>>
const d1Rows: readonly [{ id: string }[], { count: number }[]] = null as unknown as D1BatchRows
void d1HasNoTransaction
void d1Rows
// Asserted as a conditional type rather than a compiler suppression directive: a suppression passes
// whenever its line errors for ANY reason, so it would keep passing if the assignment broke for an
// unrelated one. This form fails only for the property under test — D1 is not a transaction consumer.
type D1NotTransactional = typeof d1 extends TransactionalDatabase<S> ? false : true
const d1NotTransactional: D1NotTransactional = true
void d1NotTransactional
