import { PGlite } from '@electric-sql/pglite'
import { eq } from 'drizzle-orm'
import { drizzle } from 'drizzle-orm/pglite'
import type { TransactionalDatabase } from '@platform-modules/db'
import { hashToken } from '@platform-modules/util/tokens'
import { oauthClients, oauthCodes, oauthProviderCreationSql, oauthProviderSchema, oauthTokens } from './schema.js'
import { registerClient } from './index.js'

export type TestDb = TransactionalDatabase<typeof oauthProviderSchema>

export async function createTestDb(): Promise<TestDb> {
  const client = new PGlite()
  const db = drizzle(client, { schema: oauthProviderSchema }) as unknown as TestDb

  await client.exec(oauthProviderCreationSql())

  return db
}

export async function registerTestClient(db: TestDb) {
  return registerClient(db, {
    id: 'plugin-backend-core',
    name: 'Plugin Backend Core',
    redirectUris: ['https://plugin.example.com/oauth/callback'],
    scopes: ['plugin.read', 'plugin.write'],
    confidential: false,
  })
}

export async function getOAuthCodeRecord(db: TestDb, code: string) {
  const codeHash = await hashToken(code)
  const [row] = await db.select().from(oauthCodes).where(eq(oauthCodes.codeHash, codeHash)).limit(1)
  return row
}

export async function getOAuthTokenRecord(db: TestDb, accessToken: string) {
  const secret = accessToken.split('.')[1]
  if (!secret) return null
  const accessTokenHash = await hashToken(secret)
  const [row] = await db
    .select()
    .from(oauthTokens)
    .where(eq(oauthTokens.accessTokenHash, accessTokenHash))
    .limit(1)
  return row
}

export async function getOAuthClientRecord(db: TestDb, id: string) {
  const [row] = await db.select().from(oauthClients).where(eq(oauthClients.id, id)).limit(1)
  return row
}
