/**
 * Режим сна — единая точка правды по UI и базовому контексту.
 *
 * Поведение:
 * - Включение: кнопка «Сон» (basic_contexts_ui) или авто при ConsciousnessFinCyclesTotal > 100 (см. tryAutoAfterFinCycles).
 * - Пока sleepActive: в prepare.getActiveBasicContexts принудительно только контекст SleepMode_CONTEXT_ID (подавляет Норму/критику по виталам).
 * - Стимулы: почти все заблокированы; разрешены только пары в allowedKeys (Наказание, Вопль, Сирена, Рычание, Огонь) — см. refreshStimulusButtonVisuals.
 * - Выход: toggle, SleepMode_exit(), или первый клик по разрешённому стимулу (stimuls_ui вызывает exit без флага).
 * - Нормальное завершение сновидений: sleep_dream_process вызывает SleepMode_exit(true) → после пробуждения удаляются фоновые циклы ФО (Consciousness_deleteAllBackgroundCycles).
 *
 * Сновидения: dreams.js → sleep_dream_process.js (очередь пустых кадров ЭП, пассивный цикл, реализация кадра).
 */
(function (global) {
  'use strict';

  var SLEEP_CONTEXT_ID = 15;
  var FIN_CYCLE_AUTO_THRESHOLD = 100;

  var ROW_IDS = ['stimulsRow', 'stimulsRowPositiv', 'stimulsRowNegative', 'stimulsRowNeutral'];

  /** Разрешённые в режиме сна: мотивация «Наказание»; негатив: Вопль, Сирена, Рычание, Огонь. */
  var allowedKeys = {
    'stimulsRow|8': true,
    'stimulsRowNegative|8': true,
    'stimulsRowNegative|10': true,
    'stimulsRowNegative|13': true,
    'stimulsRowNegative|20': true
  };

  function rowKey(rowId, stimId) {
    return String(rowId) + '|' + String(stimId);
  }

  function isStimulusAllowedInSleep(rowId, localStimId) {
    return !!allowedKeys[rowKey(rowId, localStimId)];
  }

  var sleepActive = false;
  /** true, если последний вход в сон был из-за счётчика финовых циклов (для подсказки UI). */
  var sleepFromAuto = false;

  function isActive() {
    return sleepActive;
  }

  /** Класс sleep-mode на html/body — общий фон страницы (согласовать с vitals_ui и SleepMode_PAGE_BACKGROUND). */
  function applySleepPageBackground() {
    var doc = global.document;
    if (!doc || !doc.body) return;
    if (sleepActive) {
      doc.documentElement.classList.add('sleep-mode');
      doc.body.classList.add('sleep-mode');
    } else {
      doc.documentElement.classList.remove('sleep-mode');
      doc.body.classList.remove('sleep-mode');
    }
  }

  function setSleepButtonVisual() {
    var btn = global.document.getElementById('sleepModeToggleBtn');
    if (!btn) return;
    if (sleepActive) {
      btn.style.backgroundColor = '#c8d8f0';
      btn.style.borderColor = '#6a7aac';
      btn.title = sleepFromAuto
        ? 'Режим сна (авто после ' + FIN_CYCLE_AUTO_THRESHOLD + '+ финовых циклов). Щёлкните, чтобы выйти.'
        : 'Режим сна включён. Щёлкните, чтобы выйти.';
    } else {
      btn.style.backgroundColor = '#f5f5f5';
      btn.style.borderColor = '#888';
      btn.title = 'Включить режим сна (только контекст «Сон», ограничение стимулов)';
    }
  }

  /** Вход в сон: флаги, витрины, стимулы, затем цепочка сновидений (SleepDreams_onSleepEntered). */
  function enter(isAuto) {
    sleepActive = true;
    sleepFromAuto = !!isAuto;
    applySleepPageBackground();
    setSleepButtonVisual();
    if (typeof global.update_vitals_view === 'function') {
      global.update_vitals_view();
    }
    if (typeof global.update_basic_contexts_view === 'function') {
      global.update_basic_contexts_view();
    }
    if (typeof global.SleepMode_refreshStimulusButtonVisuals === 'function') {
      global.SleepMode_refreshStimulusButtonVisuals();
    }
    if (typeof global.SleepDreams_onSleepEntered === 'function') {
      global.SleepDreams_onSleepEntered(!!isAuto);
    }
  }

  /**
   * @param {boolean} [normalDreamCompletion] — только если sleep_dream_process закончил лимит реконструкций:
   *   тогда Consciousness_deleteAllBackgroundCycles (пробуждение после «нормального» сна). Иначе — просто выход (кнопка, стимул).
   */
  function exit(normalDreamCompletion) {
    sleepActive = false;
    sleepFromAuto = false;
    applySleepPageBackground();
    setSleepButtonVisual();
    if (typeof global.update_vitals_view === 'function') {
      global.update_vitals_view();
    }
    if (typeof global.update_basic_contexts_view === 'function') {
      global.update_basic_contexts_view();
    }
    if (typeof global.SleepMode_refreshStimulusButtonVisuals === 'function') {
      global.SleepMode_refreshStimulusButtonVisuals();
    }
    if (typeof global.SleepDreams_onSleepExited === 'function') {
      global.SleepDreams_onSleepExited();
    }
    // Фоновые циклы — только при завершении сновидений, не при ручном пробуждении.
    if (normalDreamCompletion && typeof global.Consciousness_deleteAllBackgroundCycles === 'function') {
      global.Consciousness_deleteAllBackgroundCycles();
    }
  }

  /** Ручной переключатель с кнопки «Сон»; выход без normalDreamCompletion — фоновые циклы не трогаем. */
  function toggle() {
    if (sleepActive) {
      exit();
    } else {
      enter(false);
    }
  }

  /** Авто-вход только из счётчика финовых циклов (не дублирует enter, если уже спим). */
  function enterAuto() {
    if (sleepActive) return;
    enter(true);
  }

  /**
   * Счётчик «финовых» циклов: главный цикл помечен expired (стагнация) или завершён со status finished.
   */
  function tryAutoAfterFinCycles() {
    var n = global.ConsciousnessFinCyclesTotal || 0;
    if (n > FIN_CYCLE_AUTO_THRESHOLD) {
      enterAuto();
    }
  }

  function shouldBlockStimulusInteraction(rowId, localStimId) {
    if (!sleepActive) return false;
    return !isStimulusAllowedInSleep(rowId, localStimId);
  }

  /**
   * При активном сне: неразрешённые кнопки полупрозрачны и без клика; разрешённые — лёгкий outline (delta-бордер).
   * Вызывается на каждом пульсе из puls.js и при входе/выходе из сна.
   */
  function refreshStimulusButtonVisuals() {
    var doc = global.document;
    if (!doc) return;

    var i;
    var j;
    for (i = 0; i < ROW_IDS.length; i++) {
      var rid = ROW_IDS[i];
      var row = doc.getElementById(rid);
      if (!row) continue;
      var buttons = row.querySelectorAll('button');
      for (j = 0; j < buttons.length; j++) {
        var btn = buttons[j];
        btn.classList.remove('stimul-btn-sleep-locked');
        btn.classList.remove('stimul-btn-sleep-allowed');
        btn.style.outline = '';
        btn.style.opacity = '';
        btn.style.pointerEvents = '';
        btn.style.cursor = '';
      }
    }

    var lbls = doc.querySelectorAll('button[data-stim-row-clear]');
    for (i = 0; i < lbls.length; i++) {
      var cb = lbls[i];
      cb.classList.remove('stimul-btn-sleep-locked');
      cb.style.opacity = '';
      cb.style.pointerEvents = '';
      cb.style.cursor = '';
    }

    if (!sleepActive) return;

    for (i = 0; i < ROW_IDS.length; i++) {
      var rowId = ROW_IDS[i];
      var r = doc.getElementById(rowId);
      if (!r) continue;
      var btns = r.querySelectorAll('button');
      for (j = 0; j < btns.length; j++) {
        var b = btns[j];
        var sid = b.dataset.stimId;
        if (!sid) {
          b.classList.add('stimul-btn-sleep-locked');
          b.style.opacity = '0.42';
          b.style.pointerEvents = 'none';
          b.style.cursor = 'not-allowed';
          continue;
        }
        var idNum = parseInt(sid, 10);
        if (isStimulusAllowedInSleep(rowId, idNum)) {
          b.classList.add('stimul-btn-sleep-allowed');
          b.style.outline = '1px solid rgba(130, 150, 210, 0.55)';
          b.style.outlineOffset = '1px';
        } else {
          b.classList.add('stimul-btn-sleep-locked');
          b.style.opacity = '0.42';
          b.style.pointerEvents = 'none';
          b.style.cursor = 'not-allowed';
        }
      }
    }

    for (i = 0; i < lbls.length; i++) {
      var cbx = lbls[i];
      cbx.classList.add('stimul-btn-sleep-locked');
      cbx.style.opacity = '0.42';
      cbx.style.pointerEvents = 'none';
      cbx.style.cursor = 'not-allowed';
    }
  }

  /** Фон страницы в режиме сна (см. vitals_ui — инлайн-фон .beast-root перекрывал CSS). */
  global.SleepMode_PAGE_BACKGROUND = '#e8e8e8';

  global.SleepMode_CONTEXT_ID = SLEEP_CONTEXT_ID;
  global.SleepMode_isActive = isActive;
  global.SleepMode_exit = exit;
  global.SleepMode_toggle = toggle;
  global.SleepMode_enterAuto = enterAuto;
  global.SleepMode_tryAutoAfterFinCycles = tryAutoAfterFinCycles;
  global.SleepMode_shouldBlockStimulusInteraction = shouldBlockStimulusInteraction;
  global.SleepMode_refreshStimulusButtonVisuals = refreshStimulusButtonVisuals;
  global.SleepMode_setSleepButtonVisual = setSleepButtonVisual;

  if (typeof global.ConsciousnessFinCyclesTotal !== 'number') {
    global.ConsciousnessFinCyclesTotal = 0;
  }
})(window);
