/**
 * Центральный пульс системы существа Beast.
 *
 * Назначение:
 * - Обеспечивает базовый "сердечный" ритм существа с периодом 1 секунда.
 * - Поддерживает глобальную переменную window.Cur_puls_val — количество
 *   пульсов с начала жизни существа (а не запуска index.html).
 * - Обновляет визуальный индикатор пульса на главной странице index.html:
 *   мигающий зелёный кружок и числовой счётчик пульсов.
 *
 * Взаимодействие с интерфейсом:
 * - В index.html должны присутствовать элементы с id "pulseCircle" и "pulseCounter".
 * - Функция update_beast_pulse_view() может вызываться другими модулями,
 *   если им нужно принудительно обновить отображение (например, после
 *   загрузки сохранённого значения Cur_puls_val).
 *
 * Хранение пульса между запусками:
 * - Значение Cur_puls_val периодически сохраняется в localStorage под ключом 'Cur_puls_val'.
 */
(function (global) {
  'use strict';

  var PULSE_KEY = 'Cur_puls_val';

  // Инициализация глобальной переменной Cur_puls_val из localStorage
  var saved = 0;
  try {
    var raw = global.localStorage.getItem(PULSE_KEY);
    if (raw !== null) {
      var n = parseInt(raw, 10);
      if (!isNaN(n) && n >= 0) {
        saved = n;
      }
    }
  } catch (e) {
    saved = 0;
  }

  global.Cur_puls_val = saved;

  /** Локальный счётчик пульсов (нарастает с каждым пульсом), передаётся в getActiveBasicContexts. */
  global.cpuls = 0;

  var pulseCircle = null;
  var pulseCounterEl = null;

  /**
   * Обновление ссылок на DOM-элементы индикатора пульса.
   * Вызывается при первом обновлении отображения.
   */
  function ensure_dom_refs() {
    if (!pulseCircle) {
      pulseCircle = global.document.getElementById('pulseCircle');
    }
    if (!pulseCounterEl) {
      pulseCounterEl = global.document.getElementById('pulseCounter');
    }
  }

  /**
   * Обновить отображение текущего значения пульса на странице.
   * Экспортируется как глобальная функция update_beast_pulse_view.
   */
  function update_beast_pulse_view() {
    ensure_dom_refs();
    if (pulseCounterEl) {
      pulseCounterEl.textContent = String(global.Cur_puls_val);
    }
  }

  // Глобальный пульс: используется sep_of_puls() — один цикл с учётом времени записи в IndexedDB и голубой индикацией.
  var isOn = true;
  update_beast_pulse_view();

  global.update_beast_pulse_view = update_beast_pulse_view;

  function sep_of_puls() {
    var startTime = Date.now();
    try {
      if (typeof global.getDiffImportance === 'function') {
        global.PrevDiffForEpisode = global.getDiffImportance();
      }
      if (typeof global.runIndexedDBSavesForPulse === 'function') {
        global.runIndexedDBSavesForPulse();
      }

      if (global.Cur_puls_val === 0) {
        // начальная загрузка данных из IndexedDB
      }

      global.Cur_puls_val += 1;
      update_beast_pulse_view();
      try {
        global.localStorage.setItem(PULSE_KEY, String(global.Cur_puls_val));
      } catch (e) {}

      if (typeof global.EpisodicMemory_onPulse === 'function') {
        global.EpisodicMemory_onPulse();
      }

      if (typeof global.performSensorOperations === 'function') {
        global.performSensorOperations();
      }
      global.cpuls++;
      if (typeof global.getActiveBasicContexts === 'function') {
        global.getActiveBasicContexts(global.cpuls);
      }
      if (typeof global.update_basic_contexts_view === 'function') {
        global.update_basic_contexts_view();
      }
      if (typeof global.PerceptionTree_updateActiveBranchView === 'function') {
        global.PerceptionTree_updateActiveBranchView();
      }
      // Синхронизируем Base/Emotion/Activity инфокартины с текущей веткой дерева.
      if (typeof global.Info_updateFromPerceptionTree === 'function') {
        global.Info_updateFromPerceptionTree();
      }
      // Бордеры «готовности к ОР»: полный пересчёт только при смене BadNormWell / эмоции / ID ветки
      // (см. stimuls_ui.scheduleStimulusReadinessRefreshIfNeeded). Иначе точечно — в semantic_memory.js.
      if (typeof global.scheduleStimulusReadinessRefreshIfNeeded === 'function') {
        global.scheduleStimulusReadinessRefreshIfNeeded();
      }
      if (typeof global.SleepMode_refreshStimulusButtonVisuals === 'function') {
        global.SleepMode_refreshStimulusButtonVisuals();
      }
      // Сон: машина сновидений (очередь пустых кадров ЭП) — до шага ФО, чтобы в этом же пульсе dispetchConsciousnessThinking
      // отработал соновой пассивный главный цикл после onPulse.
      if (typeof global.SleepDreams_onPulse === 'function') {
        global.SleepDreams_onPulse(global.cpuls);
      }
      // В пассивном режиме: семантическая обработка моделей понимания; в ходе неё возникают новые образы ситуаций на будущее.
      var passiveMain = typeof global.Consciousness_getMainCycleThinkingMode === 'function' &&
        global.Consciousness_getMainCycleThinkingMode() === 'passive';
      if (passiveMain && typeof global.PassiveMode_processUnderstandingModels === 'function') {
        global.PassiveMode_processUnderstandingModels();
      }
      // Третий пульс — ориентировочный рефлекс начала осмысления: создаём первый цикл осознания.
      if (global.cpuls === 3) {
        if (typeof global.Info_updateFromPerceptionTree === 'function') {
          global.Info_updateFromPerceptionTree();
        }
        if (typeof global.Info_updateFromStimulus === 'function') {
          global.Info_updateFromStimulus(0, 'external');
        }
        if (typeof global.Info_incrementStep === 'function') {
          global.Info_incrementStep();
        }
        if (typeof global.Info_thinkingFlash === 'function') {
          global.Info_thinkingFlash();
        }
        if (typeof global.stimuls_consciousness === 'function') {
          var branchId = typeof global.PerceptionTree_getActiveTerminalNodeId === 'function'
            ? global.PerceptionTree_getActiveTerminalNodeId()
            : 0;
          global.stimuls_consciousness({
            actual_stimul_ID: 0,
            branchId: branchId,
            well: global.BadNormWell || 0,
            emotionId: 0,
            activityID: 0,
            significance: 1
          });
        }
      }
      // Диспетчер циклов мышления: один шаг главному циклу, фоновым — раз в 3 пульса.
      if (typeof global.dispetchConsciousnessThinking === 'function') {
        global.dispetchConsciousnessThinking(global.cpuls);
      }
      if (typeof global.processGeneticReflexes === 'function') {
        global.processGeneticReflexes();
      }
      global.EpisodicMemory_skipConditionalReflexFormation = false;

      ensure_dom_refs();
      if (pulseCircle) {
        isOn = !isOn;
        if (isOn) pulseCircle.classList.remove('off');
        else pulseCircle.classList.add('off');
      }
    } catch (e) {
      if (typeof global.console !== 'undefined' && global.console.error) {
        global.console.error('sep_of_puls:', e);
      }
    } finally {
      var elapsedTime = Date.now() - startTime;
      var delayTime = elapsedTime >= 1000 ? 0 : Math.max(0, 1000 - elapsedTime);
      global.setTimeout(sep_of_puls, delayTime);
    }
  }

  global.setTimeout(sep_of_puls, 1000);
})(window);