<script setup lang="ts">
import { CountdownInst, FormInst, FormItemRule, FormRules } from 'naive-ui'
import isMobilePhone from 'validator/es/lib/isMobilePhone'
import { computed, ref, shallowReadonly, useTemplateRef } from 'vue'
import { useI18n } from 'vue-i18n'
import { Down } from '@icon-park/vue-next'
import { useRoute, useRouter } from 'vue-router'
import SparkMD5 from 'spark-md5'
import { fetchForgetMemberPassword, fetchSMSCode, fetchVerifyCode } from '@/apis/user'
import { ss } from '@/utils/storage'
import { useSystemLanguageStore } from '@/store/modules/system-language'

interface PasswordInfoFormInterface {
  authCode: string
  password: string
  confirmPassword: string
}

const { t } = useI18n()

const systemLanguageStore = useSystemLanguageStore()
const route = useRoute()
const router = useRouter()

const smsLoginFormRef = useTemplateRef<FormInst>('smsLoginFormRef')
const passwordInfoFormRef = useTemplateRef<FormInst>('passwordInfoFormRef')
const countdownRef = useTemplateRef<CountdownInst>('countdownRef')

const isFinishAuthCode = ref(false)

const submitBtnLoading = ref(false)

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

const currentPhoneNumberArea = ref<'+86' | '+852'>('+86')

const smsLoginForm = ref({
  phoneNumber: '',
  code: '',
})

const passwordInfoForm = ref<PasswordInfoFormInterface>({
  authCode: '',
  password: '',
  confirmPassword: '',
})

const smsLoginFormRules = shallowReadonly<FormRules>({
  phoneNumber: {
    key: 'phoneNumber',
    required: true,
    validator: (_rule: FormItemRule, value: string) => {
      if (!value) {
        return new Error(t('login_module.please_enter_your_cell_phone_number'))
      } else if (!isMobilePhone(value, ['zh-CN', 'zh-HK'])) {
        return new Error(t('login_module.please_enter_your_correct_cell_phone_number'))
      }

      return
    },
    trigger: 'blur',
  },
  code: { required: true, message: t('login_module.please_enter_the_verification_code'), trigger: 'blur' },
})

const passwordFormRules = shallowReadonly({
  password: {
    required: true,
    trigger: 'blur',
    validator: (_rule: FormItemRule, value: string) => {
      if (!value) {
        return new Error(t('personal_settings_module.please_enter_your_new_password'))
      } else if (value.length < 6) {
        return new Error(t('personal_settings_module.the_password_contains_a_maximum_of_6_characters'))
      }

      return
    },
  },
  confirmPassword: {
    required: true,
    trigger: 'blur',
    validator: (_rule: FormItemRule, value: string) => {
      if (!value) {
        return new Error(t('personal_settings_module.please_enter_confirm_new_password'))
      } else if (value !== passwordInfoForm.value.password) {
        return new Error(
          t('personal_settings_module.verify_that_the_new_password_is_inconsistent_with_the_new_password'),
        )
      }

      return
    },
  },
})

const phoneNumberAreaOptions = computed(() => {
  return [
    {
      label: `+86⠀${t('login_module.mainland_china')}`,
      value: '+86',
    },
    {
      label: `+852 ${t('login_module.hong_kong_china')}`,
      value: '+852',
    },
  ]
})

const isEnglishLanguage = computed(() => {
  return systemLanguageStore.currentLanguage === 'en'
})

function noSideSpace(value: string) {
  return !value.startsWith(' ') && !value.endsWith(' ')
}

function onlyAllowNumber(value: string) {
  return !value || /^\d+$/.test(value)
}

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() {
  smsLoginFormRef.value?.validate(
    (errors) => {
      if (errors) return ''

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

      fetchSMSCode(getInputPhoneNumber()).then((res) => {
        if (res.code !== 0) return ''

        window.$message.success(t('login_module.successful'))
      })
    },
    (rule) => {
      return rule.key === 'phoneNumber'
    },
  )
}

function getInputPhoneNumber() {
  return currentPhoneNumberArea.value !== '+86'
    ? encodeURIComponent(`${currentPhoneNumberArea.value}${smsLoginForm.value.phoneNumber}`)
    : smsLoginForm.value.phoneNumber
}

function handleBackLogin() {
  const redirectUrl = decodeURIComponent((route.query.redirect as string) || '')
  router.replace({ path: '/login', query: redirectUrl ? { redirect: encodeURIComponent(redirectUrl) } : {} })
}

function handleNextStep() {
  smsLoginFormRef.value?.validate((errors) => {
    if (errors) return ''

    submitBtnLoading.value = true

    fetchVerifyCode<string>(smsLoginForm.value.phoneNumber, smsLoginForm.value.code)
      .then((res) => {
        if (res.code === 0) {
          isShowCountdown.value = false
          isFinishAuthCode.value = true
          passwordInfoForm.value.authCode = res.data
        }
      })
      .finally(() => {
        submitBtnLoading.value = false
      })
  })
}

function handleResetPassword() {
  passwordInfoFormRef.value?.validate((errors) => {
    if (errors) return ''

    submitBtnLoading.value = true

    fetchForgetMemberPassword(
      smsLoginForm.value.phoneNumber,
      passwordInfoForm.value.authCode,
      SparkMD5.hash(passwordInfoForm.value.confirmPassword),
    )
      .then((res) => {
        if (res.code === 0) {
          window.$message.success(t('common_module.reset_success_message'))
          handleBackLogin()
        }
      })
      .finally(() => {
        submitBtnLoading.value = false
      })
  })
}
</script>

<template>
  <div
    class="bg-px-login-h5_login_bg-png relative flex h-full w-full flex-col justify-between bg-cover bg-center bg-no-repeat py-[44px]"
  >
    <div class="px-[33px]">
      <p class="font-family-medium text-[18px]">{{ t('reset_password_module.reset_login_password') }}</p>

      <p class="text-gray-font-color mt-[9px] text-[12px]">
        {{
          isFinishAuthCode
            ? t('reset_password_module.please_enter_your_new_password')
            : t('reset_password_module.please_enter_your_registered_phone_number')
        }}
      </p>

      <!-- 验证码校验 -->
      <n-form
        v-if="!isFinishAuthCode"
        ref="smsLoginFormRef"
        label-placement="left"
        size="large"
        :model="smsLoginForm"
        :rules="smsLoginFormRules"
        class="mt-[30px]"
      >
        <n-form-item path="phoneNumber" feedback-class="text-[12px]!">
          <n-input
            v-model:value.trim="smsLoginForm.phoneNumber"
            :allow-input="onlyAllowNumber"
            :maxlength="currentPhoneNumberArea === '+852' ? 8 : 11"
            :placeholder="t('login_module.please_enter_your_cell_phone_number')"
          >
            <template #prefix>
              <div class="flex items-center">
                <n-popselect v-model:value="currentPhoneNumberArea" :options="phoneNumberAreaOptions" trigger="click">
                  <div class="flex w-[54px] cursor-pointer items-center">
                    <div class="mr-[4px] text-[14px]">{{ currentPhoneNumberArea }}</div>

                    <Down theme="outline" size="18" fill="#333" :stroke-width="3" class="mt-[2px]" />
                  </div>
                </n-popselect>

                <div class="mx-[8px] h-[18px] w-[1px] bg-[#868686]"></div>
              </div>
            </template>
          </n-input>
        </n-form-item>
        <n-form-item path="code" feedback-class="text-[12px]!">
          <n-input
            v-model:value="smsLoginForm.code"
            :allow-input="onlyAllowNumber"
            show-password-on="click"
            :maxlength="6"
            :placeholder="t('login_module.please_enter_the_verification_code')"
          >
          </n-input>
          <n-button
            v-show="!isShowCountdown"
            class="text-[11px]! ml-[9px]! text-[#333]! px-[10px]! bg-white!"
            :class="isEnglishLanguage ? 'w-[70px]!' : 'w-[90px]!'"
            :disabled="!smsLoginForm.phoneNumber"
            @click="handleSMSCodeGain"
          >
            <span>{{ t('common_module.get_code') }}</span>
          </n-button>
          <div
            v-show="isShowCountdown"
            class="flex-center rounded-theme ml-[9px]! text-gray-font-color h-[40px] flex-shrink-0 border bg-white text-center text-[12px]"
            :class="isEnglishLanguage ? 'w-[70px]' : 'w-[90px]'"
          >
            <n-countdown
              ref="countdownRef"
              :duration="countdownDuration"
              :active="countdownActive"
              :render="countdownRender"
              :on-finish="onCountdownFinish"
            />
          </div>
        </n-form-item>
        <n-form-item class="mt-4">
          <n-button
            type="primary"
            size="large"
            block
            :loading="submitBtnLoading"
            :disabled="!smsLoginForm.phoneNumber || !smsLoginForm.code"
            @click="handleNextStep"
          >
            {{ t('common_module.next_btn_text') }}
          </n-button>
        </n-form-item>
      </n-form>

      <!-- 重置密码 -->
      <n-form
        v-if="isFinishAuthCode"
        ref="passwordInfoFormRef"
        label-placement="left"
        size="large"
        :model="passwordInfoForm"
        :rules="passwordFormRules"
        class="mt-[30px]"
      >
        <n-form-item path="password">
          <n-input
            v-model:value="passwordInfoForm.password"
            type="password"
            show-password-on="click"
            class="font-sans"
            :allow-input="noSideSpace"
            :placeholder="t('personal_settings_module.please_enter_your_new_password')"
          />
        </n-form-item>
        <n-form-item path="confirmPassword">
          <n-input
            v-model:value="passwordInfoForm.confirmPassword"
            type="password"
            show-password-on="click"
            class="font-sans"
            :allow-input="noSideSpace"
            :placeholder="t('personal_settings_module.please_enter_confirm_new_password')"
          />
        </n-form-item>

        <n-form-item class="mt-4">
          <n-button
            type="primary"
            size="large"
            block
            :loading="submitBtnLoading"
            :disabled="!passwordInfoForm.password || !passwordInfoForm.confirmPassword"
            @click="handleResetPassword"
          >
            {{ t('reset_password_module.reset_password') }}
          </n-button>
        </n-form-item>
      </n-form>
    </div>

    <div class="flex-center absolute top-[500px] w-full">
      <div
        class="inline-block cursor-pointer border-b border-[#518AFF] text-[12px] leading-[14px] text-[#518AFF]"
        @click="handleBackLogin"
      >
        {{ t('reset_password_module.back_to_login') }}
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
:deep(.--n-feedback-height) {
  height: 16px !important;
}

:deep(.n-input__placeholder) {
  font-size: 13px !important;
}
</style>
