{% block css %}
<link type="text/css" rel="stylesheet" href="/css/account.css">
<link type="text/css" rel="stylesheet" href="/css/icons/arrow_right.css">
<link type="text/css" rel="stylesheet" href="/css/icons/nametag.css">
<link type="text/css" rel="stylesheet" href="/css/icons/keyhole.css">
<link type="text/css" rel="stylesheet" href="/css/icons/user_add.css">
{% endblock %}

{% block body %}
<section id="entry" class="panel medium snow">
	<section class="header unselectable">
		<h1>Идентификация</h1>
	</section>
	<section class="body">
		<iframe name="void" style="display:none"></iframe>
		<form id="identification" method="POST" action="/entry" target="void" autocomplete="on" novalidate="true">
			<label id="operator" form="identification" for="_operator">
				<i class="icon nametag"></i>
				<input id="_operator" class="stretched merged right snow borderless" name="operator" type="text" placeholder="Идентификатор оператора" list="operators"
					value="{{ session.buffer.entry.operator._key ?? cookie.buffer_entry_operator__key }}"
					onkeypress="if (event.keyCode === 13) this.nextElementSibling.click()" autocomplete="username"
					autofocus="true">
				<button type="submit" class="clay merged left" onclick="__operator(); return false"><i class="icon arrow right"></i></button>
				<datalist id="operators">
					{% for account in accounts %}
					<option value="{{ account.getKey() }}">{{ account.getKey() }} {{ account.name.first }} {{ account.name.second }}</option>
					{% endfor %}
				</datalist>
			</label>
			<label id="password" class="hidden" form="identification" for="_password">
				<i class="icon keyhole"></i>
				<input id="_password" class="stretched merged right snow borderless" name="password" type="password" placeholder="Пароль"
					onkeypress="if (event.keyCode === 13) this.nextElementSibling.click()" autocomplete="current-password">
				<button type="submit" class="clay merged left" onclick="__password()"><i class="icon arrow right"></i></button>
			</label>
		</form>

	</section>
</section>
<section id="errors" class="panel medium animation window hidden snow" style="--height: 300px">
	<section class="body">
		<dl></dl>
	</section>
</section>
<script>
  // Инициализация функций в глобальной области видимости
  let _operator, __operator, _password, __password, _errors, balls, trash;

  document.addEventListener('damper.initialized', function (e) {
    // Инициализирован демпфер

		// Защита от вызова на других страницах
		if (trash) return;

    // Инициализация HTML-элемента с блоком входа в аккаунт
    const entry = {wrap: document.getElementById('entry')};
    entry.title = entry.wrap.getElementsByTagName('h1')[0];

    // Инициализация HTML-элемента с блоком ошибок
    const errors = {wrap: document.getElementById('errors')};
    errors.list = errors.wrap.getElementsByTagName('dl')[0];

    // Инициализация HTML-элементов-оболочек полей ввода
    const fields = {
      operator: {label: document.getElementById('operator')},
      password: {label: document.getElementById('password')},
    };
    fields.operator.input = fields.operator.label.getElementsByTagName('input')[0];
    fields.password.input = fields.password.label.getElementsByTagName('input')[0];
    fields.operator.button = fields.operator.label.getElementsByTagName('button')[0];
    fields.password.button = fields.password.label.getElementsByTagName('button')[0];

		// Инициализация маски идентификатора оператора
		fields.operator.input.mask = IMask(fields.operator.input, {mask: '000000000000'});

    /**
     * Отправить входной псевдоним на сервер
     *
     * @return {void}
     */
    _operator = async () => {
      // Деинициализация индикатора и анимации об ошибке
      fields.operator.input.classList.remove('error');
      fields.operator.input.previousElementSibling.classList.remove('error');

			// Инициализация функции разблокировки
			function unblock() {
        // Разблокировка поля ввода
        fields.operator.input.removeAttribute('readonly');
        fields.operator.button.removeAttribute('disabled');

        // Инициализация отображения ошибки
        fields.operator.input.classList.add('error');
        fields.operator.input.previousElementSibling.classList.add('error');

        // Фокусировка на поле ввода
        fields.operator.input.focus();
			}

			// Запуск отсрочки разблокировки на случай, если сервер не отвечает
			const timeout = setTimeout(() => {_errors(['Сервер не отвечает']); unblock()}, 5000);

      // Запрос к серверу
      const response = await session.operator(fields.operator.input.value);

			// Удаление отсрочки разблокировки
			clearTimeout(timeout);

      if (_errors(response.errors)) {
        // Сгенерированы ошибки

        // Разблокировка
			  unblock();
      } else {
        // Не сгенерированы ошибки (подразумевается их отсутствие)

        // Деинициализация интерфейса идентификации
        fields.operator.label.classList.add('hidden');

        // Инициализация интерфейса аутентификации
        entry.title.innerText = 'Аутентификация';
        fields.password.label.classList.remove('hidden');
        fields.password.input.focus();
      }
		};

    /**
     * Отправить входной псевдоним на сервер с дополнительной подготовкой
     *
     * @return {void}
     */
    __operator = e.detail.damper(async () => {
      // Блокировка поля ввода
      fields.operator.input.setAttribute('readonly', true);
      fields.operator.button.setAttribute('disabled', true);

      // Реинициализация блока ошибок
      _errors();

      // Запуск процесса отправки входного псевдонима
      _operator();
    }, 1000);

    /**
     * Отправить пароль на сервер
     *
     * @return {void}
     */
    _password = async () => {
      // Деинициализация индикатора и анимации об ошибке
      fields.password.input.classList.remove('error');
      fields.password.input.previousElementSibling.classList.remove('error');

			// Инициализация функции разблокировки
			function unblock() {
        // Разблокировка поля ввода
        fields.password.input.removeAttribute('readonly');
        fields.password.button.removeAttribute('disabled');

        // Инициализация отображения ошибки
        fields.password.input.classList.add('error');
        fields.password.input.previousElementSibling.classList.add('error');

        // Фокусировка на поле ввода
        fields.password.input.focus();
			}

			// Запуск отсрочки разблокировки на случай, если сервер не отвечает
			const timeout = setTimeout(() => {_errors(['Сервер не отвечает']); unblock()}, 5000);

      // Запрос к серверу
      const response = await session.password(fields.password.input.value);

			// Удаление отсрочки разблокировки
			clearTimeout(timeout);

      if (_errors(response.errors) || response.verify !== true) {
        // Сгенерированы ошибки

        // Разблокировка
				unblock();
      } else {
        // Не сгенерированы ошибки (подразумевается их отсутствие)

        if (response.account) {
          // Инициализирован аккаунт

					if (typeof loader === 'function') {
						// Initialized the loader class

						// Отметить данный HTML-элемент с JS-кодом в очередь на очистку?
						trash = true;

						// Деинициализация неактуального CSS-документа
						document.head.querySelector('link[href="/css/account.css"]').remove();

						// Инициализация главной страницы
						loader.index();
						loader.menu();
					}
        }
      }
		};

    /**
     * Отправить пароль на сервер с дополнительной подготовкой
     *
     * @return {void}
     */
    __password = e.detail.damper(async () => {
      // Блокировка поля ввода
      fields.password.input.setAttribute('readonly', true);
      fields.password.button.setAttribute('disabled', true);

      // Реинициализация блока ошибок
      _errors();

      // Запуск процесса отправки входного псевдонима
      _password();
    }, 100)

    /**
     * Сгенерировать HTML-элемент с блоком ошибок
     *
     * @param {object} registry Реестр ошибок
     * @param {bool} reinitialization Реинициализировать?
     *
     * @return {bool} Сгенерированы ошибки?
     */
    _errors = (registry, reinitialization = true) => {
      function height() {
        // Скрытие HTML-элемента
        errors.wrap.style.zIndex = '-99999';
        errors.wrap.style.left = '-99999px';
        errors.wrap.style.top = '-99999px';
        errors.wrap.style.position = 'absolute';
        errors.wrap.style.display = 'var(--display, unset)';
        errors.wrap.style.opacity = '0';
        errors.wrap.style.animationName = 'unset';

        // Реинициализация переменной с данными о высоте HTML-элемента
        errors.wrap.style.setProperty('--height', errors.wrap.offsetHeight + 'px');

        // Отмена скрытия HTML-элемента
        errors.wrap.style.zIndex =
          errors.wrap.style.left =
          errors.wrap.style.top =
          errors.wrap.style.position =
          errors.wrap.style.display =
          errors.wrap.style.opacity =
          errors.wrap.style.animationName = null;
      }

      // Удаление ошибок из прошлой генерации
      if (reinitialization) errors.list.innerHTML = null;

      for (error in registry) {
        // Генерация HTML-элементов с текстами ошибок

        // Инициализация HTML-элемента текста ошибки
        const samp = document.createElement('samp');

        if (typeof registry[error] === 'object') {
          // Категория ошибок

          // Проверка наличия ошибок
          if (registry[error].length === 0) continue;

          // Инициализация HTML-элемента-оболочки
          const wrap = document.createElement('dt');

          // Запись текста категории
          samp.innerText = error;

          // Запись HTML-элементов в список
          wrap.appendChild(samp);
          errors.list.appendChild(wrap);

          // Реинициализация высоты
          height();

          // Обработка вложенных ошибок (вход в рекурсию)
          _errors(registry[error], false);
        } else {
          // Текст ошибки (подразумевается)

          // Инициализация HTML-элемента
          const wrap = document.createElement('dd');

          // Запись текста ошибки
          samp.innerText = registry[error];

          // Запись HTML-элемента в список
          wrap.appendChild(samp);
          errors.list.appendChild(wrap);

          // Реинициализация высоты
          height();
        }
      }

      // Реинициализация HTML-элемента с текстом ошибок
      if (reinitialization && errors.list.childElementCount === 0) errors.wrap.classList.add('hidden');
      else errors.wrap.classList.remove('hidden');

      return errors.list.childElementCount === 0 ? false : true;
    };
  });
</script>
{% endblock %}

{% block js %}
<script type="text/javascript" src="/js/session.js"></script>
<script type="text/javascript" src="/js/loader.js"></script>
<script type="text/javascript" src="/js/imask-7.1.0-alpha.js"></script>
{% endblock %}
