<script setup lang="ts">
import { fetchEmailCode, fetchUserInfoUpdate, fetchVerifyCode } from '@/apis/user'
import { useUserStore } from '@/store/modules/user'
import { ss } from '@/utils/storage'
import type { CountdownInst, FormInst, FormItemRule } from 'naive-ui'
import isEmail from 'validator/es/lib/isEmail'
import { onMounted, ref, shallowReadonly, useTemplateRef } from 'vue'
import { useI18n } from 'vue-i18n'

const { t } = useI18n()
const userStore = useUserStore()

const emailInfoFormRef = useTemplateRef<FormInst>('emailInfoFormRef')
const countdownRef = useTemplateRef<CountdownInst>('countdownRef')

const isShowMailboxBindingModal = defineModel<boolean>('isShowMailboxBindingModal', { default: false })

const mailboxBindingSubmitBtnLoading = ref(false)
const emailInfoForm = ref({
  email: '',
  verifyCode: '',
})

const isShowCountdown = ref(false)
const countdownDuration = ref<number>(60000)
const countdownActive = ref(true)

const emailInfoFormRules = shallowReadonly({
  email: {
    required: true,
    trigger: 'blur',
    validator: (_rule: FormItemRule, value: string) => {
      if (!value) {
        return new Error(t('login_module.please_enter_your_email_address'))
      } else if (!isEmail(value)) {
        return new Error(t('login_module.please_enter_the_correct_email_address'))
      }

      return
    },
  },
  verifyCode: {
    required: true,
    trigger: 'blur',
    validator: (_rule: FormItemRule, value: string) => {
      if (!value) {
        return new Error(t('login_module.please_enter_the_verification_code'))
      } else if (value.length < 6) {
        return new Error(t('personal_settings_module.please_enter_the_correct_verification_code'))
      }

      return
    },
  },
})

onMounted(() => {
  let timeStringDraft = ss.get('PASSWORD_CHANGE_CODE')

  if (timeStringDraft) {
    const time = Math.floor(Date.now() - parseInt(timeStringDraft))

    if (time < 60000) {
      countdownDuration.value = 60000 - time
      countdownRef.value?.reset()
      isShowCountdown.value = true
    }
  }
})

function onModalAfterLeave() {
  emailInfoForm.value.email = ''
}

function handleMailboxBindingSubmit() {
  emailInfoFormRef.value?.validate((errors) => {
    if (errors) return ''

    mailboxBindingSubmitBtnLoading.value = true

    fetchVerifyCode<string>(emailInfoForm.value.email, emailInfoForm.value.verifyCode)
      .then((res) => {
        if (res.code !== 0) return ''

        fetchUserInfoUpdate({
          email: emailInfoForm.value.email,
        })
          .then(() => {
            userStore.fetchUpdateUserInfo()

            window.$message.success(t('personal_settings_module.binding_successful'))
          })
          .finally(() => {
            isShowMailboxBindingModal.value = false

            mailboxBindingSubmitBtnLoading.value = false
            isShowCountdown.value = false
          })
      })
      .catch(() => {
        mailboxBindingSubmitBtnLoading.value = false
      })
  })
}

function countdownRender({ seconds, minutes }: { seconds: number; minutes: number }) {
  if (minutes && minutes === 1) {
    return '60 s'
  }

  return `${seconds} s`
}

function onCountdownFinish() {
  isShowCountdown.value = false
}

function handleSMSCodeGain() {
  emailInfoFormRef.value?.validate(
    (errors) => {
      if (errors) return ''

      countdownDuration.value = 60000
      ss.set('MAILBOX_BINDING_CODE', Date.now())
      countdownRef.value?.reset()
      isShowCountdown.value = true

      fetchEmailCode(encodeURIComponent(emailInfoForm.value.email)).then((res) => {
        if (res.code !== 0) return ''

        window.$message.success(t('login_module.successful'))
      })
    },
    (rule) => {
      return rule.key === 'email'
    },
  )
}
</script>

<template>
  <n-modal v-model:show="isShowMailboxBindingModal" :mask-closable="false" :on-after-leave="onModalAfterLeave">
    <n-card
      class="!w-[600px]"
      :title="t('personal_settings_module.email_binding')"
      :bordered="false"
      size="medium"
      closable
      content-style="margin-top: 20px;"
      @close="() => (isShowMailboxBindingModal = false)"
    >
      <n-form
        ref="emailInfoFormRef"
        label-placement="left"
        label-width="auto"
        :model="emailInfoForm"
        :rules="emailInfoFormRules"
        size="large"
      >
        <n-form-item :label="t('common_module.email')" path="email">
          <n-input v-model:value="emailInfoForm.email" :placeholder="t('login_module.please_enter_your_email_address')">
            <template #suffix>
              <span class="mx-[10px] inline-block h-[50%] w-[2px] bg-[#e0e0e6]"></span>
              <span v-show="!isShowCountdown" class="cursor-pointer text-[12px] text-[#333]" @click="handleSMSCodeGain">
                {{ t('login_module.get_verification_code') }}
              </span>

              <div v-show="isShowCountdown" class="inline-block w-[50px] text-center">
                <n-countdown
                  ref="countdownRef"
                  :duration="countdownDuration"
                  :active="countdownActive"
                  :render="countdownRender"
                  :on-finish="onCountdownFinish"
                />
              </div>
            </template>
          </n-input>
        </n-form-item>
        <n-form-item :label="t('common_module.verificationCode')" path="verifyCode">
          <n-input
            v-model:value="emailInfoForm.verifyCode"
            :placeholder="t('login_module.please_enter_the_verification_code')"
            :maxlength="6"
          />
        </n-form-item>
      </n-form>

      <template #footer>
        <div class="text-end">
          <n-space justify="end">
            <n-button class="!h-[34px] !w-[96px]" round @click="() => (isShowMailboxBindingModal = false)">
              {{ t('common_module.cancel_btn_text') }}
            </n-button>
            <n-button
              class="!h-[34px] !w-[96px]"
              color="#6F77FF"
              round
              :loading="mailboxBindingSubmitBtnLoading"
              @click="handleMailboxBindingSubmit"
            >
              {{ t('common_module.confirm_btn_text') }}
            </n-button>
          </n-space>
        </div>
      </template>
    </n-card>
  </n-modal>
</template>
