import { D as DataFetcher } from './DataFetcher.js';
import { D as DataExporterOption } from './ISave.js';
import { SortMode, ApplicationContext, UserInterface, DateUtils, ObjectUtils, StringUtils, NumberUtils, DataType } from '@sankhyalabs/core';
import '@sankhyalabs/ezui/dist/collection/utils/constants';
import { UserInterface as UserInterface$1 } from '@sankhyalabs/core/dist/dataunit/metadata/UnitMetadata';
import { P as PreloadManager } from './dataunit-fetcher.js';
import './filter-item-type.enum.js';
import './form-config-fetcher.js';
import './constants.js';
import InMemoryFilterColumnDataSource from '@sankhyalabs/ezui/dist/collection/components/ez-grid/utils/InMemoryFilterColumnDataSource';
import { g as getSelectedRecordsIDsInfo } from './GetSelectedRecordsIDsInfo.js';
import { I as IExportType } from './snk-data-exporter2.js';
import { h } from '@stencil/core/internal/client';

class CrudUtils {
  static assertDefaultSorting(gridConfig, dataUnit) {
    if (gridConfig && dataUnit) {
      dataUnit.defaultSorting = gridConfig
        .columns
        .filter(col => col.ascending != undefined)
        .sort((colA, colB) => colA.orderIndex - colB.orderIndex)
        .map(({ name: field, ascending }) => {
        const { dataType } = dataUnit.getField(field);
        return { field, dataType, mode: ascending ? SortMode.ASC : SortMode.DESC };
      });
    }
  }
  static parseCrudResults(entities, onlyFirst) {
    if (!Array.isArray(entities)) {
      entities = [entities];
    }
    const crudFindResults = [];
    for (const entity of entities) {
      let crudFindResult = {
        fields: new Map()
      };
      for (let key in entity) {
        let fieldValue = entity[key];
        if (fieldValue.hasOwnProperty('$')) {
          crudFindResult.fields.set(key, fieldValue.$);
        }
        if (onlyFirst) {
          break;
        }
      }
      crudFindResults.push(crudFindResult);
    }
    return crudFindResults.length > 1 ? crudFindResults : crudFindResults[0];
  }
  static find(entityName, fields, criteria, onlyFirst = true, criteriaExpression, orderBy) {
    const SERVICE_CRUD_FIND = "mge@crud.find";
    let parsedFields = [];
    let parsedCriteria = [];
    let literalCriteria = {};
    let application = ApplicationContext.getContextValue("__SNK__APPLICATION__");
    if (fields) {
      if (!Array.isArray(fields)) {
        throw new Error(application.messagesBuilder.getMessage("crudUtils.errorArray", null));
      }
      fields.forEach((fieldName) => {
        parsedFields.push({
          name: fieldName
        });
      });
    }
    if (criteria) {
      for (const key in criteria) {
        if (criteria.hasOwnProperty(key)) {
          parsedCriteria.push({ nome: key, valor: criteria[key] });
        }
      }
    }
    if (criteriaExpression) {
      literalCriteria = {
        expression: {
          $: criteriaExpression
        }
      };
    }
    let request = {
      requestBody: {
        entity: {
          name: entityName,
          criterio: parsedCriteria,
          fields: {
            field: parsedFields
          },
          literalCriteria: literalCriteria,
          orderby: orderBy
        }
      }
    };
    return new Promise((resolve) => {
      DataFetcher.get().callServiceBroker(SERVICE_CRUD_FIND, JSON.stringify(request)).then((result) => {
        var _a;
        let entities = (_a = result.entidades) === null || _a === void 0 ? void 0 : _a.entidade;
        if (!entities) {
          resolve(null);
        }
        const crudFindResults = this.parseCrudResults(entities, onlyFirst);
        resolve(crudFindResults);
      });
    });
  }
}

class TaskbarProcessor {
  constructor(defaultButtons) {
    this._defaultButtons = defaultButtons;
  }
  process(taskbarId, taskbarManager, dataState, disabledButtons = [], invisibleButtons = []) {
    var _a;
    this.customButtons = new Map();
    this.buttons = "";
    this.disabledButtons = [].concat(disabledButtons);
    (_a = this.getButtonsArray(taskbarId, taskbarManager, dataState)) === null || _a === void 0 ? void 0 : _a.forEach(btnDef => {
      let buttonName;
      if (typeof btnDef === "string") {
        buttonName = btnDef;
      }
      else {
        const customBtn = btnDef;
        this.customButtons.set(customBtn.name, customBtn);
        buttonName = customBtn.name;
      }
      if (!invisibleButtons.includes(buttonName)) {
        if (!this.isEnabled(taskbarId, taskbarManager, buttonName, dataState, disabledButtons)) {
          this.disabledButtons.push(buttonName);
        }
        if (this.buttons.length > 0) {
          this.buttons += ",";
        }
        this.buttons += buttonName;
      }
    });
  }
  getButtonsArray(taskbarId, taskbarManager, dataState) {
    const defaults = this.getButtonsFromKey(taskbarId);
    if (taskbarManager) {
      return taskbarManager.getButtons(taskbarId, dataState, [...defaults]);
    }
    return defaults;
  }
  getButtonsFromKey(taskbarId) {
    const btnsValue = this._defaultButtons[taskbarId];
    return typeof btnsValue === 'function' ? btnsValue() : btnsValue;
  }
  isEnabled(taskbarId, taskbarManager, buttonName, dataState, disabled) {
    const originalValue = disabled.includes(buttonName) ? false : true;
    if (taskbarManager && taskbarManager.isEnabled) {
      return taskbarManager.isEnabled(taskbarId, dataState, buttonName, originalValue);
    }
    return originalValue;
  }
}

class SnkMultiSelectionListDataSource {
  setDataUnit(dataUnit) {
    this._dataUnit = dataUnit;
  }
  setApplication(application) {
    this._application = application;
  }
  formatLabel(fieldName, value) {
    const { userInterface } = this._dataUnit.getField(fieldName);
    if (userInterface === UserInterface.DATETIME) {
      return DateUtils.formatDate(this._dataUnit.valueFromString(fieldName, value));
    }
    return String(this._dataUnit.getFormattedValue(fieldName, value));
  }
  async getStaticOptions(fieldName, options) {
    if (fieldName == undefined) {
      return Promise.resolve(undefined);
    }
    return Promise.resolve(await PreloadManager.getDistinct(this._dataUnit, fieldName, options === null || options === void 0 ? void 0 : options.onlyLabel));
  }
  fetchData(filterTerm, fieldName) {
    return new Promise(resolve => {
      this._application.executeSelectDistinct(this._dataUnit, fieldName, filterTerm).then(result => {
        resolve(result.map(item => {
          const field = this._dataUnit.getField(fieldName);
          if (field.userInterface === UserInterface.SEARCH) {
            return Object.assign(Object.assign({}, JSON.parse(item)), { check: true });
          }
          return { value: item, label: this.formatLabel(fieldName, item), check: true };
        }));
      });
    });
  }
  sortItems(fieldName, items) {
    return InMemoryFilterColumnDataSource.defaultSorterMultSelectionOption(this._dataUnit, fieldName, items);
  }
}

class RmPrecisionCustomValueFormatter {
  setGrid(grid) {
    if (this._grid) {
      return;
    }
    this._grid = grid;
    this.refreshSelectedRows();
  }
  setDataState(dataState) {
    if (this._dataState && ObjectUtils.equals(dataState === null || dataState === void 0 ? void 0 : dataState.metadataByRow, this._dataState.metadataByRow)) {
      return;
    }
    this._dataState = dataState;
    this.refreshSelectedRows();
  }
  format(currentValue, column, recordId) {
    var _a;
    if (StringUtils.isEmpty(currentValue)) {
      return currentValue;
    }
    const rowMetadata = (_a = this._dataState) === null || _a === void 0 ? void 0 : _a.metadataByRow.get(recordId);
    const rmPrecision = rowMetadata === null || rowMetadata === void 0 ? void 0 : rowMetadata.getProp('rm_precision', column.name);
    if (rmPrecision || rmPrecision === 0) {
      return NumberUtils.format(currentValue, rmPrecision, rmPrecision);
    }
    const columnProps = column === null || column === void 0 ? void 0 : column.props;
    if (columnProps) {
      const precision = column === null || column === void 0 ? void 0 : column.props.get('precision');
      const prettyPrecision = column === null || column === void 0 ? void 0 : column.props.get('prettyPrecision');
      if (precision !== undefined && prettyPrecision !== undefined) {
        return NumberUtils.format(currentValue, precision, prettyPrecision);
      }
    }
    return currentValue;
  }
  refreshSelectedRows() {
    var _a;
    (_a = this._grid) === null || _a === void 0 ? void 0 : _a.refreshSelectedRows();
  }
}

class CommonsExporter {
  constructor(dataUnit, grid) {
    this.MAX_WIDTH_COD = 60;
    this.MIN_WIDTH_COD = 10;
    this.DEFAULT_FONT_SIZE = 13;
    this.dataUnit = dataUnit;
    this.grid = grid;
  }
  async getColumnsMetadata() {
    var _a;
    this.columnsState = await ((_a = this.grid) === null || _a === void 0 ? void 0 : _a.getColumnsState()) || [];
    return await this.buildColumnsMetadata(this.columnsState);
  }
  getColumnsState() {
    return this.columnsState;
  }
  async buildColumnsMetadata(gridColumns) {
    var _a;
    const columnsMetadata = [];
    const searchPlusDescriptionIds = this.collectSearchPlusDescriptionIds(gridColumns);
    for (const column of gridColumns) {
      if (this.isHiddenColumn(column)) {
        continue;
      }
      /**
       * A grid adiciona uma coluna auxiliar para a descrição de campos SEARCHPLUS
       * (ex.: "ENTITYNAME.DESCRIPTIONFIELD"). A descrição já é emitida ao processar
       * o próprio SEARCHPLUS, então pulamos a auxiliar para evitar duplicar a coluna.
       */
      if (searchPlusDescriptionIds.has(column.name)) {
        continue;
      }
      const fieldData = (_a = this.dataUnit) === null || _a === void 0 ? void 0 : _a.getField(column.name);
      const customFormatter = await this.grid.getCustomValueFormatter(column.name);
      const isSearchField = this.isSearchUserInterface(fieldData);
      const labelColumn = isSearchField ? "Cód. " : column.label;
      let columnData = {
        id: column.name,
        label: labelColumn,
        width: isSearchField ? (labelColumn.length * this.DEFAULT_FONT_SIZE) : column.width,
        type: fieldData === null || fieldData === void 0 ? void 0 : fieldData.dataType,
        userInterface: fieldData === null || fieldData === void 0 ? void 0 : fieldData.userInterface,
        customFormatter
      };
      let descriptionColumn = isSearchField ? this.buildDescriptionColumn(fieldData, column) : undefined;
      if (descriptionColumn) {
        const newWidth = this.getWidthByMetaData(column === null || column === void 0 ? void 0 : column.width, columnData === null || columnData === void 0 ? void 0 : columnData.width, descriptionColumn === null || descriptionColumn === void 0 ? void 0 : descriptionColumn.width);
        columnData = Object.assign(Object.assign({}, columnData), { width: newWidth === null || newWidth === void 0 ? void 0 : newWidth.codWidth });
        descriptionColumn = Object.assign(Object.assign({}, descriptionColumn), { width: newWidth === null || newWidth === void 0 ? void 0 : newWidth.descWidth, label: (descriptionColumn === null || descriptionColumn === void 0 ? void 0 : descriptionColumn.label) || (column === null || column === void 0 ? void 0 : column.label) });
      }
      columnsMetadata.push(columnData);
      if (descriptionColumn)
        columnsMetadata.push(descriptionColumn);
    }
    return columnsMetadata || [];
  }
  collectSearchPlusDescriptionIds(gridColumns) {
    var _a;
    const descriptionIds = new Set();
    for (const column of gridColumns) {
      if (this.isHiddenColumn(column)) {
        continue;
      }
      const fieldData = (_a = this.dataUnit) === null || _a === void 0 ? void 0 : _a.getField(column.name);
      if (!this.isSearchUserInterface(fieldData)) {
        continue;
      }
      const descriptionId = this.buildDescriptionColumnId(fieldData);
      if (descriptionId) {
        descriptionIds.add(descriptionId);
      }
    }
    return descriptionIds;
  }
  /**
   * TODO: Analisar e criar uma melhor forma de tratar essa validação do "RECDESP".
   */
  isHiddenColumn(column) {
    return column.hidden && column.name !== "RECDESP";
  }
  isSearchUserInterface(fieldData) {
    return (fieldData === null || fieldData === void 0 ? void 0 : fieldData.userInterface) === UserInterface$1.SEARCH
      || (fieldData === null || fieldData === void 0 ? void 0 : fieldData.userInterface) === UserInterface$1.SEARCHPLUS;
  }
  buildDescriptionColumnId(fieldData) {
    const properties = fieldData === null || fieldData === void 0 ? void 0 : fieldData.properties;
    if ((properties === null || properties === void 0 ? void 0 : properties.DESCRIPTIONFIELD) == undefined) {
      return undefined;
    }
    const descriptionField = `${properties.ENTITYNAME}.${properties.DESCRIPTIONFIELD}`;
    return properties.mergedFrom ? `${properties.mergedFrom}.${descriptionField}` : descriptionField;
  }
  buildDescriptionColumn(fieldData, column) {
    var _a;
    const id = this.buildDescriptionColumnId(fieldData);
    if (!id) {
      return undefined;
    }
    const labelDescription = (_a = fieldData === null || fieldData === void 0 ? void 0 : fieldData.properties) === null || _a === void 0 ? void 0 : _a.DESCRIPTIONENTITY;
    const widthColumnDefault = 60;
    return {
      id,
      label: labelDescription,
      width: labelDescription ? (labelDescription.length * this.DEFAULT_FONT_SIZE - widthColumnDefault) : column.width,
      type: DataType.TEXT,
      userInterface: UserInterface$1.LONGTEXT,
      descriptionFrom: fieldData.name
    };
  }
  getWidthByMetaData(maxWidth, widthCod, widthDescription) {
    const totalCurrentWidth = widthCod + widthDescription;
    const codPercentage = widthCod / totalCurrentWidth;
    const descPercentage = widthDescription / totalCurrentWidth;
    let newWidthCod = Math.round(maxWidth * codPercentage);
    let newWidthDescription = Math.round(maxWidth * descPercentage);
    if (newWidthCod > this.MAX_WIDTH_COD) {
      newWidthCod = this.MAX_WIDTH_COD;
      newWidthDescription = maxWidth - this.MAX_WIDTH_COD;
    }
    else if (newWidthCod < this.MIN_WIDTH_COD) {
      newWidthCod = this.MIN_WIDTH_COD;
      newWidthDescription = maxWidth - this.MIN_WIDTH_COD;
    }
    return {
      codWidth: newWidthCod,
      descWidth: newWidthDescription
    };
  }
}

class ClientSideExporterProvider extends CommonsExporter {
  getSelectedNumber() {
    return this.dataUnit.getSelectionInfo().length;
  }
  getTotalRecords() {
    var _a, _b, _c;
    const { total } = ((_a = this.dataUnit) === null || _a === void 0 ? void 0 : _a.getPaginationInfo()) || {};
    return total !== null && total !== void 0 ? total : (_c = (_b = this.dataUnit) === null || _b === void 0 ? void 0 : _b.records) === null || _c === void 0 ? void 0 : _c.length;
  }
  getSelectedIDs() {
    return getSelectedRecordsIDsInfo(this.dataUnit);
  }
  getRecordID() {
    var _a, _b, _c;
    return (_c = (_b = (_a = this.dataUnit) === null || _a === void 0 ? void 0 : _a.records) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.__record__id__;
  }
  async getRecords(exportType) {
    if (this.dataUnit.records.length === 0)
      return [];
    switch (exportType) {
      case IExportType.ALL:
        return this.dataUnit.getSelectionInfo().getAllRecords();
      case IExportType.SELECTION:
        return this.resolveRecordsFromSelection();
      case IExportType.PAGE:
        return this.dataUnit.records;
      default:
        return this.resolveRecordsFromSelection();
    }
  }
  resolveRecordsFromSelection() {
    const selectionInfo = this.dataUnit.getSelectionInfo();
    if (selectionInfo.isEmpty()) {
      return this.dataUnit.records;
    }
    const selectionRecords = selectionInfo.isAllRecords() ? selectionInfo.getAllRecords() : selectionInfo.records;
    return selectionRecords.length ? selectionRecords : this.dataUnit.records;
  }
  getHiddenOptions() {
    return [
      DataExporterOption.EXPORT_BY_EMAIL,
      DataExporterOption.EXPORT_PDF_TO_EMAIL,
      DataExporterOption.EXPORT_XLS_TO_EMAIL,
      DataExporterOption.EXPORT_PAGE_TO_PDF,
      DataExporterOption.EXPORT_PAGE_TO_XLS
    ];
  }
  formatValue(record, column) {
    const { id, descriptionFrom } = column;
    const value = record[descriptionFrom || id];
    if (value == undefined) {
      return "";
    }
    if (descriptionFrom != undefined) {
      return value.label;
    }
    const fieldDescriptor = this.dataUnit.getField(id);
    if (fieldDescriptor.userInterface === UserInterface.SEARCH) {
      return value.value;
    }
    if (column.customFormatter) {
      const ezGridColumn = this.getColumnsState().find(columnState => column.id === columnState.name);
      const formattedValue = column.customFormatter.format(value, ezGridColumn, record.__record__id__);
      return formattedValue;
    }
    return this.dataUnit.getFormattedValue(id, value);
  }
}

class ContinuousInsertUtils {
  constructor(snkApplication, resourceID, configName) {
    this.snkApplication = snkApplication;
    this.keyConfigEnableContinuousInsert = `${resourceID}enableContinuousInsert${configName ? configName : ''}`;
  }
  handleSaveConfig(enableContinuousInsert) {
    return this.snkApplication.saveConfig(this.keyConfigEnableContinuousInsert, enableContinuousInsert);
  }
  getConfig() {
    return this.snkApplication.getConfig(this.keyConfigEnableContinuousInsert).then(value => {
      if (value) {
        return value == "true" ? true : false;
      }
      return false;
    }).catch(() => {
      return false;
    });
  }
  getMessage(key, params) {
    var _a, _b;
    return (_b = (_a = this.snkApplication) === null || _a === void 0 ? void 0 : _a.messagesBuilder) === null || _b === void 0 ? void 0 : _b.getMessage(key, params);
  }
  actionContinuousInsert(enableContinuousInsert, handleEnableContinuousInsert) {
    return {
      value: StringUtils.generateUUID(),
      label: enableContinuousInsert ? this.getMessage('continuousInsertUtils.actions.disable') : this.getMessage('continuousInsertUtils.actions.enable'),
      enabled: true,
      itemBuilder: () => {
        return (h("div", { class: "ez-dropdown__item-wrapper", onClick: handleEnableContinuousInsert },
          h("span", { class: "ez-dropdown__item-label" }, enableContinuousInsert ? this.getMessage('continuousInsertUtils.actions.disable') : this.getMessage('continuousInsertUtils.actions.enable'))));
      },
    };
  }
}

export { CommonsExporter as C, RmPrecisionCustomValueFormatter as R, SnkMultiSelectionListDataSource as S, TaskbarProcessor as T, CrudUtils as a, ContinuousInsertUtils as b, ClientSideExporterProvider as c };
