<template>
  <q-dialog class="full-width" v-model="showConfirmActiveModalBoolean">
    <q-card class="no-shadow">
      <q-card-section>
        <div class="text-h6">Подтвердите действие</div>
      </q-card-section>
      <q-card-section class="q-pt-none">
        После нажатия на кнопку, вы продолжите работать в прежнем режиме
      </q-card-section>
      <q-card-actions align="right" class="q-pr-md q-pl-md q-pb-md q-pt-none">
        <q-btn
          color="white"
          text-color="primary"
          outline
          @click="continueSession()"
          label="Продолжить сессию"
        />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

// берем значение из appConfig, если его нет то ставим 4 мин 30 сек
let timeBeforeReload = 270000;
if (
  Vue.prototype.$appConfig.TIME_ACTIVE_SESSION_MS &&
  !isNaN(Vue.prototype.$appConfig.TIME_ACTIVE_SESSION_MS)
) {
  timeBeforeReload = Number(Vue.prototype.$appConfig.TIME_ACTIVE_SESSION_MS);
}

@Component({})
export default class ConfirmActiveModal extends Vue {
  // Переменная для хранения состояния показываем ли мы уведомление
  // сделана числом, чтобы в setinterval прождать на 1 цикл больше и не плодить еще settimeout
  private showConfirmActiveModal = 0;

  mounted(): void {
    this.startCheckActivityUser();
  }

  // переменная для хранения интервала
  private interval15sec: ReturnType<typeof setTimeout> | undefined;

  /*
   * Функция проверки активности пользователя
   * Если пользователь не активен 270 сек (4 мин 30 сек)
   * То показываем окно и если нет подтверждения то делаем logaut
   */
  startCheckActivityUser(): void {
    // при первом открытии ставим текущее время как последнее активное у пользователя
    this.updateLastActiveTime();

    // слушатели событий для обновления времени
    document.addEventListener('mousemove', this.updateLastActiveTime);
    document.addEventListener('scroll', this.updateLastActiveTime);
    document.addEventListener('keypress', this.updateLastActiveTime);

    // слушатель изменения localstorage
    window.addEventListener('storage', this.closeConfirmActiveModal);

    // проверяем если открывается новое окно и запущена модалка
    if (localStorage.getItem('showConfirmActiveModal')) {
      // то закрываем модалку на других вкладках
      localStorage.removeItem('showConfirmActiveModal');
    }

    /*
     * Функция ожидания просрочки времени
     * по умолчанию timeBeforeReload - 270000 - 270 сек - 4 мин 30 сек
     */
    this.interval15sec = setInterval(() => {
      // Ждем когда таймер пойдет 2 раз, так как модалка с текстом должна крутится 30 сек
      // погрешность состовляет 14 сек
      if (this.showConfirmActiveModal) {
        if (this.showConfirmActiveModal > 1) {
          this.$emit('logAuth');
          localStorage.removeItem('showConfirmActiveModal');
        } else {
          this.showConfirmActiveModal++;
        }
      } else if (
        !localStorage.getItem('lastActiveTime') ||
        Number(localStorage.getItem('lastActiveTime')) + timeBeforeReload <
          Number(new Date())
      ) {
        localStorage.setItem('showConfirmActiveModal', 'true');
        this.showConfirmActiveModal++;
      }
    }, 15000);
  }

  /*
   * Функция закрытия модалки через флаг localstorage showConfirmActiveModal при обнулении value
   */
  closeConfirmActiveModal(event: StorageEvent): void {
    if (
      (event.key === 'showConfirmActiveModal' && !event.newValue) ||
      event.key === null
    ) {
      this.showConfirmActiveModal = 0;
    }
  }

  // переменная задержки в 2 сек чтобы ограничить нагрузку на изменение localStorage
  saveDateInLocalStorage = false;

  /*
   * Функция обновления последнего времени актива в localStorage
   * saveDateInLocalStorage - переменная ограничивающая перезапись в localStorage, чтобы снизить загрузку
   */
  updateLastActiveTime(): void {
    if (this.saveDateInLocalStorage) return;
    this.saveDateInLocalStorage = true;
    localStorage.setItem('lastActiveTime', String(Number(new Date())));
    setTimeout(() => {
      this.saveDateInLocalStorage = false;
    }, 2000);
  }

  /*
   * Функция продолжения сессии
   */
  continueSession(): void {
    this.showConfirmActiveModal = 0;
    localStorage.removeItem('showConfirmActiveModal');
  }

  /*
   * Computed для хранения boolean состояния показываем ли мы уведомление
   */
  get showConfirmActiveModalBoolean(): boolean {
    return !!this.showConfirmActiveModal;
  }

  /*
   * Очищаем все слушатели и интервал
   */
  beforeDestroy(): void {
    document.removeEventListener('mousemove', this.updateLastActiveTime);
    document.removeEventListener('scroll', this.updateLastActiveTime);
    document.removeEventListener('keypress', this.updateLastActiveTime);

    window.removeEventListener('storage', this.updateLastActiveTime);

    if (this.interval15sec) {
      clearInterval(this.interval15sec);
    }
  }
}
</script>
