import { POST } from '../route'
import { prisma } from '@/lib/prisma'
import * as rateLimit from '@/lib/rate-limit'

jest.mock('@/lib/prisma', () => ({
  prisma: { download: { create: jest.fn() } },
}))
jest.mock('@/lib/rate-limit')

const mockCreate = prisma.download.create as jest.Mock
const mockIsRateLimited = rateLimit.isRateLimited as jest.Mock

function req(body: object, ip = '1.2.3.4') {
  return new Request('http://localhost/api/downloads', {
    method: 'POST',
    headers: { 'content-type': 'application/json', 'x-forwarded-for': ip },
    body: JSON.stringify(body),
  })
}

describe('POST /api/downloads', () => {
  beforeEach(() => {
    mockIsRateLimited.mockReturnValue(false)
    mockCreate.mockResolvedValue({ uuid: 'test-uuid' })
  })

  it('returns 429 when rate limited', async () => {
    mockIsRateLimited.mockReturnValue(true)
    const res = await POST(req({ url: 'https://y.com', format: 'mp4', quality: 'best', subtitles: false }))
    expect(res.status).toBe(429)
  })

  it('returns 400 when url is missing', async () => {
    const res = await POST(req({ format: 'mp4', quality: 'best', subtitles: false }))
    expect(res.status).toBe(400)
  })

  it('returns 400 when format is missing', async () => {
    const res = await POST(req({ url: 'https://y.com', quality: 'best', subtitles: false }))
    expect(res.status).toBe(400)
  })

  it('returns 201 with uuid on success', async () => {
    const res = await POST(req({ url: 'https://youtube.com/watch?v=abc', format: 'mp4', quality: 'best', subtitles: false }))
    expect(res.status).toBe(201)
    expect(await res.json()).toEqual({ uuid: 'test-uuid' })
  })

  it('passes correct fields to prisma', async () => {
    await POST(req({ url: 'https://y.com/watch?v=x', format: 'mp3', quality: '720p', subtitles: true }, '9.9.9.9'))
    expect(mockCreate).toHaveBeenCalledWith({
      data: expect.objectContaining({
        url: 'https://y.com/watch?v=x',
        format: 'mp3',
        quality: '720p',
        subtitles: true,
        ipAddress: '9.9.9.9',
      }),
    })
  })
})
