<template>
  <q-stepper
    v-model="step"
    vertical
    color="primary"
    animated
    flat
    class="bg-transparent q-pt-none"
    >
    <q-step
      :name="1"
      :title="$t('account_helper__enter_email')"
      :done="step>1"
      >
      <q-input
        v-model="login"
        autofocus
        dense
        filled
        :label = "$t('account_helper__email')"
        :rules="validationRules.email"
        lazy-rules
        no-error-icon
        @focus="($refs.emailInput as typeof QInput)?.resetValidation()"
        ref="emailInput"
        :disable="type==='changePwd'"
        class="q-pb-none"
      />
      <q-stepper-navigation>
        <q-btn
          @click="handleSubmit"
          color="primary"
          :label="$t('continue')"
          :disabled="!isEmailValid"
          :unelevated="!isEmailValid"
          class="fix-disabled-btn"
        />
      </q-stepper-navigation>
    </q-step>

    <q-step
      :name="2"
      :title="$t('account_helper__confirm_email')"
      :done="step>2"
      >
      <div class="q-pb-md">{{$t('account_helper__confirm_email_message')}}</div>
      <q-input
        v-model="code"
        dense
        filled
        autofocus
        hide-bottom-space
        :label = "$t('account_helper__code')"
        num="30"
      />
      <q-stepper-navigation>
        <q-btn
          @click="handleSubmit"
          color="primary"
          :label="$t('continue')"
          :disable="code.length===0"
          :unelevated="code.length===0"
          class="fix-disabled-btn"
        />
        <q-btn
          flat
          @click="step=1"
          color="primary"
          :label="$t('back')"
          class="q-ml-sm"
        />
      </q-stepper-navigation>
    </q-step>

    <q-step
      v-if="type === 'register'"
      :name="3"
      :title="$t('account_helper__agreement')"
      :done="step>3"
      >
      <agreement-block v-model="agreement"/>
      <q-stepper-navigation>
        <q-btn
          @click="handleSubmit"
          color="primary"
          :label="$t('account_helper__agreement_btn')"
          :disabled="agreement.length !== 2"
          :unelevated="agreement.length !== 2"
          class="fix-disabled-btn"
        />
        <q-btn
          flat
          @click="step=2"
          color="primary"
          :label="$t('back')"
          class="q-ml-sm"
        />
      </q-stepper-navigation>
    </q-step>

    <q-step
      :name="4"
      :title="$t('account_helper__set_password')"
      >
       <q-input
        v-model="password"
        dense
        filled
        autofocus
        :label="$t('account_helper__password')"
        :type="isPwd ? 'password' : 'text'"
        hide-hint
        :hint="passwordHint"
        :rules="validationRules.password"
        lazy-rules
        no-error-icon
        @focus="($refs.passwordInput as typeof QInput)?.resetValidation()"
        ref="passwordInput"
        class="q-pb-none"
        >
        <template #append>
          <q-icon
            color="grey-5"
            :name="isPwd ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
            class="cursor-pointer"
            @click="isPwd=!isPwd"
          />
        </template>
      </q-input>

      <q-stepper-navigation>
        <q-btn
          @click="handleSubmit"
          color="primary"
          :label="$t('account_helper__finish')"
          :disabled="!isPasswordValid"
          :unelevated="!isPasswordValid"
          class="fix-disabled-btn"
        />
        <q-btn
          flat
          @click="step= type === 'register' ? 3 : 2"
          color="primary"
          :label="$t('back')"
          class="q-ml-sm"
        />
      </q-stepper-navigation>
    </q-step>
  </q-stepper>
  
  <pn-magic-overlay
    v-if="showSuccessOverlay"
    icon="mdi-check-circle-outline"
    :message1="getHelperMessage.m1"
    :message2="getHelperMessage.m2"
    :route-name="getRoute"
  />
</template>
  
<script setup lang="ts">
  import { ref, computed, onMounted, onUnmounted, inject } from 'vue'
  import type { AxiosError } from 'axios'
  import { QInput } from 'quasar'
  import { useAuthStore, type AuthFlowType } from 'stores/auth'
  import { useSettingsStore } from 'stores/settings'
  import agreementBlock from 'components/agreementBlock.vue'
  import { useInputRules } from 'composables/useInputRules'
  import type { WebApp } from '@twa-dev/types'

  const tg = inject('tg') as WebApp

  const { inputRules } = useInputRules()

  const flowType = computed<AuthFlowType>(() => {
    return props.type === 'register'
      ? 'register' 
      : props.type === 'forgotPwd'
        ? 'forgot' 
        : props.type === 'changePwd'
          ? 'changePwd'
          : 'changeMethod'
  })

  const authStore = useAuthStore()
  const settingsStore = useSettingsStore()

  const props = defineProps<{
    type: 'register' | 'forgotPwd' | 'changePwd' | 'changeMethod'
    email?: string
  }>()

  type Step = 1 | 2 | 3 | 4

  const step = ref<Step>(1)
  const login = ref<string>(props.email || '')
  const code = ref<string>('')
  const password = ref<string>('')
  const showSuccessOverlay = ref(false)
  const isPwd = ref<boolean>(true)
  const validationRules = {
    email: [inputRules.email],
    password: [inputRules.password]
  }

  const getRoute = computed(() => {
     return (props.type === 'changeMethod' || props.type === 'changePwd')
        ? 'account'
        : 'projects'
  }) 

  const isEmailValid = computed(() => 
    validationRules.email.every(f => f(login.value) === true)
  )

  const isPasswordValid = computed(() => 
    validationRules.password.every(f => f(password.value) === true)
  )

  const passwordHint = computed(() => {
    const result = validationRules.password[0] ? validationRules.password[0](password.value) : null
    return typeof result === 'string' ? result : ''
  })

  const stepActions: Record<Step, () => Promise<void> | void> = {
    1: async () => {
      await authStore.initRegistration(flowType.value, login.value, settingsStore.settings.locale)
    },
    2: async () => {
      await authStore.confirmCode(flowType.value, login.value, code.value)
    },
    3: () => {},
    4: async () => {
      await authStore.setPassword(flowType.value, login.value, code.value, password.value)
      if (flowType.value === 'register' || flowType.value === 'changeMethod') {
        await authStore.loginWithCredentials(login.value, password.value, tg.initData, settingsStore.settings.locale)
      }
      if (flowType.value === 'register') {
        acceptSubmit.value = true
        sessionStorage.removeItem('account-helper')
      }
    }
  }

  const handleSubmit = async () => {
    try {
      await stepActions[step.value]()
      if (step.value < 4) {
        step.value++
        if (step.value === 3 && props.type !== 'register') step.value++
      } else {
        showSuccessOverlay.value = true
      }
    } catch (error) {
      console.error(error as AxiosError)
    }
  }

  const getHelperMessage = computed(() => {
    switch (flowType.value) {
      case 'register': return { m1: 'account_helper__register_message1', m2: 'slogan' }
      case 'forgot': return { m1: 'account_helper__forgot_password_message1', m2: 'account_helper__go_projects' }
      case 'changePwd': return { m1: 'account_helper__change_password_message1', m2: '' }
      case 'changeMethod': return { m1:'account_helper__change_method_message1', m2: '' }
      default: return { m1: '', m2: '' }
    }
  })

  const agreement = ref<('terms'| 'consent')[]>([])
  const acceptSubmit = ref(false)
  onMounted(() => {
     if (props.type !== 'register') return
     
     const ah = sessionStorage.getItem('account-helper')
     if (!ah) return

     const ahVal = JSON.parse(ah)
     login.value = ahVal.login
     code.value = ahVal.code
     agreement.value = ahVal.agreement
     step.value = ahVal.step
  })

  onUnmounted(() => {
    if (props.type === 'register' && step.value >= 3 && !acceptSubmit.value) {
      sessionStorage.setItem(
        'account-helper',
        JSON.stringify({
          login: login.value,
          code: code.value,
          agreement: agreement.value,
          step: step.value
        })
      )
    }
  })

</script>

<style>
</style>
