/* ============================================================
   sys-fields.jsx — built-in document fields (Bộ môn / Trạng thái / Định dạng)
   with per-project admin overrides: icon, display name, hidden.
   Config persists in project_settings.settings.sysFields via cdeData.
   Consumers read through window.* helpers; useSysCfg() re-renders on change.
   ============================================================ */
(function () {
  const SYS_FIELDS = [
    { id: "disc",   name: "Bộ môn",     icon: "boxes" },
    { id: "status", name: "Trạng thái", icon: "circle-dot" },
    { id: "type",   name: "Định dạng",  icon: "file" },
  ];

  let _cfg = null;                 // { disc:{name?,icon?,hidden?,options?}, ... } — null until loaded
  const _subs = new Set();
  // rebuild the discipline globals before notifying so consumers see fresh values
  const _notify = () => { rebuildDisc(); _subs.forEach(fn => fn()); };

  function loadSysCfg(force) {
    if (_cfg && !force) return Promise.resolve(_cfg);
    // not ready yet — return defaults WITHOUT caching, so a later (post-login) call retries
    if (!(window.cdeData && cdeData.projectSettings && window.CDE_READY)) return Promise.resolve(_cfg || {});
    return cdeData.projectSettings()
      .then(s => { _cfg = (s && s.sysFields) || {}; _notify(); return _cfg; })
      .catch(() => { _cfg = {}; return _cfg; });
  }
  const sysCfg = () => _cfg || {};

  /* ---- Bộ môn (disc) as an editable property: single dynamic source ----
     window.DISC_NAME (id→label) & window.DISC_COL (id→color) are built from
     project config (sysFields.disc.options) with DEFAULT_DISC as the seed/fallback.
     The objects are created once and MUTATED in place so every consumer that
     captured the reference (transmittals/rfi/access do `= window.DISC_NAME`)
     keeps seeing current values. Never reassign these two — only mutate. */
  const DEFAULT_DISC = [
    { id: "inf",  label: "Hạ tầng",     color: "#14b8a6" },
    { id: "str",  label: "Kết cấu",     color: "#60a5fa" },
    { id: "arc",  label: "Kiến trúc",   color: "#a78bfa" },
    { id: "mep",  label: "MEP",         color: "#f59e0b" },
    { id: "pm",   label: "Quản lý",     color: "#334155" },
    { id: "site", label: "Công trường", color: "#5b6b72" },
  ];
  function discOptions() {
    const o = (sysCfg().disc || {}).options;
    return (Array.isArray(o) && o.length) ? o : DEFAULT_DISC;
  }
  window.DISC_NAME = window.DISC_NAME || {};
  window.DISC_COL  = window.DISC_COL  || {};
  function rebuildDisc() {
    const nm = window.DISC_NAME, col = window.DISC_COL;
    for (const k in nm) delete nm[k];
    for (const k in col) delete col[k];
    discOptions().forEach(o => { nm[o.id] = o.label; col[o.id] = o.color; });
  }
  rebuildDisc();   // seed defaults synchronously (before login / before consumers render)

  function sysFieldMeta(id) {
    const base = SYS_FIELDS.find(f => f.id === id) || { id, name: id, icon: null };
    const o = sysCfg()[id] || {};
    return { id, name: o.name || base.name, icon: (o.icon !== undefined ? o.icon : base.icon) || null, hidden: !!o.hidden };
  }
  const visibleSysFields = () => SYS_FIELDS.map(f => sysFieldMeta(f.id)).filter(f => !f.hidden);
  const hiddenSysFields  = () => SYS_FIELDS.map(f => sysFieldMeta(f.id)).filter(f => f.hidden);
  const isSysHidden = (id) => !!(sysCfg()[id] && sysCfg()[id].hidden);

  // patch: {name?, icon?, hidden?}; pass icon:null to clear an icon override
  async function saveSysField(id, patch) {
    const cur = sysCfg();
    const next = { ...cur, [id]: { ...(cur[id] || {}), ...patch } };
    await cdeData.updateProjectSettings({ sysFields: next });
    _cfg = next; _notify();
    return next;
  }

  // React hook: subscribe to config changes, trigger first load
  function useSysCfg() {
    const [, force] = React.useReducer(x => x + 1, 0);
    React.useEffect(() => {
      _subs.add(force);
      if (_cfg == null) loadSysCfg();
      return () => { _subs.delete(force); };
    }, []);
    return sysCfg();
  }

  Object.assign(window, {
    SYS_FIELDS, loadSysCfg, sysCfg, sysFieldMeta,
    visibleSysFields, hiddenSysFields, isSysHidden, saveSysField, useSysCfg,
    DEFAULT_DISC, discOptions,
  });
})();
