/* global window, React */
// ── Store для варианта «Спокойствие» (красный телефон) ──
// Своя память (отдельный ключ), баллы риска по сигналам и пересчёт светофора
// в зависимости от выбранного «уровня чуткости» (агрессии красного).
const CALM_KEY = "signal_calm_state_v1";

// score 0..100 — насколько остро. Порог красного/жёлтого зависит от уровня чуткости.
// Сценарии демо: переопределяют баллы по сигналам, чтобы показать
// три состояния — «всё в норме» → «отклонения» → «проблемы».
const SCENARIOS = {
  green:    { "c-margin":20,"c-cash":18,"c-stock":24,"c-plan":22,"c-debt":16,"c-ops":19,"c-hr":14,"c-it":10 },
  deviation:{ "c-margin":58,"c-cash":52,"c-stock":48,"c-plan":46,"c-debt":44,"c-ops":33,"c-hr":22,"c-it":12 },
  problem:  { "c-margin":86,"c-cash":78,"c-stock":64,"c-plan":52,"c-debt":44,"c-ops":33,"c-hr":22,"c-it":12 },
};
const SCENARIO_LIST = [
  ["green", "Всё в норме", "Бизнес здоров — телефон молчит"],
  ["deviation", "Отклонения", "Появились зоны внимания"],
  ["problem", "Проблемы", "Есть критичное — пора действовать"],
];

const CALM_SEED = {
  level: "normal",            // calm | normal | sharp
  scenario: "green",          // green | deviation | problem
  digestOn: true,
  digestTime: "08:30",
  acknowledged: [],           // id отмеченных «принято»
  signals: [
    { id: "c-margin", area: "Маржа", source: "1С + Касса", score: 86, metric: "24,6%", delta: "−8,4% к плану",
      cause: "Закупочные цены выросли по 12 позициям, продажные не обновлены.",
      risk: "−1,2 млн ₽ прибыли в месяц", action: "Пересчитать цены", owner: "Коммерческий директор",
      series: [33,32,31,32,30,31,29,30,28,27,25,24.6] },
    { id: "c-cash", area: "Деньги", source: "Банк + 1С", score: 78, metric: "18 дн", delta: "до кассового разрыва",
      cause: "Платежи поставщикам совпали с ростом дебиторской задолженности.",
      risk: "−2,1 млн ₽ дефицита ликвидности", action: "Сдвинуть платежи", owner: "Финансовый директор",
      series: [46,50,43,54,48,58,51,62,55,66,60,70] },
    { id: "c-stock", area: "Склад", source: "WMS", score: 64, metric: "9 дн", delta: "запас по ходовым",
      cause: "Спрос растёт быстрее поставок.", risk: "−3,8 млн ₽ недополученной выручки",
      action: "Ускорить закупку", owner: "Операционный директор",
      series: [38,44,41,49,45,52,48,57,51,64,58,72] },
    { id: "c-plan", area: "Продажи", source: "CRM", score: 52, metric: "91%", delta: "плана месяца",
      cause: "Лиды просели в трёх каналах.", risk: "−4,8 млн ₽ выручки к концу месяца",
      action: "Перераспределить лиды", owner: "Коммерческий директор",
      series: [42,45,48,52,47,50,46,43,39,36,34,31] },
    { id: "c-debt", area: "Дебиторка", source: "1С", score: 44, metric: "18,4 млн", delta: "+12% за месяц",
      cause: "Три клиента вышли за лимит отсрочки.", risk: "Заморозка 2,2 млн ₽ в обороте",
      action: "Запустить сбор дебиторки", owner: "Финансовый менеджер",
      series: [14,15,15.4,16,16.3,16.9,17.2,17.6,18,18.2,18.3,18.4] },
    { id: "c-ops", area: "Операции", source: "WMS", score: 33, metric: "42 дн", delta: "оборачиваемость",
      cause: "Лёгкий рост складских остатков.", risk: "Небольшая заморозка капитала",
      action: "Проверить медленные позиции", owner: "Операционный директор",
      series: [38,39,40,40,41,41,42,42,42,42,42,42] },
    { id: "c-hr", area: "Команда", source: "HR", score: 22, metric: "норма", delta: "загрузка ок",
      cause: "Загрузка и текучесть в пределах нормы.", risk: "Рисков нет",
      action: "Ничего не требуется", owner: "—",
      series: [70,71,70,72,71,72,71,72,72,72,72,72] },
    { id: "c-it", area: "Данные", source: "ETL", score: 12, metric: "99,8%", delta: "аптайм",
      cause: "Загрузки идут штатно, данные свежие.", risk: "Рисков нет",
      action: "Ничего не требуется", owner: "—",
      series: [99.7,99.8,99.8,99.9,99.8,99.9,99.8,99.9,99.8,99.9,99.8,99.8] },
  ],
};

// пороги по уровню чуткости: [redMin, amberMin]
const THRESH = { calm: [82, 62], normal: [65, 42], sharp: [50, 28] };
const LEVELS = [
  ["calm", "Спокойный", "Краснеет только при крупном риске. Меньше шума."],
  ["normal", "Обычный", "Сбалансировано: важное — красным, остальное — под наблюдением."],
  ["sharp", "Чуткий", "Реагирует рано. Больше предупреждений на ранней стадии."],
];

function sevOf(score, level) { const [r, a] = THRESH[level]; return score >= r ? "red" : score >= a ? "amber" : "green"; }

function calmLoad() { try { const raw = localStorage.getItem(CALM_KEY); if (raw) return JSON.parse(raw); } catch (e) {} return JSON.parse(JSON.stringify(CALM_SEED)); }
let cstate = calmLoad();
const clisteners = new Set();
function cpersist() { try { localStorage.setItem(CALM_KEY, JSON.stringify(cstate)); } catch (e) {} }
function cemit() { clisteners.forEach((l) => l(cstate)); }
function ccommit() { cpersist(); cemit(); }
window.addEventListener("storage", (e) => { if (e.key === CALM_KEY && e.newValue) { try { cstate = JSON.parse(e.newValue); cemit(); } catch (err) {} } });

const CalmStore = {
  get: () => cstate,
  levels: LEVELS,
  subscribe(fn) { clisteners.add(fn); return () => clisteners.delete(fn); },
  reset() { cstate = JSON.parse(JSON.stringify(CALM_SEED)); ccommit(); },
  setLevel(l) { cstate.level = l; ccommit(); },
  setScenario(sc) { cstate.scenario = sc; const m = SCENARIOS[sc]; if (m) cstate.signals.forEach((s) => { if (m[s.id] != null) s.score = m[s.id]; }); cstate.acknowledged = []; ccommit(); },
  scenarios: SCENARIO_LIST,
  toggleDigest() { cstate.digestOn = !cstate.digestOn; ccommit(); },
  setDigestTime(t) { cstate.digestTime = t; ccommit(); },
  ack(id) { if (!cstate.acknowledged.includes(id)) { cstate.acknowledged.push(id); ccommit(); } },
  // производные
  effScore(s) { const m = SCENARIOS[cstate.scenario]; return (m && m[s.id] != null) ? m[s.id] : s.score; },
  withSev() { return cstate.signals.map((s) => ({ ...s, score: this.effScore(s), severity: sevOf(this.effScore(s), cstate.level) })); },
  counts() { const a = this.withSev(); return { red: a.filter((s)=>s.severity==="red").length, amber: a.filter((s)=>s.severity==="amber").length, green: a.filter((s)=>s.severity==="green").length, total: a.length }; },
};

// философия эскалации
const ESCALATION = {
  green: { label: "Ничего не делать", icon: "check", text: "Показатель в норме. Система молчит — это и есть хороший знак.", color: "var(--green)" },
  amber: { label: "Позвонить", icon: "phone", text: "Под наблюдением. Достаточно звонка ответственному, чтобы прояснить и не упустить.", color: "var(--amber)" },
  red: { label: "Ехать разбираться", icon: "target", text: "Критично. Это уровень, на котором стоит вмешаться лично и принять решение сегодня.", color: "var(--red)" },
};

window.CalmStore = CalmStore;
window.calmSev = sevOf;
window.ESCALATION = ESCALATION;
window.useCalm = function useCalm() {
  const [, force] = React.useReducer((x) => x + 1, 0);
  React.useEffect(() => CalmStore.subscribe(() => force()), []);
  return CalmStore;
};
