import { UserInterface } from '@sankhyalabs/core/dist/dataunit/metadata/UnitMetadata';
import { DataType } from '@sankhyalabs/core';
export 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.SEARCH
      || (fieldData === null || fieldData === void 0 ? void 0 : fieldData.userInterface) === UserInterface.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.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
    };
  }
}
