import { Action, ArrayUtils, DataType, DateUtils, FieldComparator, ObjectUtils, UserInterface, } from '@sankhyalabs/core';
import { ColumnFilterManager } from './ColumnFilterManager';
export default class InMemoryFilterColumnDataSource {
  constructor(dataUnit) {
    this.lastAppliedFilters = [];
    this.FILTER_COLUMN_TERM = 'FILTRO_COLUNA_';
    this.onDataUnitAction = (action) => {
      var _a, _b;
      if (action.type === Action.DATA_SAVED || action.type === Action.RECORDS_REMOVED) {
        this.originalRecords = this.dataUnit.records;
        return;
      }
      if (action.type !== Action.DATA_LOADED)
        return;
      const appliedFilters = this.getAppliedFilterNames((_b = (_a = action.payload) === null || _a === void 0 ? void 0 : _a.filters) !== null && _b !== void 0 ? _b : []);
      if (this.originalRecords && ObjectUtils.equals(appliedFilters, this.lastAppliedFilters))
        return;
      this.originalRecords = action.payload.records;
      this.lastAppliedFilters = appliedFilters;
    };
    this.dataUnit = dataUnit;
    if (this.dataUnit.records.length > 0) {
      this.originalRecords = this.dataUnit.records;
    }
    this.dataUnit.subscribe(this.onDataUnitAction);
  }
  refresh() {
    this.originalRecords = this.dataUnit.records;
  }
  getAppliedFilterNames(filters) {
    const appliedFilters = filters.map(filter => filter.name);
    return appliedFilters.filter(filterName => !filterName.includes(this.FILTER_COLUMN_TERM));
  }
  getStaticOptions(fieldName) {
    return Promise.resolve(ColumnFilterManager.compileDistinctFromArray(fieldName, this.dataUnit, this.originalRecords));
  }
  fetchData(filterTerm, fieldName) {
    return new Promise(resolve => {
      const filteredRecords = this.originalRecords.filter(record => this.includesSearchTerm(record, fieldName, filterTerm));
      const options = filteredRecords.map(item => this.buildFieldOption(item, fieldName));
      resolve(this.removeDuplicatedOptions(options));
    });
  }
  sortItems(fieldName, items) {
    return InMemoryFilterColumnDataSource.defaultSorterMultSelectionOption(this.dataUnit, fieldName, items);
  }
  buildFieldOption(item, fieldName) {
    return {
      value: this.buildValue(item, fieldName),
      label: this.formatLabel(fieldName, item[fieldName]),
      check: true,
    };
  }
  buildValue(item, fieldName) {
    var _a;
    let value = item[fieldName];
    if (((_a = this.dataUnit.getField(fieldName)) === null || _a === void 0 ? void 0 : _a.dataType) === DataType.OBJECT) {
      value = value.value;
    }
    return value === null || value === void 0 ? void 0 : value.toString();
  }
  removeDuplicatedOptions(options) {
    const noDuplicatedOptions = [];
    options.forEach(option => {
      if (!noDuplicatedOptions.find(({ label }) => label === option.label)) {
        noDuplicatedOptions.push(option);
      }
    });
    return noDuplicatedOptions;
  }
  includesSearchTerm(record, fieldName, filterTerm) {
    let label = this.buildLabel(fieldName, record[fieldName]);
    return label.toLowerCase().includes(filterTerm.toLowerCase());
  }
  buildLabel(fieldName, value) {
    var _a;
    const { dataType } = this.dataUnit.getField(fieldName);
    if (dataType === DataType.NUMBER) {
      return value === null || value === void 0 ? void 0 : value.toString().replace('.', ',');
    }
    if (dataType === DataType.DATE) {
      return (typeof value === 'object')
        ? (_a = DateUtils.formatDate(this.dataUnit.valueFromString(fieldName, value))) === null || _a === void 0 ? void 0 : _a.toString()
        : value === null || value === void 0 ? void 0 : value.toString();
    }
    if (dataType === DataType.OBJECT) {
      return `${value === null || value === void 0 ? void 0 : value.value} - ${value === null || value === void 0 ? void 0 : value.label}`;
    }
    return value === null || value === void 0 ? void 0 : value.toString();
  }
  formatLabel(fieldName, value) {
    var _a, _b;
    const { userInterface, dataType } = this.dataUnit.getField(fieldName);
    if (dataType === DataType.DATE) {
      return (typeof value === 'object')
        ? DateUtils.formatDate(this.dataUnit.valueFromString(fieldName, value))
        : value === null || value === void 0 ? void 0 : value.toString();
    }
    if (dataType === DataType.NUMBER && userInterface !== UserInterface.DECIMALNUMBER) {
      return (_a = parseInt(this.dataUnit.getFormattedValue(fieldName, value))) === null || _a === void 0 ? void 0 : _a.toString();
    }
    return (_b = this.dataUnit.getFormattedValue(fieldName, value)) === null || _b === void 0 ? void 0 : _b.toString();
  }
  static defaultSorterMultSelectionOption(dataUnit, fieldName, items) {
    const fieldDescriptor = dataUnit.getField(fieldName);
    if (fieldDescriptor == undefined) {
      return ArrayUtils.sortAlphabetically(items);
    }
    return items.sort((itemA, itemB) => {
      return FieldComparator.compareValues(fieldDescriptor, itemA.value, itemB.value);
    });
  }
}
