import { createAppLocalVue, waitNT } from '@/../tests/utils' // should be the first to implement default mocks
import OTPResetPassword from '../landing/components/OTPResetPassword'
import { mount } from '@vue/test-utils'
import flushPromises from 'flush-promises'
import { loggedOutStore } from '@/../tests/factories/auth-store'
import store from '@/store'
import router from '@/router'

const localVue = createAppLocalVue()

describe('Login - Landing - OTP Reset Password', () => {
  let wrapper, sendResetPassword

  beforeEach(async () => {
    sendResetPassword = jest.fn().mockImplementation(() => Promise.resolve(true))

    wrapper = mount(OTPResetPassword, {
      localVue,
      store,
      router,
      methods: {
        sendResetPassword,
        setResetResponseData(value) {
          this.$data.responseData = value
        },
        initPhoneMixin: jest.fn(),
      },
      data: () => ({
        resetErrorStatus: null,
        responseData: {},
      }),
      computed: {
        getResetErrorStatus() {
          return this.$data.resetErrorStatus
        },
        getResetResponseData() {
          return this.$data.responseData
        },
      },
    })

    await flushPromises()
  })

  it('Should display errors', async () => {
    wrapper.setData({
      resetErrorStatus: true,
      resetErrorMsg: ['error1'],
    })

    await waitNT(wrapper.vm)

    expect(wrapper.find('.alert').text()).toContain('Login.LoginForm.MobileResetMessage')
  })

  describe('isMobile Prop Is True', () => {
    beforeEach(async () => {
      wrapper.setData({
        responseData: {
          mobile_country_code_id: 1,
          mobile_num: '1231312313',
        },
      })

      await flushPromises()
    })

    it('Should display correctly', async () => {
      expect(wrapper.isVueInstance()).toBeTruthy()
    })

    it('Should validate fields', async () => {
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await waitNT(wrapper.vm)
      expect(wrapper.vm.$validator.errors.any()).toBe(true)
    })

    it('Should validate fields with otp and submit', async () => {
      wrapper.find({ ref: 'otp' }).setValue('123123')
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await flushPromises()

      expect(sendResetPassword).toBeCalledWith({
        otp: '123123',
        request_type: 'validate',
        mobile_country_code_id: 1,
        mobile_num: '1231312313',
      })

      wrapper.find({ ref: 'newPassword' }).setValue('passWORD1234')
      wrapper.find({ ref: 'confirmNewPassword' }).setValue('passWORD1234')
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await flushPromises()
      await waitNT(wrapper.vm)

      expect(sendResetPassword).toBeCalledWith({
        otp: '123123',
        request_type: 'reset-password',
        mobile_country_code_id: 1,
        mobile_num: '1231312313',
        password: 'passWORD1234',
        password_confirmation: 'passWORD1234',
      })
    })
  })

  describe('isMobile Prop Is false', () => {
    beforeEach(async () => {
      wrapper.setData({
        responseData: {
          email: 'shiman.dc@gmail.com',
        },
      })

      await waitNT(wrapper.vm)
      await flushPromises()
    })

    it('Should display correctly', async () => {
      expect(wrapper.isVueInstance()).toBeTruthy()
    })

    it('Should validate fields', async () => {
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await waitNT(wrapper.vm)
      expect(wrapper.vm.$validator.errors.any()).toBe(true)
    })

    it('Should validate fields with otp and submit', async () => {
      wrapper.find({ ref: 'otp' }).setValue('123123')
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await flushPromises()

      expect(sendResetPassword).toBeCalledWith({
        otp: '123123',
        request_type: 'validate',
        email: 'shiman.dc@gmail.com',
      })

      wrapper.find({ ref: 'newPassword' }).setValue('passWORD1234')
      wrapper.find({ ref: 'confirmNewPassword' }).setValue('passWORD1234')
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await flushPromises()
      await waitNT(wrapper.vm)

      expect(sendResetPassword).toBeCalledWith({
        otp: '123123',
        request_type: 'reset-password',
        email: 'shiman.dc@gmail.com',
        password: 'passWORD1234',
        password_confirmation: 'passWORD1234',
      })
    })
  })

  describe('userId prop is set', () => {
    beforeEach(async () => {
      wrapper.setProps({
        userId: 1,
      })

      await waitNT(wrapper.vm)
      await flushPromises()
    })

    it('Should validate fields', async () => {
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await waitNT(wrapper.vm)
      expect(wrapper.vm.$validator.errors.any()).toBe(true)
    })

    it('Should validate fields with otp and submit', async () => {
      wrapper.find({ ref: 'otp' }).setValue('123123')
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await flushPromises()

      expect(sendResetPassword).toBeCalledWith({
        otp: '123123',
        request_type: 'validate',
        user_id: 1,
      })

      wrapper.find({ ref: 'newPassword' }).setValue('passWORD1234')
      wrapper.find({ ref: 'confirmNewPassword' }).setValue('passWORD1234')
      wrapper.find({ ref: 'submitButton' }).trigger('click')

      await flushPromises()
      await waitNT(wrapper.vm)

      expect(sendResetPassword).toBeCalledWith({
        otp: '123123',
        request_type: 'reset-password',
        user_id: 1,
        password: 'passWORD1234',
        password_confirmation: 'passWORD1234',
      })
    })
  })
})
