// tests/unit/media-download.unit.spec.ts
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { downloadAndUploadImage } from '../../src/lib/utils/media-download'

// Mock fetch globally
const mockFetch = vi.fn()
vi.stubGlobal('fetch', mockFetch)

// Mock payload instance
const mockPayload = {
  find: vi.fn(),
  create: vi.fn(),
}

describe('downloadAndUploadImage', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('should download image and create media document', async () => {
    // Mock successful fetch
    const mockBuffer = Buffer.from('fake-image-data')
    mockFetch.mockResolvedValue({
      ok: true,
      headers: { get: (h: string) => (h === 'content-type' ? 'image/jpeg' : '1024') },
      arrayBuffer: () => Promise.resolve(mockBuffer.buffer),
    })

    // Mock no existing duplicate
    mockPayload.find.mockResolvedValue({ docs: [], totalDocs: 0 })

    // Mock media creation
    mockPayload.create.mockResolvedValue({ id: 42 })

    const result = await downloadAndUploadImage(mockPayload as any, {
      url: 'https://img.youtube.com/vi/abc123/hqdefault.jpg',
      filename: 'abc123_thumbnail.jpg',
      alt: 'Video Thumbnail',
    })

    expect(result).toBe(42)
    expect(mockFetch).toHaveBeenCalledWith(
      'https://img.youtube.com/vi/abc123/hqdefault.jpg',
      expect.objectContaining({ signal: expect.any(AbortSignal) }),
    )
    expect(mockPayload.create).toHaveBeenCalledWith(
      expect.objectContaining({
        collection: 'media',
        file: expect.objectContaining({
          name: 'abc123_thumbnail.jpg',
          mimetype: 'image/jpeg',
        }),
      }),
    )
  })

  it('should return existing media ID if duplicate found', async () => {
    mockPayload.find.mockResolvedValue({
      docs: [{ id: 99 }],
      totalDocs: 1,
    })

    const result = await downloadAndUploadImage(mockPayload as any, {
      url: 'https://img.youtube.com/vi/abc123/hqdefault.jpg',
      filename: 'abc123_thumbnail.jpg',
    })

    expect(result).toBe(99)
    expect(mockFetch).not.toHaveBeenCalled()
  })

  it('should return null on fetch error', async () => {
    mockPayload.find.mockResolvedValue({ docs: [], totalDocs: 0 })
    mockFetch.mockRejectedValue(new Error('Network error'))

    const result = await downloadAndUploadImage(mockPayload as any, {
      url: 'https://img.youtube.com/vi/bad/hqdefault.jpg',
      filename: 'bad_thumbnail.jpg',
    })

    expect(result).toBeNull()
  })

  it('should return null on non-ok response', async () => {
    mockPayload.find.mockResolvedValue({ docs: [], totalDocs: 0 })
    mockFetch.mockResolvedValue({ ok: false, status: 404 })

    const result = await downloadAndUploadImage(mockPayload as any, {
      url: 'https://img.youtube.com/vi/notfound/hqdefault.jpg',
      filename: 'notfound_thumbnail.jpg',
    })

    expect(result).toBeNull()
  })
})
