import { createAppLocalVue, waitNT } from '@/../tests/utils' // should be the first to implement default mocks
import App from '@/app/App.vue'
import mockLoginForm from '../landing/components/LoginForm'
import mockResetPassword from '../landing/components/OTPResetPassword'
import { shallowMount, mount } from '@vue/test-utils'
import SecurityConfig from '@/config/security'
import { loggedOutStore } from '../../../../tests/factories/auth-store'
import flushPromises from 'flush-promises'
import { store as appStore } from '@/store'
import { LOGIN_URL } from '@/config/defaults'
import loginRoutingMixin from '@/app/login/landing/components/mixins/loginRoutingMixin'

describe('Login - Routing', () => {
  let store
  let localVue
  let router
  let wrapper

  const Component = {
    template: '<div class="mi-component"></div>',
  }

  beforeEach(async () => {
    router = await require('@/router').default
    SecurityConfig.router = router
    store = loggedOutStore(appStore)
    localVue = createAppLocalVue()

    wrapper = mount(Component, {
      router,
      localVue,
      store: store,
      mixins: [loginRoutingMixin],
      data: () => ({
        firstTimeLogin: false,
        isEnroledOnBehalf: false,
        resetStatus: false,
        resetResponseData: false,
      }),
      computed: {
        getIsFirstTimeLogin() {
          return this.$data.firstTimeLogin
        },
        getIsEnroledOnBehalf() {
          return this.$data.isEnroledOnBehalf
        },
        getResetStatus() {
          return this.$data.resetStatus
        },
        getResetResponseData() {
          return this.$data.resetResponseData
        },
      },
      sync: false,
    })

    await flushPromises()
  })

  it('Should route to change password if getIsFirstTimeLogin', async () => {
    wrapper.setData({
      firstTimeLogin: true,
    })

    await flushPromises()
    await waitNT(wrapper.vm)

    expect(wrapper.vm.$route.path).toMatch(LOGIN_URL + '/change-password')
  })

  it('Should route to preferred contact if getIsFirstTimeLogin and getIsEnroledOnBehalf is true', async () => {
    wrapper.setData({
      firstTimeLogin: true,
      isEnroledOnBehalf: true,
    })

    await flushPromises()
    await waitNT(wrapper.vm)

    expect(wrapper.vm.$route.path).toMatch(LOGIN_URL + '/contact')
  })

  it('Should route to otp-reset if getResetStatus is true and resetResponseData is there', async () => {
    wrapper.setData({
      resetResponseData: {
        status: true,
      },
      resetStatus: true,
    })

    await waitNT(wrapper.vm)
    await flushPromises()

    expect(wrapper.vm.$route.path).toMatch(LOGIN_URL + '/otp-reset')
  })

  it('Should route to otp-reset if currently in otp-reset and resetResponseData is there', async () => {
    wrapper.setData({
      resetResponseData: {
        status: true,
      },
    })

    router.push(LOGIN_URL + '/otp-reset')
    await flushPromises()
    await waitNT(wrapper.vm)

    expect(wrapper.vm.$route.path).toMatch(LOGIN_URL + '/otp-reset')
  })

  it('Should route to login if getResetStatus is true and resetResponseData is not there', async () => {
    wrapper.setData({
      resetStatus: true,
    })

    await flushPromises()
    await waitNT(wrapper.vm)

    expect(wrapper.vm.$route.path).toMatch(LOGIN_URL)
  })

  it('Should route to login if currently in otp-reset and resetResponseData is not there', async () => {
    router.push(LOGIN_URL + '/otp-reset')
    await flushPromises()
    await waitNT(wrapper.vm)

    expect(wrapper.vm.$route.path).toMatch(LOGIN_URL)
  })
})
