import { it, describe, expect, vi, beforeEach } from 'vitest'
import { flushPromises, shallowMount } from '@vue/test-utils'
import MySequencesView from '../../../views/MySequencesView.vue'
import axios from 'axios'
import { createI18n } from 'vue-i18n'
import fr from '../../../locales/fr.json'
import Button from '../../../components/Button.vue'
import { createRouter, createWebHistory } from 'vue-router'
import { createTestingPinia } from '@pinia/testing'
vi.mock('../../../utils/dates', () => ({
  formatDate: vi.fn()
}))
vi.mock('axios')

const i18n = createI18n({
  locale: 'fr',
  fallbackLocale: 'fr',
  globalInjection: true,
  legacy: false,
  messages: {
    fr
  }
})
const router = createRouter({
  history: createWebHistory(),
  routes: []
})

const mockResponseSequences = [
  {
    href: 'https://my-link',
    rel: 'self',
    type: 'application/json'
  },
  {
    href: 'https://my-link',
    id: 'my-id',
    rel: 'child',
    'stats:items': { count: 16 },
    title: 'ma sequence 1',
    extent: {
      temporal: {
        interval: [['2022-09-22T08:03:08+00:00', '2022-09-22T08:03:08+00:00']]
      }
    }
  }
]

describe('Template', () => {
  it('should render the view without sequences', async () => {
    vi.spyOn(axios, 'get').mockResolvedValue({ data: { links: [] } })
    const wrapper = shallowMount(MySequencesView, {
      global: {
        plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
        mocks: {
          $t: (msg) => msg
        }
      }
    })
    await flushPromises()
    expect(axios.get).toHaveBeenCalledWith('api/users/me/catalog')
    expect(wrapper.vm.userSequences).toEqual([])
    expect(wrapper.html()).contains('general.header.upload_text')
  })

  it('should render the view with a loader loading', async () => {
    const wrapper = shallowMount(MySequencesView, {
      global: {
        plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
        mocks: {
          $t: (msg) => msg
        }
      }
    })
    await flushPromises()
    expect(axios.get).toHaveBeenCalledWith('api/users/me/catalog')
    expect(wrapper.vm.userSequences).toEqual([])
    expect(wrapper.html()).contains('general.header.upload_text')
  })

  it('should render the view with a sequence in the list', async () => {
    vi.spyOn(axios, 'get').mockResolvedValue({
      data: { links: mockResponseSequences }
    })
    const wrapper = shallowMount(MySequencesView, {
      global: {
        plugins: [i18n, createTestingPinia({ createSpy: vi.fn })],
        mocks: {
          $t: (msg) => msg
        }
      }
    })
    wrapper.vm.isLoading = true
    await wrapper.vm.$nextTick()
    expect(wrapper.html()).contains('<loader')
  })
})

describe('Methods', () => {
  const mockResponseSequencesToSort = [
    {
      href: 'https://my-link',
      id: 'my-id',
      rel: 'child',
      'stats:items': { count: 16 },
      title: 'za sequence 1',
      extent: {
        temporal: {
          interval: [['2030-09-22T08:03:08+00:00', '2022-09-22T08:03:08+00:00']]
        }
      }
    },
    {
      href: 'https://my-link',
      id: 'my-id',
      rel: 'child',
      'stats:items': { count: 2 },
      title: 'ma sequence 1',
      extent: {
        temporal: {
          interval: [['2022-09-22T08:03:08+00:00', '2022-09-22T08:03:08+00:00']]
        }
      }
    }
  ]
  beforeEach(async () => {
    await axios.get.mockReturnValue({
      data: { links: mockResponseSequencesToSort }
    })
    await flushPromises()
  })
  describe('sortAlpha', () => {
    it('should should sort sequences by title', async () => {
      const wrapper = shallowMount(MySequencesView, {
        global: {
          plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
          mocks: {
            $t: (msg) => msg
          },
          components: {
            Button
          }
        }
      })
      wrapper.vm.isLoading = false
      await wrapper.vm.$nextTick()
      const spy = vi.spyOn(wrapper.vm, 'sortAlpha')
      const buttonWrapper = wrapper.findComponent(
        '[data-test="button-sort-title"]'
      )
      await buttonWrapper.vm.$emit('trigger')
      expect(spy).toHaveBeenCalledWith('title')
      expect(wrapper.vm.userSequences[0]).toEqual(
        mockResponseSequencesToSort[1]
      )
    })
  })
  describe('sortNum', () => {
    it('should should sort sequences by number of pictures', async () => {
      const wrapper = shallowMount(MySequencesView, {
        global: {
          plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
          mocks: {
            $t: (msg) => msg
          },
          components: {
            Button
          }
        }
      })
      wrapper.vm.isLoading = false
      await wrapper.vm.$nextTick()
      const spy = vi.spyOn(wrapper.vm, 'sortNum')
      const buttonWrapper = wrapper.findComponent(
        '[data-test="button-sort-number"]'
      )
      await buttonWrapper.vm.$emit('trigger')

      expect(spy).toHaveBeenCalledWith('num')
      expect(wrapper.vm.userSequences[0]).toEqual(
        mockResponseSequencesToSort[1]
      )
    })
    it('should should sort sequences by date', async () => {
      const wrapper = shallowMount(MySequencesView, {
        global: {
          plugins: [i18n, router, createTestingPinia({ createSpy: vi.fn })],
          mocks: {
            $t: (msg) => msg
          },
          components: {
            Button
          }
        }
      })
      wrapper.vm.isLoading = false
      await wrapper.vm.$nextTick()
      const spy = vi.spyOn(wrapper.vm, 'sortNum')
      const buttonWrapper = wrapper.findComponent(
        '[data-test="button-sort-date"]'
      )
      await buttonWrapper.vm.$emit('trigger')

      expect(spy).toHaveBeenCalledWith('date')
      expect(wrapper.vm.userSequences[0]).toEqual(
        mockResponseSequencesToSort[1]
      )
    })
  })
})
