import { describe, it, expect, vi, beforeEach } from 'vitest'

vi.mock('@/lib/prisma', () => ({
  prisma: {
    claudeQuestion: { updateMany: vi.fn() },
    loginPairing: { updateMany: vi.fn() },
  },
}))

import { prisma } from '@/lib/prisma'
import { POST } from '@/app/api/cron/expire-questions/route'

const mockPrisma = prisma as unknown as {
  claudeQuestion: { updateMany: ReturnType<typeof vi.fn> }
  loginPairing: { updateMany: ReturnType<typeof vi.fn> }
}

const SECRET = 'test-cron-secret-abc123'

function makeReq(headers: Record<string, string> = {}): Request {
  return new Request('http://localhost:3000/api/cron/expire-questions', {
    method: 'POST',
    headers,
  })
}

beforeEach(() => {
  vi.clearAllMocks()
  process.env.CRON_SECRET = SECRET
  mockPrisma.claudeQuestion.updateMany.mockResolvedValue({ count: 0 })
  mockPrisma.loginPairing.updateMany.mockResolvedValue({ count: 0 })
})

describe('POST /api/cron/expire-questions', () => {
  it('401 zonder Authorization-header', async () => {
    const res = await POST(makeReq())
    expect(res.status).toBe(401)
    expect(mockPrisma.claudeQuestion.updateMany).not.toHaveBeenCalled()
    expect(mockPrisma.loginPairing.updateMany).not.toHaveBeenCalled()
  })

  it('401 met verkeerde secret', async () => {
    const res = await POST(makeReq({ authorization: 'Bearer wrong-secret' }))
    expect(res.status).toBe(401)
  })

  it('401 als CRON_SECRET niet is gezet (faal-veilig)', async () => {
    delete process.env.CRON_SECRET
    const res = await POST(makeReq({ authorization: 'Bearer ' + SECRET }))
    expect(res.status).toBe(401)
  })

  it('200 met juiste secret + beide updateMany aangeroepen', async () => {
    mockPrisma.claudeQuestion.updateMany.mockResolvedValue({ count: 3 })
    mockPrisma.loginPairing.updateMany.mockResolvedValue({ count: 1 })

    const res = await POST(makeReq({ authorization: 'Bearer ' + SECRET }))
    expect(res.status).toBe(200)
    const body = await res.json()
    expect(body).toMatchObject({
      expired_questions: 3,
      expired_pairings: 1,
    })
    expect(body.ran_at).toMatch(/^\d{4}-\d{2}-\d{2}T/)

    // Question-update: status='open' AND expires_at < now → 'expired'
    const qArg = mockPrisma.claudeQuestion.updateMany.mock.calls[0][0]
    expect(qArg.where).toMatchObject({ status: 'open' })
    expect(qArg.where.expires_at).toMatchObject({ lt: expect.any(Date) })
    expect(qArg.data).toEqual({ status: 'expired' })

    // Pairing-update: status='pending' AND expires_at < now → 'cancelled'
    const pArg = mockPrisma.loginPairing.updateMany.mock.calls[0][0]
    expect(pArg.where).toMatchObject({ status: 'pending' })
    expect(pArg.data).toEqual({ status: 'cancelled' })
  })
})
