import { dashboardService } from '@/services/dashboard-service'
import { discoverService } from '@/services/discover-service'
import { downloadService } from '@/services/download-service'
import { gamesService } from '@/services/games-service'
import { progressService } from '@/services/progress-service'
import { searchService } from '@/services/search-service'
import { watchLaterService } from '@/services/watch-later-service'

describe('mock services', () => {
  it('returns dashboard payload', async () => {
    const payload = await dashboardService.getDashboard({ latencyMs: 0 })

    expect(payload.watchLater.length).toBeGreaterThan(0)
    expect(payload.gameBacklog.every((item) => item.type === 'game')).toBe(true)
    expect(payload.recommendations.length).toBeGreaterThan(0)
    expect(payload.activeDownloads.length).toBeGreaterThan(0)
  })

  it('returns continue watching entries', async () => {
    const entries = await progressService.getContinueWatching('mock-access-token', { latencyMs: 0 })

    expect(entries.length).toBeGreaterThan(0)
    expect(entries[0]?.progress.progressPercent).toBeGreaterThanOrEqual(0)
  })

  it('updates continue watching progress', async () => {
    const token = 'mock-access-token'
    const updated = await progressService.updateProgress(
      token,
      {
        mediaId: 2,
        seasonNumber: 1,
        episodeNumber: 7,
        progressPercent: 100,
      },
      { latencyMs: 0 },
    )

    expect(updated.some((entry) => entry.item.id === 2 && entry.progress.progressPercent === 100)).toBe(false)
  })

  it('filters and paginates discover sections', async () => {
    const pageOne = await discoverService.getSections(
      {
        page: 1,
        pageSize: 2,
        mediaType: 'game',
        genre: 'Action',
      },
      { latencyMs: 0 },
    )

    expect(pageOne.length).toBeGreaterThan(0)
    expect(pageOne.every((section) => section.items.length <= 2)).toBe(true)
    expect(pageOne.flatMap((section) => section.items).every((item) => item.type === 'game')).toBe(true)
  })

  it('returns dedicated game sections', async () => {
    const sections = await gamesService.getSections({ page: 1, pageSize: 3 }, { latencyMs: 0 })

    expect(sections.length).toBeGreaterThan(0)
    expect(sections.flatMap((section) => section.items).every((item) => item.type === 'game')).toBe(true)
  })

  it('returns ranked search results', async () => {
    const results = await searchService.search('zero', { mediaType: 'all' }, { latencyMs: 0 })

    expect(results.length).toBeGreaterThan(0)
    expect(results[0]?.title.toLowerCase()).toContain('zero')
  })

  it('supports watch later add/remove flow', async () => {
    const token = 'mock-access-token'
    const before = await watchLaterService.getWatchLater(token, { latencyMs: 0 })
    const candidateID = 31

    const afterAdd = await watchLaterService.addWatchLater(token, candidateID, { latencyMs: 0 })
    expect(afterAdd.some((item) => item.id === candidateID)).toBe(true)
    expect(afterAdd.find((item) => item.id === candidateID)?.type).toBe('game')

    const afterRemove = await watchLaterService.removeWatchLater(token, candidateID, { latencyMs: 0 })
    expect(afterRemove.some((item) => item.id === candidateID)).toBe(false)
    expect(afterRemove.length).toBeLessThanOrEqual(afterAdd.length)
    expect(before.length).toBeGreaterThan(0)
  })

  it('supports download create/list/cancel flow', async () => {
    const token = 'mock-access-token'
    const before = await downloadService.list(token, { limit: 30 }, { latencyMs: 0 })

    const created = await downloadService.create(
      token,
      {
        sourceType: 'http',
        source: 'https://example.com/archive.mkv',
        title: 'Archive Pull',
      },
      { latencyMs: 0 },
    )

    expect(created.status).toBe('queued')

    const afterCreate = await downloadService.list(token, { limit: 30 }, { latencyMs: 0 })
    expect(afterCreate.some((job) => job.id === created.id)).toBe(true)

    const cancelled = await downloadService.cancel(token, created.id, { latencyMs: 0 })
    expect(cancelled.status).toBe('failed')
    expect(before.length).toBeGreaterThan(0)
  })

  it('supports explicit error simulation', async () => {
    await expect(dashboardService.getDashboard({ latencyMs: 0, simulateError: true })).rejects.toThrow(
      'Mock request failed',
    )
  })
})
