import { describe, it, expect, vi, beforeEach } from 'vitest'
import { POST } from './route'
import { NextRequest } from 'next/server'

vi.mock('@/lib/youtube', () => ({
  getVideoInfo: vi.fn(),
}))

import { getVideoInfo } from '@/lib/youtube'

const mockGetVideoInfo = vi.mocked(getVideoInfo)

function createRequest(body: object): NextRequest {
  return new NextRequest('http://localhost:3000/api/info', {
    method: 'POST',
    body: JSON.stringify(body),
    headers: { 'Content-Type': 'application/json' },
  })
}

describe('POST /api/info', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('returns 400 when URL is missing', async () => {
    const request = createRequest({})
    const response = await POST(request)
    const data = await response.json()

    expect(response.status).toBe(400)
    expect(data.success).toBe(false)
    expect(data.error).toBe('URL is required')
  })

  it('returns 400 for invalid YouTube URL', async () => {
    const request = createRequest({ url: 'https://vimeo.com/123' })
    const response = await POST(request)
    const data = await response.json()

    expect(response.status).toBe(400)
    expect(data.success).toBe(false)
    expect(data.error).toBe('Invalid YouTube URL')
  })

  it('returns 500 when getVideoInfo fails', async () => {
    mockGetVideoInfo.mockResolvedValue(null)

    const request = createRequest({ url: 'https://youtube.com/watch?v=dQw4w9WgXcQ' })
    const response = await POST(request)
    const data = await response.json()

    expect(response.status).toBe(500)
    expect(data.success).toBe(false)
    expect(data.error).toBe('Failed to get video info')
  })

  it('returns video info on success', async () => {
    const mockVideoInfo = {
      title: 'Test Video',
      duration: 180,
      thumbnail: 'https://example.com/thumb.jpg',
      formats: [],
    }
    mockGetVideoInfo.mockResolvedValue(mockVideoInfo)

    const request = createRequest({ url: 'https://youtube.com/watch?v=dQw4w9WgXcQ' })
    const response = await POST(request)
    const data = await response.json()

    expect(response.status).toBe(200)
    expect(data.success).toBe(true)
    expect(data.videoInfo).toEqual(mockVideoInfo)
  })

  it('handles exceptions gracefully', async () => {
    const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
    mockGetVideoInfo.mockRejectedValue(new Error('Network error'))

    const request = createRequest({ url: 'https://youtube.com/watch?v=dQw4w9WgXcQ' })
    const response = await POST(request)
    const data = await response.json()

    expect(response.status).toBe(500)
    expect(data.success).toBe(false)
    expect(data.error).toBe('Network error')
    consoleSpy.mockRestore()
  })
})
