<template>
  <div v-if="visible" class="verification-dialog" @click.self="handleClose">
    <div class="verification-dialog__panel">
      <button type="button" class="verification-dialog__close" @click="handleClose">
        <SvgIcon name="close" size="24" />
      </button>

      <div class="verification-dialog__title">{{ t('Settings.dialog.title') }}</div>
      <div class="verification-dialog__subtitle">{{ t('Settings.dialog.subtitle') }}</div>
      <div class="verification-dialog__email">{{ email }}</div>

      <InputCode
        ref="verificationCodeRef"
        class="verification-code"
        @update:model-value="handleVerificationCodeChange"
        @submit="handleVerificationCodeChange"
      />

      <button
        type="button"
        class="verification-dialog__submit"
        :disabled="saving || verificationCode.length !== 6"
        @click="handleSubmit"
      >
        {{ t('Settings.dialog.submit') }}
      </button>

      <button
        type="button"
        class="verification-dialog__resend"
        :disabled="resendCountdown > 0"
        @click="handleResend"
      >
        {{ resendButtonText }}
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import InputCode from '@/components/input-code.vue'

const props = withDefaults(
  defineProps<{
    visible: boolean
    email: string
    saving?: boolean
  }>(),
  {
    saving: false
  }
)

const emit = defineEmits<{
  close: []
  resend: []
  submit: [code: string]
}>()

const { t } = useI18n()

const RESEND_COUNTDOWN_SECONDS = 60

const verificationCode = ref('')
const resendCountdown = ref(RESEND_COUNTDOWN_SECONDS)
const verificationCodeRef = ref<{ resetCode: (size?: number) => void } | null>(null)
let resendCountdownTimer: ReturnType<typeof window.setInterval> | null = null

const formattedResendCountdown = computed(
  () => `00:${String(resendCountdown.value).padStart(2, '0')}`
)

const resendButtonText = computed(() =>
  resendCountdown.value > 0
    ? t('Settings.dialog.resendCodeIn', { time: formattedResendCountdown.value })
    : t('Settings.dialog.resendCode')
)

const clearResendCountdownTimer = () => {
  if (resendCountdownTimer) {
    window.clearInterval(resendCountdownTimer)
    resendCountdownTimer = null
  }
}

const startResendCountdown = () => {
  clearResendCountdownTimer()
  resendCountdown.value = RESEND_COUNTDOWN_SECONDS
  resendCountdownTimer = window.setInterval(() => {
    if (resendCountdown.value <= 1) {
      resendCountdown.value = 0
      clearResendCountdownTimer()
      return
    }

    resendCountdown.value -= 1
  }, 1000)
}

const resetVerificationCodeInput = async () => {
  verificationCode.value = ''
  await nextTick()
  verificationCodeRef.value?.resetCode?.()
}

const handleClose = () => {
  emit('close')
}

const handleVerificationCodeChange = (value: string) => {
  verificationCode.value = value
}

const handleSubmit = () => {
  if (verificationCode.value.length !== 6) return

  emit('submit', verificationCode.value)
}

const handleResend = async () => {
  if (resendCountdown.value > 0) return

  emit('resend')
  startResendCountdown()
  await resetVerificationCodeInput()
}

watch(
  () => props.visible,
  async (visible) => {
    if (!visible) {
      clearResendCountdownTimer()
      verificationCode.value = ''
      resendCountdown.value = RESEND_COUNTDOWN_SECONDS
      return
    }

    await resetVerificationCodeInput()
    startResendCountdown()
  }
)

watch(
  () => props.email,
  async () => {
    if (!props.visible) return

    await resetVerificationCodeInput()
    startResendCountdown()
  }
)

onBeforeUnmount(() => {
  clearResendCountdownTimer()
})
</script>

<style lang="less" scoped>
.verification-dialog {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: rgba(0, 0, 0, 0.4);
}

.verification-dialog__panel {
  width: 60rem;
  padding: 4.8rem 7.2rem 5rem;
  position: relative;
  background: #efefef;
  box-shadow: 0 2rem 6rem rgba(35, 35, 35, 0.14);
}

.verification-dialog__close {
  position: absolute;
  top: 2rem;
  right: 2rem;
  border: none;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: #585858;
  cursor: pointer;
}

.verification-dialog__title {
  color: #232323;
  text-align: center;
  font-family: 'KaiseiOpti-Bold';
  font-size: 3rem;
}

.verification-dialog__subtitle {
  margin-top: 2rem;
  color: #585858;
  text-align: center;
  font-family: 'KaiseiOpti-Regular';
  font-size: 1.6rem;
  line-height: 2.8rem;
}

.verification-dialog__email {
  margin-top: 0.8rem;
  color: #232323;
  text-align: center;
  font-family: 'KaiseiOpti-Bold';
  font-size: 1.6rem;
  line-height: 2.4rem;
}

.verification-code {
  margin-top: 4.8rem;
  --input-code-justify-content: center;
  --input-code-input-gap: 1.4rem;
  --input-code-input-width: 6rem;
  --input-code-input-height: 6rem;
}

.verification-dialog__submit {
  width: 100%;
  height: 4.8rem;
  margin-top: 5rem;
  border: 0.1rem solid #232323;
  background: #232323;
  color: #ffffff;
  font-family: 'KaiseiOpti-Bold';
  font-size: 1.6rem;
  cursor: pointer;

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}

.verification-dialog__resend {
  margin: 2rem auto 0;
  display: block;
  border: none;
  padding: 0;
  background: transparent;
  color: #7c7c7c;
  font-family: 'KaiseiOpti-Regular';
  font-size: 1.6rem;
  line-height: 1.6;
  text-decoration: underline;
  text-underline-offset: 0.2rem;
  cursor: pointer;

  &:disabled {
    cursor: default;
    opacity: 0.85;
  }
}
</style>
