import { vi, describe, test, expect, beforeEach, afterEach } from 'vitest'
import ApiRequestService from '~/services/data/apiRequestService'
import ImageManager from '~/services/data/imageManager'
import 'blob-polyfill'

let apiRequestService: ApiRequestService
let imageManager: ImageManager

let initConsoleError: any

beforeEach(() => {
  // @ts-ignore
  apiRequestService = vi.fn() as ApiRequestService

  imageManager = new ImageManager(apiRequestService)

  // Important : Restore console error after mocking
  initConsoleError = console.error
})

afterEach(() => {
  vi.restoreAllMocks()
  console.error = initConsoleError
})

describe('get', () => {
  test('simple call', async () => {
    const blobPart = vi.fn()
    const response = vi.fn()

    // @ts-ignore
    response.blob = () => blobPart

    // @ts-ignore
    apiRequestService.get = vi.fn((url: string) => response)

    // @ts-ignore
    imageManager.getCacheKey = vi.fn(() => '123456')

    // @ts-ignore
    imageManager.toBase64 = vi.fn((_: string) => 'base64:azerty')

    const result = await imageManager.get(1)

    expect(apiRequestService.get).toHaveBeenCalledWith('api/download/1', [
      '123456',
    ])

    // @ts-ignore
    expect(imageManager.toBase64).toHaveBeenCalledWith(blobPart)

    expect(result).toEqual('base64:azerty')
  })

  test('no id, no default image provided', async () => {
    expect(await imageManager.get(null)).toEqual(ImageManager.defaultImage)
  })

  test('no id, default image provided', async () => {
    const defaultImage = 'a_picture.jpg'

    expect(await imageManager.get(null, defaultImage)).toEqual(defaultImage)
  })

  test('no response, no default image', async () => {
    const blobPart = vi.fn()

    // @ts-ignore
    apiRequestService.get = vi.fn((url: string) => null)

    // @ts-ignore
    imageManager.getCacheKey = vi.fn(() => '123456')
    // @ts-ignore
    imageManager.toBase64 = vi.fn()

    console.error = vi.fn()

    const result = await imageManager.get(1)

    expect(apiRequestService.get).toHaveBeenCalledWith('api/download/1', [
      '123456',
    ])
    expect(console.error).toHaveBeenCalledWith('Error: image 1 not found')
    // @ts-ignore
    expect(imageManager.toBase64).toHaveBeenCalledTimes(0)

    expect(result).toEqual(ImageManager.defaultImage)
  })

  test('no response, default image', async () => {
    const blobPart = vi.fn()

    // @ts-ignore
    blobPart.size = 0

    const response = vi.fn()

    // @ts-ignore
    response.blob = () => blobPart

    // @ts-ignore
    apiRequestService.get = vi.fn((url: string) => response)

    // @ts-ignore
    imageManager.getCacheKey = vi.fn(() => '123456')

    // @ts-ignore
    imageManager.toBase64 = vi.fn()

    console.error = vi.fn()

    const result = await imageManager.get(1, 'some_default.jpg')

    expect(apiRequestService.get).toHaveBeenCalledWith('api/download/1', [
      '123456',
    ])
    expect(console.error).toHaveBeenCalledWith('Error: image 1 is invalid')
    // @ts-ignore
    expect(imageManager.toBase64).toHaveBeenCalledTimes(0)

    expect(result).toEqual('some_default.jpg')
  })
})

describe('toBase64', () => {
  test('simple call', async () => {
    // @ts-ignore
    expect(await imageManager.toBase64('some_data')).toEqual(
      'data:image/jpeg;base64,c29tZV9kYXRh',
    )
  })
})

describe('getCacheKey', () => {
  test('simple call', () => {
    // @ts-ignore
    expect(imageManager.getCacheKey()).toMatch(/\d{10,}/)
  })
})
