import { createAppLocalVue } from '@/../tests/utils' // should be the first to implement default mocks
import App from '@/app/App.vue'
import EsacRedemptionFrom from '../redemption/components/EsacRedemptionForm'
import { shallowMount, mount } from '@vue/test-utils'
import { loggedInStore, loggedOutStore } from '@/../tests/factories/auth-store'
import flushPromises from 'flush-promises'
import { store as appStore } from '@/store'
import { ESAC_VOUCHER_LIST, ESAC_REDEMPTION_FORM } from '@/config/url-prefix'
import _ from 'lodash'

describe('Esac - Routing', () => {
  let store
  let localVue
  let router
  let SecurityConfig

  beforeEach(async () => {
    jest.resetModules()
    jest.clearAllMocks()

    router = await require('@/router').default

    SecurityConfig = await require('@/config/security').default

    SecurityConfig.router = router

    localVue = createAppLocalVue()

    await flushPromises()
  })

  // Esac Dashboard
  it('Should not render esac component when logged out', async () => {
    store = loggedOutStore()

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_VOUCHER_LIST).catch(() => {})

    await flushPromises()

    expect(wrapper.vm.$route.path).not.toMatch(ESAC_VOUCHER_LIST)
  })

  it('Should render esac component when logged in', async () => {
    store = loggedInStore(appStore)

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_VOUCHER_LIST)

    await flushPromises()

    expect(wrapper.vm.$route.path).toMatch(ESAC_VOUCHER_LIST)

    expect(wrapper.isVueInstance()).toBeTruthy()
  })

  it('Should render esac component when logged in with :page', async () => {
    store = loggedInStore(appStore)

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_VOUCHER_LIST + '/1')

    await flushPromises()

    expect(wrapper.vm.$route.path).toMatch(ESAC_VOUCHER_LIST)

    expect(wrapper.vm.$route.params.page).toBe('1')
  })

  // Esac Redemption
  it('Should not render redemption component when logged out', async () => {
    store = loggedOutStore(appStore)

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_REDEMPTION_FORM).catch(() => {})

    await flushPromises()

    expect(wrapper.vm.$route.path).not.toMatch(ESAC_REDEMPTION_FORM)
  })

  it('Should render redemption component when logged in', async () => {
    store = loggedInStore(appStore)

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_REDEMPTION_FORM)

    await flushPromises()

    expect(wrapper.vm.$route.path).toMatch(ESAC_REDEMPTION_FORM)

    expect(wrapper.isVueInstance()).toBeTruthy()
  })

  it('Should render redemption component when logged in with sale id', async () => {
    let actions = {
      loadEsacCountryRelation: jest.fn(),
      redirectToEsacMakePaymentScreen: jest.fn(),
    }
    store = loggedInStore(
      _.merge(appStore, {
        modules: {
          esac: {
            actions,
          },
        },
      })
    )

    const wrapper = mount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_REDEMPTION_FORM + '/1')

    await flushPromises()

    let redemptionForm = wrapper.find(EsacRedemptionFrom)
    expect(redemptionForm.exists()).toBe(true)
    expect(redemptionForm.props('saleId')).toBe('1')
    expect(wrapper.vm.$route.path).toMatch(ESAC_REDEMPTION_FORM)
    expect(actions.loadEsacCountryRelation).toHaveBeenCalledTimes(1)
    expect(actions.redirectToEsacMakePaymentScreen).toHaveBeenCalledTimes(1)
    expect(wrapper.vm.$route.params.saleId).toBe('1')
  })

  // Esac Dashboard
  it('Should not render esac list component when logged out', async () => {
    store = loggedOutStore()

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_VOUCHER_LIST).catch(() => {})

    await flushPromises()

    expect(wrapper.vm.$route.path).not.toMatch(ESAC_VOUCHER_LIST)
  })

  // Esac Redemption
  it('Should not render redemption form component when logged out', async () => {
    store = loggedOutStore()

    const wrapper = shallowMount(App, {
      localVue,
      router,
      store: store,
    })

    router.push(ESAC_REDEMPTION_FORM).catch(() => {})

    await flushPromises()

    expect(wrapper.vm.$route.path).not.toMatch(ESAC_REDEMPTION_FORM)
  })
})
