var __rest = (this && this.__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;
};
import FilterItemType from '../../../../components/snk-filter-bar/filter-item/filter-item-type.enum';
import { ResourceFetcher } from './resource-fetcher';
import { ObjectUtils } from '@sankhyalabs/core';
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.MULTI_LIST === type) {
          const { label: _ } = item, 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;
}
export default class FilterBarConfigFetcher extends 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.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 = 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;
  }
}
