'use strict';

const formConfigFetcher = require('./form-config-fetcher-fef79845.js');
const DataFetcher = require('./DataFetcher-21f8c2dc.js');
const filterItemType_enum = require('./filter-item-type.enum-a7ffdaa6.js');
const core = require('@sankhyalabs/core');

class GridConfigFetcher extends formConfigFetcher.ResourceFetcher {
  constructor() {
    super(...arguments);
    this.GRID_CONFIG_VERSION = "V3:";
  }
  async getDefaultConfig(resourceId) {
    var _a, _b;
    const payload = { 'requestBody': { 'gridConfig': { 'configName': `GrdCfgHtml5:${resourceId}` } } };
    const response = await DataFetcher.DataFetcher.get().callServiceBroker('GridConfig.restoreGridConfigFromJson', JSON.stringify(payload));
    const columns = (_b = (_a = response === null || response === void 0 ? void 0 : response.gridConfig) === null || _a === void 0 ? void 0 : _a.field) !== null && _b !== void 0 ? _b : [];
    return { columns };
  }
  getConfig(gridName, resourceID) {
    const completePath = this.getPath(resourceID, gridName);
    return new Promise((resolve, reject) => {
      this.loadResource(completePath)
        .then(loadedResource => {
        let config = undefined;
        if (loadedResource) {
          config = JSON.parse(loadedResource);
        }
        resolve(config);
      }).catch((error) => {
        reject(error);
      });
    });
  }
  saveConfig(config, gridName, resourceID) {
    const completePath = this.getPath(resourceID, gridName);
    return new Promise((resolve, reject) => {
      this.saveResource(config, completePath)
        .then((resp) => {
        resolve(JSON.parse(resp.resource));
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  getPath(resourceID, name) {
    if (name) {
      return `cfg://grid/${this.GRID_CONFIG_VERSION}${resourceID}/${name}`;
    }
    return `cfg://grid/${this.GRID_CONFIG_VERSION}${resourceID}`;
  }
}

var __rest = (undefined && undefined.__rest) || function (s, e) {
  var t = {};
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
    t[p] = s[p];
  if (s != null && typeof Object.getOwnPropertySymbols === "function")
    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
      if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
        t[p[i]] = s[p[i]];
    }
  return t;
};
function normalizeValue(value, type) {
  if (value == undefined) {
    return value;
  }
  if (value instanceof Date) {
    return value.toISOString();
  }
  if (typeof value === "object") {
    if (value instanceof Array) {
      return value.map(item => {
        if (filterItemType_enum.FilterItemType.MULTI_LIST === type) {
          const values = __rest(item, ["label"]);
          return normalizeValue(values);
        }
        return normalizeValue(item);
      });
    }
    else {
      const normalized = Object.assign({}, value);
      Object.keys(value).forEach(prop => {
        if (value[prop] !== undefined) {
          normalized[prop] = normalizeValue(value[prop], type);
        }
        else {
          delete normalized[prop];
        }
      });
      return normalized;
    }
  }
  return value;
}
class FilterBarConfigFetcher extends formConfigFetcher.ResourceFetcher {
  normalize(items) {
    return items.map(item => {
      const { id, value, fixed, visible, type, groupedItems } = item;
      const stateItem = { id };
      if (value) {
        stateItem["value"] = normalizeValue(value, type);
      }
      if (fixed) {
        stateItem["fixed"] = fixed;
      }
      if (groupedItems) {
        if (groupedItems.length === 0) {
          return;
        }
        if (groupedItems.filter(item => item.visible).length > 0) {
          stateItem["visible"] = true;
        }
        stateItem["groupedItems"] = this.normalize(groupedItems);
      }
      else {
        if (visible) {
          stateItem["visible"] = true;
        }
      }
      return stateItem;
    }).filter(item => item != undefined);
  }
  saveConfig(items, resourceID, configName) {
    return this.saveResource(this.normalize(items), this.getPath(resourceID, configName));
  }
  getConfig(resourceID, configName, urlParams) {
    return new Promise((accept, reject) => {
      this.loadResource(this.getPath(resourceID, configName, urlParams))
        .then((configAsString) => {
        let fieldsList;
        if (configAsString) {
          const filterBarConfig = JSON.parse(configAsString);
          fieldsList = this.buildFieldList(filterBarConfig.items);
        }
        accept(fieldsList || []);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  buildFieldList(items) {
    return items.map(item => {
      var _a, _b;
      if (item.type === filterItemType_enum.FilterItemType.MULTI_LIST) {
        const multiListValue = item.value;
        /**
         * Existe um bug no HTML5 onde ele salva a configuração do filtro na FilterBar como objeto em vez de array
         * Esse cenário ocorre quando há apenas um item na configuração do filtro
         */
        let multilistValueArray = (_b = (_a = multiListValue === null || multiListValue === void 0 ? void 0 : multiListValue.elements) !== null && _a !== void 0 ? _a : multiListValue === null || multiListValue === void 0 ? void 0 : multiListValue.members) !== null && _b !== void 0 ? _b : multiListValue;
        // Precisamos verificar se o objeto existe ou está unfefined
        multilistValueArray = multilistValueArray !== null && multilistValueArray !== void 0 ? multilistValueArray : [];
        multilistValueArray = Array.isArray(multilistValueArray) ? multilistValueArray : [multilistValueArray];
        // Existem cenários onde o HTML5 não salva o Id do filtro, apenas seu label e value
        multilistValueArray = multilistValueArray.map(itemRaw => {
          return Object.assign(Object.assign({}, itemRaw), { id: (itemRaw.id !== undefined) ? itemRaw.id : itemRaw.value });
        });
        item.value = core.ObjectUtils.copy(multilistValueArray);
      }
      return item;
    });
  }
  getPath(resourceID, name, urlParams) {
    let path = `cfg://filter/FilterBarState:${resourceID}`;
    if (name) {
      path += `.${name}`;
    }
    if (urlParams) {
      path += this.buildQueryString(urlParams);
    }
    return path;
  }
  buildQueryString(urlParams) {
    let queryString = '?';
    for (let key in urlParams) {
      if (!urlParams.hasOwnProperty(key)) {
        continue;
      }
      if (queryString.length > 1) {
        queryString += '&';
      }
      queryString += key + '=' + urlParams[key];
    }
    return queryString;
  }
}

class PersonalizedFilterFetcher {
  constructor() {
    this.DEFAULT_RESOURCE = '_default';
    this.templateByQuery = new Map();
    this.buildTemplates();
  }
  resolveURI(resourceID, configName, isDefault) {
    let uri = "filter-assistent-config://" + resourceID;
    if (configName) {
      uri += "." + configName;
    }
    if (isDefault) {
      uri += this.DEFAULT_RESOURCE;
    }
    return uri;
  }
  resolveLegacyConfigName(legacyConfigName, isDefault) {
    if (!legacyConfigName) {
      return '';
    }
    let legacyConfig = `?legacyResourceID=${legacyConfigName}`;
    if (isDefault) {
      legacyConfig += this.DEFAULT_RESOURCE;
    }
    return legacyConfig;
  }
  buildTemplates() {
    this.templateByQuery.set("fetchFilterFields", DataFetcher.dist.gql `
    query($name: String!) {
      $queryAlias$: fetchFilterFields(name: $name){
        currentLink {
          description
          uri
        }
        links {
          description
          uri
          fieldCount
        }
        fields {
          name
          description
          uri
          onlyDate
          dataType
          userInterface
          entityName
          properties {
            name
            value
          }
        }
      }
    }
    `);
    this.templateByQuery.set("fetchFilterAssistent", DataFetcher.dist.gql `
    query($name: String!) {
      $queryAlias$: fetchFilterAssistent(name: $name) {
        id
        name
        active
        expression
        warningMessage
        assistent
      }
    }`);
    this.templateByQuery.set("savePersonalizedFilter", DataFetcher.dist.gql `
    mutation($name: String!, $filterAssistent: InputFilterAssistent!)  {
      $queryAlias$: savePersonalizedFilter(name: $name, filterAssistent: $filterAssistent) {
        id
        name
      }
    }`);
    this.templateByQuery.set("deletePersonalizedFilter", DataFetcher.dist.gql `
    mutation($name: String!, $filterId: String!) {
      $queryAlias$: deletePersonalizedFilter(name: $name, filterId: $filterId) {
        id
        name
      }
    }`);
    this.templateByQuery.set("validateExpression", DataFetcher.dist.gql `
    query($dataUnitName: String!, $expression: String!) {
      $queryAlias$: validateExpression(dataUnitName: $dataUnitName, expression: $expression) {
        valid
        message
      }
    }`);
  }
  async loadDefaultFilter(resourceID, filterID, configName, legacyConfigName) {
    return this.loadPersonalizedFilter(resourceID, filterID, configName, legacyConfigName, true);
  }
  async loadPersonalizedFilter(resourceID, filterID, configName, legacyConfigName, isDefault) {
    return new Promise((resolve, reject) => {
      DataFetcher.DataFetcher.get()
        .callGraphQL({
        values: { name: this.resolveURI(resourceID, configName, isDefault) + "/" + filterID + this.resolveLegacyConfigName(legacyConfigName, isDefault) },
        query: this.templateByQuery.get("fetchFilterAssistent"),
      })
        .then((resp) => {
        resp.assistent = JSON.parse(resp.assistent);
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  async saveDefaultFilter(personalizedFilter, resourceID, configName) {
    return this.savePersonalizedFilter(personalizedFilter, resourceID, configName, true);
  }
  async savePersonalizedFilter(personalizedFilter, resourceID, configName, isDefault) {
    if (!personalizedFilter || Object.keys(personalizedFilter).length == 0) {
      return Promise.reject(new Error("personalizedFilter não pode ser vazio"));
    }
    let personalizedFilterParsed = JSON.parse(JSON.stringify(personalizedFilter));
    personalizedFilterParsed.assistent = JSON.stringify(personalizedFilterParsed.assistent);
    return new Promise((resolve, reject) => {
      DataFetcher.DataFetcher.get()
        .callGraphQL({
        values: { name: this.resolveURI(resourceID, configName, isDefault), filterAssistent: personalizedFilterParsed },
        query: this.templateByQuery.get("savePersonalizedFilter"),
      })
        .then((resp) => {
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  removeDefaultFilter(personalizedFilter, resourceID, configName) {
    return this.removePersonalizedFilter(personalizedFilter, resourceID, configName, true);
  }
  async removePersonalizedFilter(personalizedFilter, resourceID, configName, isDefault) {
    return new Promise((resolve, reject) => {
      DataFetcher.DataFetcher.get()
        .callGraphQL({
        values: { name: this.resolveURI(resourceID, configName, isDefault), filterId: personalizedFilter.id },
        query: this.templateByQuery.get("deletePersonalizedFilter"),
      })
        .then((resp) => {
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  async validatePersonalizedFilter(dataUnitName, expression) {
    return new Promise((resolve, reject) => {
      DataFetcher.DataFetcher.get()
        .callGraphQL({
        values: { dataUnitName: dataUnitName, expression: expression },
        query: this.templateByQuery.get("validateExpression"),
      })
        .then((resp) => {
        resolve(resp);
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
  loadFields(uri) {
    return new Promise((resolve, reject) => {
      DataFetcher.DataFetcher.get()
        .callGraphQL({
        values: { name: uri },
        query: this.templateByQuery.get("fetchFilterFields"),
      })
        .then((resp) => {
        var _a;
        let fields = resp.fields;
        for (const field of fields) {
          if (Array.isArray(field.properties) && field.properties.length > 0) {
            const propertiesConvertedObject = field.properties.reduce((accumulator, prop) => {
              accumulator[prop.name] = prop.value;
              return accumulator;
            }, {});
            field.properties = propertiesConvertedObject;
          }
          if ((_a = field === null || field === void 0 ? void 0 : field.properties) === null || _a === void 0 ? void 0 : _a.options) {
            field.properties.options = JSON.parse(field.properties.options);
          }
        }
        resolve(Object.assign(Object.assign({}, resp), { fields: fields }));
      })
        .catch((error) => {
        reject(error);
      });
    });
  }
}

var CONFIG_SOURCE;
(function (CONFIG_SOURCE) {
  CONFIG_SOURCE["form"] = "form";
  CONFIG_SOURCE["grid"] = "grid";
  CONFIG_SOURCE["filterBar"] = "filterBar";
})(CONFIG_SOURCE || (CONFIG_SOURCE = {}));
class ConfigStorage {
  static addFilterBarLegacyConfig(configName, legacyConfigName) {
    this.validateResourceId(legacyConfigName);
    this.filterBarLegacyConfig.set(configName, legacyConfigName);
  }
  static addFormLegacyConfig(configName, legacyConfigName) {
    this.validateResourceId(legacyConfigName);
    this.formLegacyConfig.set(configName, legacyConfigName);
  }
  static addGridLegacyConfig(configName, legacyConfigName) {
    this.validateResourceId(legacyConfigName);
    this.gridLegacyConfig.set(configName, legacyConfigName);
  }
  static preload(resourceID, configName, legacyConfigs) {
    if (configName && (legacyConfigs === null || legacyConfigs === void 0 ? void 0 : legacyConfigs.gridLegacyConfig)) {
      ConfigStorage.addGridLegacyConfig(configName, legacyConfigs.gridLegacyConfig);
    }
    if (configName && (legacyConfigs === null || legacyConfigs === void 0 ? void 0 : legacyConfigs.formLegacyConfig)) {
      ConfigStorage.addFormLegacyConfig(configName, legacyConfigs.formLegacyConfig);
    }
    ConfigStorage.loadFormConfig(configName, resourceID);
    ConfigStorage.loadGridConfig(configName, resourceID);
  }
  static async loadFilterBarConfig(name, resourceID, urlParams) {
    urlParams = this.handleLegacyConfig(name, CONFIG_SOURCE.filterBar, urlParams);
    const cacheID = ConfigStorage.buildCacheID(name, CONFIG_SOURCE.filterBar, resourceID);
    if (!ConfigStorage.configById.has(cacheID)) {
      ConfigStorage.configById.set(cacheID, ConfigStorage.filterBarConfigFetcher.getConfig(resourceID, name, urlParams));
    }
    return ConfigStorage.configById.get(cacheID);
  }
  static async loadFormConfig(name, resourceID) {
    name = this.handleLegacyConfigAsString(name, CONFIG_SOURCE.form);
    const cacheID = ConfigStorage.buildCacheID(name, CONFIG_SOURCE.form, resourceID);
    if (!ConfigStorage.configById.has(cacheID)) {
      ConfigStorage.configById.set(cacheID, ConfigStorage.formConfigFetcher.loadFormConfig(name, resourceID));
    }
    return ConfigStorage.configById.get(cacheID);
  }
  static async loadGridConfig(name, resourceID) {
    name = this.handleLegacyConfigAsString(name, CONFIG_SOURCE.grid);
    const cacheID = ConfigStorage.buildCacheID(name, CONFIG_SOURCE.grid, resourceID);
    if (!ConfigStorage.configById.has(cacheID)) {
      ConfigStorage.configById.set(cacheID, ConfigStorage.gridConfigFetcher.getConfig(name, resourceID));
    }
    return ConfigStorage.configById.get(cacheID);
  }
  static async saveFilterBarConfig(config, name, resourceID) {
    await this.deleteFilterBarConfigCache(name, resourceID);
    return this.filterBarConfigFetcher.saveConfig(config, resourceID, name);
  }
  static async saveFormConfig(config, name, resourceID) {
    name = this.handleLegacyConfigAsString(name, CONFIG_SOURCE.form);
    await this.deleteFormConfigCache(name, resourceID);
    return this.formConfigFetcher.saveConfig(config, name, resourceID);
  }
  static async saveCardState(config, name, resourceID) {
    return this.formConfigFetcher.saveCardState(config, name, resourceID);
  }
  static async getDefaultGridConfig(resourceId) {
    return await this.gridConfigFetcher.getDefaultConfig(resourceId);
  }
  static async saveGridConfig(config, name, resourceID) {
    if (config == undefined) {
      return;
    }
    name = this.handleLegacyConfigAsString(name, CONFIG_SOURCE.grid);
    await this.deleteGridConfigCache(name, resourceID);
    return this.gridConfigFetcher.saveConfig(config, name, resourceID);
  }
  static async loadDefaultFilter(filterId, resourceID, configName) {
    const legacyConfigName = this.filterBarLegacyConfig.get(configName);
    return this.personalizedFilterFetcher.loadDefaultFilter(resourceID, filterId, configName, legacyConfigName);
  }
  static async loadPersonalizedFilter(filterId, resourceID, configName) {
    const legacyConfigName = this.filterBarLegacyConfig.get(configName);
    return this.personalizedFilterFetcher.loadPersonalizedFilter(resourceID, filterId, configName, legacyConfigName);
  }
  static async savePersonalizedFilter(personalizedFilter, resourceID, configName) {
    //Ao criar ou alterar um filtro personalizado,
    //precisamos remover o cache do status da filterbar.
    await this.deleteFilterBarConfigCache(configName, resourceID);
    return this.personalizedFilterFetcher.savePersonalizedFilter(personalizedFilter, resourceID, configName);
  }
  static async saveDefaultFilter(personalizedFilter, resourceID, configName) {
    await this.deleteFilterBarConfigCache(configName, resourceID);
    return this.personalizedFilterFetcher.saveDefaultFilter(personalizedFilter, resourceID, configName);
  }
  static async removeDefaultFilter(personalizedFilter, resourceID, configName) {
    return this.personalizedFilterFetcher.removeDefaultFilter(personalizedFilter, resourceID, configName);
  }
  static async removePersonalizedFilter(personalizedFilter, resourceID, configName) {
    return this.personalizedFilterFetcher.removePersonalizedFilter(personalizedFilter, resourceID, configName);
  }
  static async validatePersonalizedFilter(dataUnitName, expression) {
    return this.personalizedFilterFetcher.validatePersonalizedFilter(dataUnitName, expression);
  }
  static async deleteGridConfigCache(name, resourceID) {
    await this.deleteConfigCache(name, resourceID, CONFIG_SOURCE.grid);
  }
  static async deleteFormConfigCache(name, resourceID) {
    await this.deleteConfigCache(name, resourceID, CONFIG_SOURCE.form);
  }
  static async deleteFilterBarConfigCache(name, resourceID) {
    await this.deleteConfigCache(name, resourceID, CONFIG_SOURCE.filterBar);
  }
  static validateResourceId(resourceId) {
    if (!resourceId)
      throw Error(this.LEGACY_CONFIG_NAME_ERROR_MESSAGE);
  }
  static handleLegacyConfig(configName, configSource, urlParams) {
    let legacyConfigName;
    switch (configSource) {
      case CONFIG_SOURCE.filterBar:
        legacyConfigName = this.filterBarLegacyConfig.get(configName);
        break;
      case CONFIG_SOURCE.grid:
        legacyConfigName = this.gridLegacyConfig.get(configName);
        break;
      case CONFIG_SOURCE.form:
        legacyConfigName = this.formLegacyConfig.get(configName);
    }
    const params = urlParams ? Object.assign({}, urlParams) : {};
    if (legacyConfigName) {
      params['legacyResourceID'] = legacyConfigName;
    }
    return params;
  }
  static handleLegacyConfigAsString(name, source) {
    const params = this.handleLegacyConfig(name, source);
    const legacyResourceID = params['legacyResourceID'];
    if (legacyResourceID) {
      name = name + `?legacyResourceID=${legacyResourceID}`;
    }
    return name;
  }
  static async deleteConfigCache(name, resourceID, source) {
    const cacheID = ConfigStorage.buildCacheID(name, source, resourceID);
    this.configById.delete(cacheID);
  }
  static buildCacheID(name, source, resourceID) {
    if (name == undefined) {
      return `req_${source}_${resourceID}`;
    }
    return `req_${source}_${name}_${resourceID}`;
  }
}
ConfigStorage.LEGACY_CONFIG_NAME_ERROR_MESSAGE = "LegacyConfigName precisa ser informado.";
ConfigStorage.filterBarLegacyConfig = new Map();
ConfigStorage.formLegacyConfig = new Map();
ConfigStorage.gridLegacyConfig = new Map();
ConfigStorage.configById = new Map();
ConfigStorage.filterBarConfigFetcher = new FilterBarConfigFetcher();
ConfigStorage.formConfigFetcher = new formConfigFetcher.FormConfigFetcher();
ConfigStorage.gridConfigFetcher = new GridConfigFetcher();
ConfigStorage.personalizedFilterFetcher = new PersonalizedFilterFetcher();

exports.ConfigStorage = ConfigStorage;
exports.PersonalizedFilterFetcher = PersonalizedFilterFetcher;
