/**
 * Cyber-Assistant — Entity Consolidation (multi-entités, lecture seule)
 * ---------------------------------------------------------------------------
 * État volatile et helpers réseau pour les vues consolidées de l'entité
 * principale. Aucune donnée consolidée n'entre dans appData ni dans les
 * payloads poussables.
 */
(function() {
  'use strict';

  var SYNC_API = './data/sync.php';
  var VALID_MODES = { scope: true, consolidated: true };
  var SECTION_PAGE_LIMIT = 1000;
  var SECTION_MAX_ROWS = 10000;
  var CONSOLIDABLE_SECTIONS = {
    'risks': true,
    'threats-section': true,
    'actions': true,
    'nonconformities': true,
    'critical-assets': true,
    'audits': true,
    'documents': true,
    'stakeholders': true,
    'kpis': true,
    'managementReviews': true,
    'project-risks': true,
    'risk-analysis': true
  };

  var state = {
    dashboardMode: 'scope',
    sectionModes: {},
    sectionCache: {},
    summaryCache: null,
    summaryCacheAt: 0
  };

  function _em() { return window.CSI_EntityManager; }

  function isAllowed() {
    var EM = _em();
    return !!(EM && EM.isMultiEntity && EM.isMultiEntity() &&
      EM.isGroupUser && EM.isGroupUser() &&
      EM.activeScope && !EM.activeScope());
  }

  function _normalizeMode(mode) {
    return VALID_MODES[mode] ? mode : 'scope';
  }

  function getDashboardMode() {
    if (!isAllowed()) return 'scope';
    return _normalizeMode(state.dashboardMode);
  }

  function setDashboardMode(mode) {
    if (!isAllowed()) {
      state.dashboardMode = 'scope';
      return false;
    }
    state.dashboardMode = _normalizeMode(mode);
    return true;
  }

  function getSectionMode(sectionId) {
    if (!isAllowed()) return 'scope';
    return _normalizeMode(state.sectionModes[sectionId] || 'scope');
  }

  function setSectionMode(sectionId, mode) {
    if (!sectionId || !isSectionConsolidable(sectionId)) return false;
    if (!isAllowed()) {
      state.sectionModes = {};
      return false;
    }
    state.sectionModes[sectionId] = _normalizeMode(mode);
    return true;
  }

  function isSectionConsolidable(sectionId) {
    return !!CONSOLIDABLE_SECTIONS[sectionId];
  }

  function clear() {
    state.dashboardMode = 'scope';
    state.sectionModes = {};
    state.sectionCache = {};
    state.summaryCache = null;
    state.summaryCacheAt = 0;
  }

  function _authHeader() {
    return window.CSI_AuthManager && window.CSI_AuthManager.getAuthHeader ?
      window.CSI_AuthManager.getAuthHeader() : '';
  }

  function _fetchJson(url) {
    var f = window.fetchWithTimeout || window.fetch;
    if (!f) return Promise.reject(new Error('fetch unavailable'));
    return f(url, { headers: { 'Authorization': _authHeader() } })
      .then(function(r) {
        if (!r || !r.ok) {
          var httpError = new Error('HTTP ' + (r ? r.status : '0'));
          httpError.status = r ? r.status : 0;
          httpError.url = url;
          throw httpError;
        }
        return r.json();
      })
      .then(function(d) {
        if (!d || d.ok === false) throw new Error((d && d.error) || 'Chargement impossible');
        return d;
      });
  }

  function _sectionUrl(sectionId, offset) {
    return SYNC_API +
      '?action=consolidated-read&section=' + encodeURIComponent(sectionId) +
      '&limit=' + encodeURIComponent(SECTION_PAGE_LIMIT) +
      '&offset=' + encodeURIComponent(offset || 0);
  }

  function _numberOr(value, fallback) {
    var parsed = parseInt(value, 10);
    return isNaN(parsed) ? fallback : parsed;
  }

  function _entityItemKey(item) {
    if (!item || typeof item !== 'object') return '';
    var entityId = item._entity && item._entity.id != null ? String(item._entity.id) : '';
    var itemId = item.id != null ? String(item.id) : '';
    return entityId && itemId ? entityId + '::' + itemId : '';
  }

  function _appendUniqueItems(target, seen, pageItems) {
    pageItems.forEach(function(item) {
      var key = _entityItemKey(item);
      if (key && seen[key]) return;
      if (key) seen[key] = true;
      target.push(item);
    });
  }

  function _sectionResult(template, items, total, truncated) {
    var result = {};
    Object.keys(template || {}).forEach(function(key) {
      if (key !== 'items') result[key] = template[key];
    });
    result.items = items;
    result.total = total;
    result.loaded = items.length;
    result.limit = SECTION_PAGE_LIMIT;
    result.offset = 0;
    result.truncated = !!truncated;
    return result;
  }

  function _fetchRemainingSectionPages(sectionId, firstPage) {
    var items = [];
    var seen = {};
    var firstItems = firstPage && Array.isArray(firstPage.items) ? firstPage.items : [];
    var total = _numberOr(firstPage && firstPage.total, firstItems.length);
    _appendUniqueItems(items, seen, firstItems);

    function finalize(truncated) {
      return _sectionResult(firstPage, items, total, truncated);
    }

    function nextOffset(page, fallbackOffset, pageItems) {
      var reportedOffset = _numberOr(page && page.offset, fallbackOffset);
      var reportedLimit = Math.max(1, _numberOr(page && page.limit, SECTION_PAGE_LIMIT));
      var computed = reportedOffset + pageItems.length;
      return computed > fallbackOffset ? computed : fallbackOffset + reportedLimit;
    }

    function loadNext(offset) {
      if (items.length >= total || offset >= total) return Promise.resolve(finalize(false));
      if (offset >= SECTION_MAX_ROWS) return Promise.resolve(finalize(total > items.length));

      return _fetchJson(_sectionUrl(sectionId, offset)).then(function(page) {
        var pageItems = page && Array.isArray(page.items) ? page.items : [];
        if (!pageItems.length) return finalize(total > items.length);
        _appendUniqueItems(items, seen, pageItems);
        total = Math.max(total, _numberOr(page && page.total, total));
        var offsetAfterPage = nextOffset(page, offset, pageItems);
        var pageLimit = Math.max(1, _numberOr(page && page.limit, SECTION_PAGE_LIMIT));
        var isShortPage = pageItems.length < pageLimit;
        if (items.length >= total || offsetAfterPage >= total) return finalize(false);
        if (offsetAfterPage >= SECTION_MAX_ROWS || isShortPage) return finalize(total > items.length);
        return loadNext(offsetAfterPage);
      });
    }

    return loadNext(nextOffset(firstPage, 0, firstItems));
  }

  function fetchSummary(opts) {
    opts = opts || {};
    if (!isAllowed()) return Promise.resolve(null);
    if (!opts.force && state.summaryCache && (Date.now() - state.summaryCacheAt) < 15000) {
      return Promise.resolve(state.summaryCache);
    }
    return _fetchJson(SYNC_API + '?action=consolidated-summary').then(function(d) {
      state.summaryCache = d;
      state.summaryCacheAt = Date.now();
      return d;
    });
  }

  function fetchSection(sectionId, opts) {
    opts = opts || {};
    if (!isAllowed() || !sectionId) return Promise.resolve(null);
    if (!opts.force && state.sectionCache[sectionId]) return Promise.resolve(state.sectionCache[sectionId]);
    return _fetchJson(_sectionUrl(sectionId, 0))
      .then(function(firstPage) {
        return _fetchRemainingSectionPages(sectionId, firstPage);
      })
      .then(function(sectionData) {
        state.sectionCache[sectionId] = sectionData;
        return sectionData;
      });
  }

  var api = {
    isAllowed: isAllowed,
    getDashboardMode: getDashboardMode,
    setDashboardMode: setDashboardMode,
    getSectionMode: getSectionMode,
    setSectionMode: setSectionMode,
    isSectionConsolidable: isSectionConsolidable,
    fetchSummary: fetchSummary,
    fetchSection: fetchSection,
    clear: clear
  };

  if (window.CSI && window.CSI.register) {
    window.CSI.register('entity-consolidation', { exports: { CSI_EntityConsolidation: api } });
  }
  window.CSI_EntityConsolidation = api;
  void 0;
})();
