/*
  Модуль модальных диалогов для оператора (проект BEAST).

  Назначение:
  - Заменяет стандартные alert/confirm/prompt собственными модальными окнами.
  - Обеспечивает единый стиль и управление диалогами для интерфейса оператора.
  - Используется для интерактивного общения системы с оператором.

  Доступные функции (глобальные):
  - show_alert(message, timeShow = 0)
      Показать информационное сообщение.
      message  – HTML‑строка с текстом сообщения.
      timeShow – время автозакрытия в миллисекундах (0 – без автозакрытия).

  - show_confirm(message, callBack)
      Показать диалог подтверждения с кнопками "Да" / "Нет".
      message  – HTML‑строка с текстом вопроса.
      callBack – функция(result), куда передаётся 'OK' или 'NO'.

  - show_prompt(message, callBack)
      Показать диалог ввода текста.
      message  – HTML‑строка с поясняющим текстом.
      callBack – функция(value), вызывается только при подтверждении ввода.

  - close_alert()
      Принудительно закрыть активный диалог.

  Примеры использования см. в файле beast/sys/alerts/samples.htm.
*/

(function (global) {
  'use strict';

  // Глобальные переменные для отслеживания активного диалога и таймера автозакрытия
  var activeDialog = null;
  var closeTimeout = null;
  var activeOnClose = null;
  var lastCloseUserInitiated = false;

  /**
   * Создать (или вернуть уже существующий) затемняющий слой под диалогом.
   * @returns {HTMLElement}
   */
  function createOverlay() {
    var overlay = document.getElementById('alert-overlay');
    if (!overlay) {
      overlay = document.createElement('div');
      overlay.id = 'alert-overlay';
      overlay.style.cssText =
        'position:fixed;top:0;left:0;width:100%;height:100%;' +
        'background-color:rgba(0,0,0,0.5);z-index:9998;display:none;' +
        'cursor:pointer;margin:0;padding:0;';
      document.body.appendChild(overlay);

      // Закрытие при щелчке по фону (кроме простого alert)
      overlay.addEventListener('click', function () {
        if (activeDialog && activeDialog.dataset.type !== 'alert') {
          closeDialog();
        }
      });
    }
    return overlay;
  }

  /**
   * Создать структуру диалога.
   * @param {string} type - тип диалога: 'alert' | 'confirm' | 'prompt'
   * @returns {HTMLElement}
   */
  function createDialog(type) {
    // Закрываем существующий диалог, если он есть
    if (activeDialog) {
      closeDialog();
    }

    var dialog = document.createElement('div');
    dialog.className = 'alert-dialog';
    dialog.dataset.type = type;
    dialog.style.cssText =
      'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);' +
      'z-index:9999;background-color:#ffffff;border-radius:8px;' +
      'box-shadow:0 4px 12px rgba(0,0,0,0.25);padding:20px;padding-top:40px;' +
      'max-width:90%;max-height:90vh;overflow:auto;' +
      'font-family:Arial,sans-serif;font-size:12pt;text-align:left;' +
      'box-sizing:border-box;margin:0;';

    // Кнопка закрытия в правом верхнем углу
    var closeButton = document.createElement('button');
    closeButton.className = 'alert-close';
    closeButton.innerHTML = '&times;';
    closeButton.setAttribute('aria-label', 'Закрыть');
    closeButton.style.cssText =
      'position:absolute;top:0;right:0;background-color:#f5f5f5;' +
      'border:1px solid #ddd;border-radius:0 8px 0 0;font-size:20px;' +
      'color:#666;cursor:pointer;padding:0;margin:0;width:32px;height:32px;' +
      'display:flex;align-items:center;justify-content:center;z-index:10000;' +
      'box-sizing:border-box;';
    closeButton.addEventListener('mouseenter', function () {
      closeButton.style.backgroundColor = '#e0e0e0';
      closeButton.style.color = '#000';
      closeButton.style.borderColor = '#ccc';
    });
    closeButton.addEventListener('mouseleave', function () {
      closeButton.style.backgroundColor = '#f5f5f5';
      closeButton.style.color = '#666';
      closeButton.style.borderColor = '#ddd';
    });
    closeButton.addEventListener('click', function (e) {
      e.stopPropagation();
      lastCloseUserInitiated = true;
      closeDialog();
    });
    dialog.appendChild(closeButton);

    // Контейнер для текста сообщения
    var messageContainer = document.createElement('div');
    messageContainer.className = 'alert-message';
    messageContainer.style.cssText =
      'margin-bottom:15px;line-height:1.4;word-wrap:break-word;margin-top:0;';
    dialog.appendChild(messageContainer);

    document.body.appendChild(dialog);
    activeDialog = dialog;

    return dialog;
  }

  /**
   * Закрыть текущий диалог и скрыть фон.
   */
  function closeDialog() {
    if (closeTimeout) {
      clearTimeout(closeTimeout);
      closeTimeout = null;
    }

    if (activeDialog) {
      if (activeDialog.parentNode) {
        activeDialog.parentNode.removeChild(activeDialog);
      }
      activeDialog = null;
    }

    if (typeof activeOnClose === 'function') {
      try { activeOnClose({ userInitiated: !!lastCloseUserInitiated }); } catch (e) {}
    }
    activeOnClose = null;
    lastCloseUserInitiated = false;

    var overlay = document.getElementById('alert-overlay');
    if (overlay) {
      overlay.style.display = 'none';
    }
  }

  /**
   * Публичная функция: показать информационный диалог.
   * @param {string} message - HTML‑сообщение.
   * @param {number} [timeShow=0] - время автозакрытия в миллисекундах (0 – без автозакрытия).
   */
  function show_alert(message, timeShow) {
    if (typeof timeShow === 'undefined') {
      timeShow = 0;
    }
    var opts = arguments.length >= 3 ? arguments[2] : null;
    if (typeof opts === 'function') {
      opts = { onClose: opts };
    }
    if (!opts || typeof opts !== 'object') opts = {};
    var dialogType = opts.dialogType || 'alert';

    // Не перетираем "чужие" модалки (confirm/prompt/alert), если пытаемся показать cyclelog.
    if (dialogType === 'cyclelog' && activeDialog && activeDialog.dataset && activeDialog.dataset.type !== 'cyclelog') {
      return;
    }

    var dialog = createDialog(dialogType);
    activeOnClose = (typeof opts.onClose === 'function') ? opts.onClose : null;
    dialog.querySelector('.alert-message').innerHTML = message;

    // Если нет автозакрытия – добавляем кнопку "Закрыть"
    if (timeShow === 0) {
      var buttonsContainer = document.createElement('div');
      buttonsContainer.className = 'alert-buttons';
      buttonsContainer.style.cssText =
        'display:flex;justify-content:flex-end;gap:10px;margin-top:15px;';

      var closeButton = document.createElement('button');
      closeButton.className = 'alert-button alert-button-close';
      closeButton.textContent = 'Закрыть';
      closeButton.style.cssText =
        'padding:8px 16px;border:none;border-radius:4px;font-size:12pt;' +
        'cursor:pointer;min-width:80px;background-color:#2196F3;color:white;';
      closeButton.addEventListener('mouseenter', function () {
        closeButton.style.backgroundColor = '#0b7dda';
      });
      closeButton.addEventListener('mouseleave', function () {
        closeButton.style.backgroundColor = '#2196F3';
      });
      closeButton.addEventListener('click', function () {
        lastCloseUserInitiated = true;
        closeDialog();
      });

      buttonsContainer.appendChild(closeButton);
      dialog.appendChild(buttonsContainer);
    }

    // Автозакрытие, если указано положительное время
    if (timeShow > 0) {
      closeTimeout = global.setTimeout(closeDialog, timeShow);
    }
  }

  // Служебные экспортируемые хелперы: чтобы лог цикла не перетирал другие диалоги.
  function getActiveDialogType() {
    return activeDialog && activeDialog.dataset ? (activeDialog.dataset.type || null) : null;
  }
  global.Alert_getActiveDialogType = getActiveDialogType;

  /**
   * Публичная функция: показать диалог подтверждения.
   * @param {string} message - HTML‑сообщение.
   * @param {function(string)} callBack - обработчик результата ('OK' или 'NO').
   */
  function show_confirm(message, callBack) {
    var overlay = createOverlay();
    overlay.style.display = 'block';

    var dialog = createDialog('confirm');
    dialog.querySelector('.alert-message').innerHTML = message;

    var buttonsContainer = document.createElement('div');
    buttonsContainer.className = 'alert-buttons';
    buttonsContainer.style.cssText =
      'display:flex;justify-content:flex-end;gap:10px;margin-top:15px;';

    // Кнопка "Нет"
    var noButton = document.createElement('button');
    noButton.className = 'alert-button alert-button-no';
    noButton.textContent = 'Нет';
    noButton.style.cssText =
      'padding:8px 16px;border:none;border-radius:4px;font-size:12pt;' +
      'cursor:pointer;min-width:80px;background-color:#f44336;color:white;';
    noButton.addEventListener('mouseenter', function () {
      noButton.style.backgroundColor = '#da190b';
    });
    noButton.addEventListener('mouseleave', function () {
      noButton.style.backgroundColor = '#f44336';
    });
    noButton.addEventListener('click', function () {
      closeDialog();
      if (typeof callBack === 'function') {
        callBack('NO');
      }
    });

    // Кнопка "Да"
    var okButton = document.createElement('button');
    okButton.className = 'alert-button alert-button-ok';
    okButton.textContent = 'Да';
    okButton.style.cssText =
      'padding:8px 16px;border:none;border-radius:4px;font-size:12pt;' +
      'cursor:pointer;min-width:80px;background-color:#4CAF50;color:white;';
    okButton.addEventListener('mouseenter', function () {
      okButton.style.backgroundColor = '#45a049';
    });
    okButton.addEventListener('mouseleave', function () {
      okButton.style.backgroundColor = '#4CAF50';
    });
    okButton.addEventListener('click', function () {
      closeDialog();
      if (typeof callBack === 'function') {
        callBack('OK');
      }
    });

    buttonsContainer.appendChild(noButton);
    buttonsContainer.appendChild(okButton);
    dialog.appendChild(buttonsContainer);

    // Поддержка клавиши Escape для отмены
    var escHandler = function (e) {
      if (e.key === 'Escape' && activeDialog && activeDialog.dataset.type === 'confirm') {
        closeDialog();
        global.document.removeEventListener('keydown', escHandler);
      }
    };
    global.document.addEventListener('keydown', escHandler);
  }

  /**
   * Публичная функция: показать диалог ввода текста.
   * @param {string} message - HTML‑сообщение.
   * @param {function(string)} callBack - обработчик введённого значения.
   */
  function show_prompt(message, callBack) {
    var overlay = createOverlay();
    overlay.style.display = 'block';

    var dialog = createDialog('prompt');
    dialog.querySelector('.alert-message').innerHTML = message;

    // Поле ввода
    var input = document.createElement('input');
    input.className = 'alert-prompt-input';
    input.type = 'text';
    input.autofocus = true;
    input.style.cssText =
      'width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;' +
      'font-size:12pt;box-sizing:border-box;margin-bottom:15px;';
    dialog.appendChild(input);

    var buttonsContainer = document.createElement('div');
    buttonsContainer.className = 'alert-buttons';
    buttonsContainer.style.cssText =
      'display:flex;justify-content:flex-end;gap:10px;margin-top:15px;';

    // Кнопка "Отмена"
    var cancelButton = document.createElement('button');
    cancelButton.className = 'alert-button alert-button-cancel';
    cancelButton.textContent = 'Отмена';
    cancelButton.style.cssText =
      'padding:8px 16px;border:none;border-radius:4px;font-size:12pt;' +
      'cursor:pointer;min-width:80px;background-color:#9e9e9e;color:white;';
    cancelButton.addEventListener('mouseenter', function () {
      cancelButton.style.backgroundColor = '#888888';
    });
    cancelButton.addEventListener('mouseleave', function () {
      cancelButton.style.backgroundColor = '#9e9e9e';
    });
    cancelButton.addEventListener('click', function () {
      closeDialog();
      // При отмене callback не вызывается
    });

    // Кнопка "OK"
    var okButton = document.createElement('button');
    okButton.className = 'alert-button alert-button-ok';
    okButton.textContent = 'OK';
    okButton.style.cssText =
      'padding:8px 16px;border:none;border-radius:4px;font-size:12pt;' +
      'cursor:pointer;min-width:80px;background-color:#4CAF50;color:white;';
    okButton.addEventListener('mouseenter', function () {
      okButton.style.backgroundColor = '#45a049';
    });
    okButton.addEventListener('mouseleave', function () {
      okButton.style.backgroundColor = '#4CAF50';
    });
    okButton.addEventListener('click', function () {
      var value = input.value;
      closeDialog();
      if (typeof callBack === 'function' && value !== '') {
        callBack(value);
      }
    });

    // Поддержка Enter в поле ввода
    input.addEventListener('keypress', function (e) {
      if (e.key === 'Enter') {
        okButton.click();
      }
    });

    buttonsContainer.appendChild(cancelButton);
    buttonsContainer.appendChild(okButton);
    dialog.appendChild(buttonsContainer);

    // Поддержка Escape для отмены
    var escHandler = function (e) {
      if (e.key === 'Escape' && activeDialog && activeDialog.dataset.type === 'prompt') {
        closeDialog();
        global.document.removeEventListener('keydown', escHandler);
      }
    };
    global.document.addEventListener('keydown', escHandler);
  }

  /**
   * Публичная функция: принудительно закрыть активный диалог.
   */
  function close_alert() {
    closeDialog();
  }

  // Экспорт функций в глобальное пространство имён
  global.show_alert = show_alert;
  global.show_confirm = show_confirm;
  global.show_prompt = show_prompt;
  global.close_alert = close_alert;
})(window);

