/**
 * YouTubeClient.getVideoStatistics Unit Tests
 *
 * Tests the batch video statistics retrieval method that fetches
 * view counts, like counts, and comment counts for multiple videos.
 */

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

const mockVideosList = vi.fn()

vi.mock('googleapis', () => {
  class MockOAuth2 {
    setCredentials(): void {
      // no-op
    }
  }

  return {
    google: {
      auth: {
        OAuth2: MockOAuth2,
      },
      youtube: () => ({
        videos: {
          list: mockVideosList,
        },
        commentThreads: { list: vi.fn() },
        comments: {
          insert: vi.fn(),
          setModerationStatus: vi.fn(),
          delete: vi.fn(),
        },
        channels: { list: vi.fn() },
      }),
    },
  }
})

const mockPayload = {} as import('payload').Payload

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

  it('should return parsed statistics for multiple videos', async () => {
    mockVideosList.mockResolvedValueOnce({
      data: {
        items: [
          {
            id: 'vid1',
            statistics: {
              viewCount: '1500',
              likeCount: '120',
              commentCount: '45',
            },
          },
          {
            id: 'vid2',
            statistics: {
              viewCount: '3200',
              likeCount: '250',
              commentCount: '80',
            },
          },
        ],
      },
    })

    const { YouTubeClient } = await import(
      '@/lib/integrations/youtube/YouTubeClient'
    )

    const client = new YouTubeClient(
      {
        clientId: 'test-id',
        clientSecret: 'test-secret',
        accessToken: 'test-token',
        refreshToken: 'test-refresh',
      },
      mockPayload,
    )

    const result = await client.getVideoStatistics(['vid1', 'vid2'])

    expect(result).toEqual([
      { id: 'vid1', views: 1500, likes: 120, comments: 45 },
      { id: 'vid2', views: 3200, likes: 250, comments: 80 },
    ])

    expect(mockVideosList).toHaveBeenCalledWith({
      part: ['statistics'],
      id: ['vid1', 'vid2'],
      maxResults: 50,
    })
  })

  it('should return empty array for empty input without calling API', async () => {
    const { YouTubeClient } = await import(
      '@/lib/integrations/youtube/YouTubeClient'
    )

    const client = new YouTubeClient(
      {
        clientId: 'test-id',
        clientSecret: 'test-secret',
        accessToken: 'test-token',
        refreshToken: 'test-refresh',
      },
      mockPayload,
    )

    const result = await client.getVideoStatistics([])

    expect(result).toEqual([])
    expect(mockVideosList).not.toHaveBeenCalled()
  })

  it('should default missing statistics to zero', async () => {
    mockVideosList.mockResolvedValueOnce({
      data: {
        items: [
          {
            id: 'vid3',
            statistics: {},
          },
        ],
      },
    })

    const { YouTubeClient } = await import(
      '@/lib/integrations/youtube/YouTubeClient'
    )

    const client = new YouTubeClient(
      {
        clientId: 'test-id',
        clientSecret: 'test-secret',
        accessToken: 'test-token',
        refreshToken: 'test-refresh',
      },
      mockPayload,
    )

    const result = await client.getVideoStatistics(['vid3'])

    expect(result).toEqual([
      { id: 'vid3', views: 0, likes: 0, comments: 0 },
    ])
  })

  it('should handle null items in API response', async () => {
    mockVideosList.mockResolvedValueOnce({
      data: {
        items: null,
      },
    })

    const { YouTubeClient } = await import(
      '@/lib/integrations/youtube/YouTubeClient'
    )

    const client = new YouTubeClient(
      {
        clientId: 'test-id',
        clientSecret: 'test-secret',
        accessToken: 'test-token',
        refreshToken: 'test-refresh',
      },
      mockPayload,
    )

    const result = await client.getVideoStatistics(['vid-missing'])

    expect(result).toEqual([])
  })

  it('should propagate API errors', async () => {
    mockVideosList.mockRejectedValueOnce(new Error('API quota exceeded'))

    const { YouTubeClient } = await import(
      '@/lib/integrations/youtube/YouTubeClient'
    )

    const client = new YouTubeClient(
      {
        clientId: 'test-id',
        clientSecret: 'test-secret',
        accessToken: 'test-token',
        refreshToken: 'test-refresh',
      },
      mockPayload,
    )

    await expect(
      client.getVideoStatistics(['vid1']),
    ).rejects.toThrow('API quota exceeded')
  })
})
