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

// Mock the cookie helper directly — easier than mocking next/headers + reasoning
// over the cookies() async wrapper. The actual cookie wiring is tested in
// pair-start.test.ts.
const { mockReadPairCookie } = vi.hoisted(() => ({
  mockReadPairCookie: vi.fn(),
}))

vi.mock('@/lib/auth/pair-cookie', () => ({
  readPairCookie: mockReadPairCookie,
  setPairCookie: vi.fn(),
  clearPairCookie: vi.fn(),
}))

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

import { prisma } from '@/lib/prisma'
import { hashToken } from '@/lib/auth/pairing'
import type { NextRequest } from 'next/server'
import { GET } from '@/app/api/auth/pair/stream/[pairingId]/route'

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

function makeReq(): NextRequest {
  // Minimaal NextRequest-shape voor de auth-paden — we komen niet aan signal/url toe
  // omdat de auth-checks vóór de stream-setup falen.
  return { signal: new AbortController().signal } as unknown as NextRequest
}

const params = (id: string) =>
  ({ params: Promise.resolve({ pairingId: id }) }) as { params: Promise<{ pairingId: string }> }

beforeEach(() => {
  vi.clearAllMocks()
})

describe('GET /api/auth/pair/stream/[pairingId]', () => {
  it('401 zonder s4m_pair-cookie', async () => {
    mockReadPairCookie.mockResolvedValue(null)
    const res = await GET(makeReq(), params('pair-x'))
    expect(res.status).toBe(401)
    const body = await res.json()
    expect(body.error).toMatch(/cookie/i)
    expect(mockPrisma.loginPairing.findUnique).not.toHaveBeenCalled()
  })

  it('404 als pairing onbekend is', async () => {
    mockReadPairCookie.mockResolvedValue('whatever-token')
    mockPrisma.loginPairing.findUnique.mockResolvedValue(null)
    const res = await GET(makeReq(), params('pair-onbekend'))
    expect(res.status).toBe(404)
  })

  it('410 als pairing verlopen is', async () => {
    mockReadPairCookie.mockResolvedValue('correct-token')
    mockPrisma.loginPairing.findUnique.mockResolvedValue({
      desktop_token_hash: hashToken('correct-token'),
      status: 'pending',
      expires_at: new Date(Date.now() - 1000),
    })
    const res = await GET(makeReq(), params('pair-verlopen'))
    expect(res.status).toBe(410)
  })

  it('401 als cookie hashed naar andere desktop_token_hash', async () => {
    mockReadPairCookie.mockResolvedValue('verkeerd-token')
    mockPrisma.loginPairing.findUnique.mockResolvedValue({
      desktop_token_hash: hashToken('echt-token'),
      status: 'pending',
      expires_at: new Date(Date.now() + 60_000),
    })
    const res = await GET(makeReq(), params('pair-mismatch'))
    expect(res.status).toBe(401)
  })
})
