/* widget-registry.jsx — центральный реестр виджетов (KSH-356).
   Единственный источник правды о виджете: заголовок/иконка/категория, дефолты
   (ширина/высота/тип графика), допустимые типы графика, поведение (drag/resize/…),
   источник данных и рендер. Потребители — ops-field (каталог + рабочий набор),
   lk-arrange (meta секций), lk-hub-wgt (бенто). Новый флаг в GLOBAL_BEHAVIORS или в
   спеке виджета применяется ко всем потребителям автоматически.

   Модуль ничего не рендерит и не тянет зависимостей — грузится до ops-field/lk-arrange/
   lk-hub-wgt, поэтому подключение безопасно и обратимо. */
(function () {
  /* порядок категорий в каталоге (совпадает с историческим ops-field) */
  const CAT_ORDER = ['Разделы', 'Операционный центр', 'Продажи', 'Клиенты', 'Производство', 'Команда', 'Финансы'];

  /* глобальные дефолты — правка здесь применяется ко ВСЕМ виджетам сразу */
  const GLOBAL_DEFAULTS = { cols: 2, minCols: 1, maxCols: 6, height: 'auto', viz: null };
  const GLOBAL_BEHAVIORS = { drag: true, resize: true, color: true, expand: true, spark: false };

  const specs = {};   /* id -> spec */
  const order = [];   /* порядок регистрации */

  function define(id, spec) {
    if (!specs[id]) order.push(id);
    specs[id] = Object.assign({}, spec, { id });
    return specs[id];
  }
  function registerAll(map) {
    Object.keys(map || {}).forEach((id) => define(id, map[id]));
    return WidgetRegistry;
  }
  const get = (id) => specs[id];
  const has = (id) => Object.prototype.hasOwnProperty.call(specs, id);
  const list = () => order.map((id) => specs[id]);

  /* категории, реально присутствующие среди зарегистрированных виджетов */
  function cats() {
    const present = [...new Set(list().map((w) => w.cat).filter(Boolean))];
    return CAT_ORDER.filter((c) => present.includes(c)).concat(present.filter((c) => !CAT_ORDER.includes(c)));
  }
  const catWidgets = (cat) => order.filter((id) => specs[id].cat === cat).map((id) => [id, specs[id]]);

  /* слитые дефолты: спек над глобальными */
  const defaults = (id) => Object.assign({}, GLOBAL_DEFAULTS, (specs[id] && specs[id].defaults) || {});

  /* поведение: глобальные флаги + оверрайд спека. behavior(id) → объект; behavior(id,'drag') → bool */
  function behavior(id, flag) {
    const b = Object.assign({}, GLOBAL_BEHAVIORS, (specs[id] && specs[id].behaviors) || {});
    return flag ? !!b[flag] : b;
  }

  const WidgetRegistry = {
    define, registerAll, get, has, list, cats, catWidgets, defaults, behavior,
    CAT_ORDER, GLOBAL_DEFAULTS, GLOBAL_BEHAVIORS, specs,
  };
  window.WidgetRegistry = window.WidgetRegistry || WidgetRegistry;
})();
