import { createToken, validateToken } from '../token'
import { prisma } from '../prisma'

jest.mock('../prisma', () => ({
  prisma: {
    downloadToken: {
      create: jest.fn(),
      findUnique: jest.fn(),
    },
  },
}))

const mockCreate = (prisma.downloadToken.create as jest.Mock)
const mockFindUnique = (prisma.downloadToken.findUnique as jest.Mock)

describe('createToken', () => {
  it('inserts a DownloadToken and returns the token string', async () => {
    mockCreate.mockResolvedValue({ token: 'generated-token' })

    const result = await createToken('dl-id-1')

    expect(mockCreate).toHaveBeenCalledWith(
      expect.objectContaining({
        data: expect.objectContaining({ downloadId: 'dl-id-1' }),
      })
    )
    expect(result).toBe('generated-token')
  })
})

describe('validateToken', () => {
  it('returns null when token not found', async () => {
    mockFindUnique.mockResolvedValue(null)
    expect(await validateToken('bad')).toBeNull()
  })

  it('returns null when token is expired', async () => {
    mockFindUnique.mockResolvedValue({
      expiresAt: new Date(Date.now() - 1000),
      download: { id: 'dl-1', filePath: '/storage/abc.mp4' },
    })
    expect(await validateToken('expired-tok')).toBeNull()
  })

  it('returns null when filePath is null', async () => {
    mockFindUnique.mockResolvedValue({
      expiresAt: new Date(Date.now() + 3_600_000),
      download: { id: 'dl-1', filePath: null },
    })
    expect(await validateToken('tok')).toBeNull()
  })

  it('returns downloadId and filePath for a valid token', async () => {
    mockFindUnique.mockResolvedValue({
      expiresAt: new Date(Date.now() + 3_600_000),
      download: { id: 'dl-1', filePath: '/storage/abc.mp4' },
    })
    expect(await validateToken('tok')).toEqual({
      downloadId: 'dl-1',
      filePath: '/storage/abc.mp4',
    })
  })
})
