/**
 * Четвёртый уровень осознания (conscience_level_4).
 *
 * Реализовано: гештальтный уровень — буфер резонанса, обновление гештальтов по ЭП, тик Gestalt_onConsciousnessTick
 * (см. beast/_9_Conscience/gestalt.js, about_gestalt.md). Дополнительные триггеры (metaReflection и т.д.) —
 * через conscience_level_4({ sourceCycle, reason }).
 *
 * Вызов из канала ФО: conscience_level_4_runFromChannel(cycle) — после ур.3 в том же тике runOneStep.
 *
 * @param {Object} context
 * @param {Object} context.sourceCycle
 * @param {string} [context.reason]
 */
(function (global) {
  'use strict';

  function puls() {
    return typeof global.cpuls === 'number' ? global.cpuls : 0;
  }

  function appendCycleLog(cycle, text, force) {
    if (!cycle || typeof global.Consciousness_cycleAppendLog !== 'function') return;
    if (!force && !cycle.isMainCycle) return;
    global.Consciousness_cycleAppendLog(cycle, text, puls(), force ? { force: true } : undefined);
  }

  function conscience_level_4(context) {
    var cycle = context && context.sourceCycle;
    var reason = (context && context.reason) || '';
    if (!cycle) return;

    appendCycleLog(
      cycle,
      'Ур.4: ' + (reason || 'ручной вызов') + ' — расширение (conscience_level_4.js).',
      false
    );

    // TODO: условия входа (флаги цикла / инфокартины), иерархия целей, долгие планы — вызывать отдельные подсистемы.
  }

  /**
   * Один тик канала ФО для ур.4 (вызывается из Consciousness_runOneStep *после* ур.3 в том же пульсе).
   *
   * Гештальты на этом уровне (реализация в beast/_9_Conscience/gestalt.js):
   *
   * 1) Кто крутится здесь
   *    Обработка гештальта и буфера резонанса выполняется только для *главного* running-цикла
   *    (Gestalt_onConsciousnessTick внутри сам отсекает фоновые циклы). Так на пульс не дублируется
   *    разбор резонанса по числу фоновых процессов.
   *
   * 2) Что уже сделано *до* ур.4 в этом тике
   *    В начале ур.3 вызван Gestalt_prepareContextForCycle: в global.GestaltContextForLevel3 лежит снимок
   *    открытой доминанты по образу цели (если цель есть). Ур.3 использует это только как контекст;
   *    поиск правил и мотор идут по своим правилам.
   *
   * 3) Что делает вызов Gestalt_onConsciousnessTick(cycle)
   *    • Привязка «ведущего» открытого гештальта к цели главного цикла (cycle.goalImageId или
   *      InfoPicture.currentGoalId в режиме target): обновляются Gestalt_activeGestaltId и связанные поля.
   *    • Если у этого гештальта статус ещё не «частичное решение» (ниже PARTIAL), просматривается
   *      GestaltResonanceBuffer — FIFO сигнатур успешных/закрытых кадров ЭП. Для каждой пары
   *      (сигнатура × открытый гештальт) считается эвристический score; при превышении порога —
   *      инсайт аналогии, дополнение списка автоматизмов и analogyPool, возможный переход status 0→1.
   *    • Повторно вызывается Gestalt_prepareContextForCycle: после возможных инсайтов по резонансу
   *      контекст для следующего пульса и для чтения из других модулей обновлён.
   *
   * 4) Что *не* делается в этом вызове
   *    Закрытие кадра ЭП и запись новой сигнатуры в буфер выполняются в episodic_memory.closeLastFrame →
   *    Gestalt_onEpisodeFeedbackClosed (не здесь). Ур.4 не запускает мотор и не подменяет ур.3.
   *
   * 5) Расширения
   *    Дополнительные ветки (мета-рефлексия, флаги цикла) можно добавлять ниже, рядом с условными
   *    вызовами conscience_level_4({ sourceCycle, reason }).
   */
  function conscience_level_4_runFromChannel(cycle) {
    if (!cycle || cycle.status !== 'running') return;
    if (typeof global.Gestalt_onConsciousnessTick === 'function') {
      try {
        global.Gestalt_onConsciousnessTick(cycle);
      } catch (e) {}
    }
    // Пример будущего условия:
    // if (cycle.metaReflectionPending) { conscience_level_4({ sourceCycle: cycle, reason: 'meta' }); }
  }

  global.conscience_level_4 = conscience_level_4;
  global.conscience_level_4_runFromChannel = conscience_level_4_runFromChannel;
})(window);
