import { sql } from 'drizzle-orm'
import { createPgliteClient } from '@platform-modules/db/pglite'
import { describe, expect, it } from 'vitest'

import { CredentialNotFoundError, resolveCredential } from './credential.js'
import { accounts, apiKeys, credentials, plugins, pressZoneInitSql, pressZoneSchema, sites } from '../schema.js'

async function createDb() {
  const db = createPgliteClient({ schema: pressZoneSchema })

  for (const statement of pressZoneInitSql.split(';').map((part) => part.trim()).filter(Boolean)) {
    await db.execute(sql.raw(statement))
  }

  return db
}

describe('resolveCredential', () => {
  it('resolves an api-key-backed credential link by account, site, and provider', async () => {
    const db = await createDb()
    const accountId = '11111111-1111-1111-1111-111111111111'
    const siteId = '22222222-2222-2222-2222-222222222222'
    const credentialId = '33333333-3333-3333-3333-333333333333'
    const apiKeyId = 'ak_press_zone'

    await db.insert(accounts).values({
      id: accountId,
      slug: 'acct-press-zone',
    })
    await db.insert(plugins).values({
      key: 'translate',
      name: 'Translate',
    })
    await db.insert(sites).values({
      id: siteId,
      accountId,
      pluginKey: 'translate',
      displayUrl: 'https://example.test',
    })
    await db.insert(apiKeys).values({
      id: apiKeyId,
      prefix: 'pk_live_press_zone',
      secretHash: 'hashed-secret',
      owner: 'site',
      scopes: 'translate.write',
      createdAt: new Date('2026-07-03T00:00:00.000Z'),
    })
    await db.insert(credentials).values({
      id: credentialId,
      accountId,
      siteId,
      provider: 'wordpress',
      apiKeyId,
    })

    const credential = await resolveCredential(db, {
      account: accountId,
      site: siteId,
      provider: 'wordpress',
    })

    expect(credential.id).toBe(credentialId)
    expect(credential.accountId).toBe(accountId)
    expect(credential.siteId).toBe(siteId)
    expect(credential.provider).toBe('wordpress')
    expect(credential.apiKeyId).toBe(apiKeyId)
    expect(credential.oauthTokenId).toBeNull()
  })

  it('throws a typed not-found error when the credential link is missing', async () => {
    const db = await createDb()
    const params = {
      account: '44444444-4444-4444-4444-444444444444',
      site: '55555555-5555-5555-5555-555555555555',
      provider: 'wordpress',
    }

    const pending = resolveCredential(db, params)

    await expect(pending).rejects.toBeInstanceOf(CredentialNotFoundError)
    await expect(pending).rejects.toMatchObject({
      code: 'CREDENTIAL_NOT_FOUND',
      httpStatus: 404,
      context: params,
    })
  })
})
