<template>
  <q-page class="flex flex-center bg-grey-3">
    <q-card style="width: 300px">
      <!-- лого -->
      <div v-if="props.logo" style="margin-top: -50px" class="text-center">
        <q-avatar class="shadow-2 bg-white" size="100px">
          <img :src="props.logo" />
        </q-avatar>
      </div>

      <!-- вход по email -->
      <q-card-section>
        <q-form @submit="codeSubmit" autocomplete="on">
          <div class="q-mb-md text-center">
            {{ t`Код надіслано на` }}
            <span class="text-bold">{{ email }}</span>
          </div>

          <q-input
            v-model="code"
            @focus="input => input.target.select()"
            class="num-code"
            mask="#  #  #  #"
            oncontextmenu="return false"
            autocomplete="one-time-code"
            input-style="font-size: 25px; text-align: center"
            outlined
            unmasked-value
            fill-mask
            autofocus />

          <div v-if="!errorText" class="text-center text-grey q-mt-md">
            {{ t`час до закінчення дії коду` }}: {{ time }}
          </div>
          <div v-else class="text-white text-red bg-red-1 q-pa-xs q-mt-md text-center">{{ errorText }}</div>

          <q-btn
            v-if="code && code.length === 4"
            type="submit"
            :label="t`Увійти`"
            class="full-width q-mt-md"
            :loading="checkInProgress"
            padding="md"
            color="primary" />

          <q-btn
            to="/login"
            :label="t`Повернутись назад`"
            icon="keyboard_backspace"
            class="full-width q-mt-md"
            padding="sm"
            color="primary"
            flat
            no-caps />
        </q-form>
      </q-card-section>
    </q-card>
  </q-page>
</template>

<script setup>
import tfm from '@nitra/tfm'
import { autoLogin, checkToken, defaultLogin } from '@nitra/vite-boot/token'
import { date } from 'quasar'
import { onBeforeMount, onUnmounted, ref, watch } from 'vue'

// Чи потрібен мультимовний варіант
const props = defineProps({
  logo: {
    type: String,
    default: 'https://cdn.jsdelivr.net/npm/@nitra/auth-components@2/assets/logo.jpeg'
  }
})

const baseUrl = import.meta.env.BASE_URL

// const router = useRouter()

// Авто авторизація якщо у користувача є коректний токен
autoLogin()

const t = tfm.bind({ tr: getTr() })

const code = ref(null)
const errorText = ref('')
let intervalId = 0
let email = localStorage.getItem('email')
let otpDate = new Date(localStorage.getItem('email-otp-date'))
const checkInProgress = ref(false)
const time = ref('29:59')

// отправка кода
const codeSubmit = async () => {
  if (new Date() > otpDate) {
    errorText.value = t`Час очікування закінчився. Запросіть новий код`
    stopTimer()
    return
  }

  try {
    checkInProgress.value = true

    const response = await fetch(`${baseUrl}auth/otp-code`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        email,
        code: code.value
      })
    })

    const res = await response.json()

    if (res.token) {
      const check = checkToken(res.token)
      if (check.result === 'ok') {
        await defaultLogin(check.decoded, res.token)
      } else {
        errorText.value = t`Користувачу ${localStorage.getItem(
          'email'
        )} не дозволено входити в дане програмне забезпечення`
      }
    } else {
      errorText.value = t`Невірний код!`
    }
  } catch (error) {
    errorText.value = error.message
  } finally {
    checkInProgress.value = false
  }
}

watch(code, (code, _prevCode) => {
  // Якщо введено 4 цифри не чекаємо коли користувач натисне Enter
  if (code.length === 4) {
    codeSubmit()
  }
})

// обновление данных таймера
const updateTimerData = timer => {
  let minutes = parseInt(timer / 60, 10)
  let seconds = parseInt(timer % 60, 10)
  minutes = minutes < 10 ? '0' + minutes : minutes
  seconds = seconds < 10 ? '0' + seconds : seconds
  time.value = `${minutes}:${seconds}`
}

// очистить таймер
const stopTimer = () => {
  clearInterval(intervalId)
  localStorage.removeItem('email-otp-date')
}

// запускаем таймер
onBeforeMount(() => {
  // Якщо передано код автовходу
  if (globalThis.location.search.length) {
    try {
      const jsonString = atob(globalThis.location.search.slice(3))
      const { e, c } = JSON.parse(jsonString)
      if (e && c) {
        email = e
        code.value = c
        otpDate = date.addToDate(new Date(), { minutes: 30 })
        codeSubmit()
      }
    } catch (error) {
      console.error(error)
    }
  }

  let timer = Math.round((otpDate - Date.now()) / 1000)
  updateTimerData(timer)
  --timer
  intervalId = setInterval(() => {
    updateTimerData(timer)
    if (--timer < 0) {
      window.close()
      // router.push('/login')
    }
  }, 1000)
})

// очищаем таймер
onUnmounted(() => {
  stopTimer()
})

/**
 * LOCALIZATION
 * @returns {object} translations
 */
function getTr() {
  return {
    'час до закінчення дії коду': { ru: 'время до окончания действия кода' },
    'Код надіслано на': { ru: 'Код отправлен на' },
    Увійти: { ru: 'Войти' },
    'Повернутись назад': { ru: 'Вернуться назад' },
    'Час очікування закінчився. Запросіть новий код': { ru: 'Время ожидания истекло. Запросите новый код' },
    'Невірний код!': { ru: 'Неверный код!' },
    'Користувачу ': { ru: 'Пользователю ' },
    ' не дозволено входити в дане програмне забезпечення': { ru: ' не разрешено входить в данное приложение' }
  }
}
</script>
