import { describe, expect, it, vi, beforeEach } from 'vitest'
import { Hono } from 'hono'
import type { AppEnv } from '../src/types'

const mockVerifyAdminSession = vi.fn()
const mockCreateDb = vi.fn(() => ({}))
const mockFindAdminWithPermissions = vi.fn()

vi.mock('@zync/auth', () => ({
  verifyAdminSession: (...args: unknown[]) => mockVerifyAdminSession(...args),
}))

vi.mock('@zync/db/queries', () => ({
  createDb: (...args: unknown[]) => mockCreateDb(...args),
  findAdminWithPermissions: (...args: unknown[]) => mockFindAdminWithPermissions(...args),
}))

import { adminAuthMiddleware } from '../src/middleware/admin-auth'
import { ADMIN_COOKIE } from '../src/lib/cookies'

function appWithMiddleware() {
  const app = new Hono<AppEnv>()
  app.use('*', adminAuthMiddleware)
  app.get('/', (c) => c.json(c.get('session')))
  return app
}

describe('adminAuthMiddleware', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockVerifyAdminSession.mockResolvedValue({
      sub: 'admin-1',
      type: 'admin',
      totp_verified: true,
      exp: 100,
      iat: 50,
    })
  })

  it('omits role when the admin record has no assigned role', async () => {
    mockFindAdminWithPermissions.mockResolvedValue({
      id: 'admin-1',
      role: null,
      permissions: ['admin.billing:read'],
    })

    const res = await appWithMiddleware().request(
      '/',
      { headers: { Cookie: `${ADMIN_COOKIE}=signed-token` } },
      { Bindings: { JWT_SECRET: 'secret' } as AppEnv['Bindings'] },
    )

    expect(res.status).toBe(200)
    await expect(res.json()).resolves.toEqual({
      sub: 'admin-1',
      type: 'admin',
      totp_verified: true,
      exp: 100,
      iat: 50,
      permissions: ['admin.billing:read'],
    })
  })
})
