var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { MapToComponentField, MapToComponentMethod, VegaSlimmer } from 'vega-slimmer/core';
import { isNonNullable } from '../../../../types/type-guard';
import { VegaTableSorter } from './vega-table-sorter';
/**
 * The sort controller for the vega-table
 */
export class VegaTableSortController extends VegaSlimmer {
  /**
   * The callback of [watchColumns]{@link VegaTable.watchColumns}
   */
  watchColumns() {
    this.syncSortOrder();
  }
  /**
   * The method for header cell sort click
   *
   * @param {VegaTableColumnConfig} column - The column for sorting
   * @param {VegaTableSortOrderType} nextSortOrder - The next sorter order
   */
  handleHeadSortClick(column, nextSortOrder) {
    if (this.sortConfig.type === 'single') {
      this.sortersMap.clear();
    }
    if (!nextSortOrder) {
      if (this.sortersMap.has(column.prop)) {
        this.sortersMap.delete(column.prop);
      }
    }
    else {
      this.sortersMap.set(column.prop, new VegaTableSorter(column.prop, nextSortOrder, column.sorter));
    }
    if (column.sorter !== 'event') {
      this.vegaTableDataSourceController.setCurrentData(this.sortData(this.vegaTableDataSourceController.getDataSource(), Array.from(this.sortersMap.values())));
    }
    this.changeEventEmitter.emit({
      sorters: Array.from(this.sortersMap.values()).map((s) => s.toExternalFormat()),
    });
  }
  /**
   * Sync the default sort order from the columns
   */
  syncSortOrder() {
    this.columns
      .filter((column) => isNonNullable(column.sorter) && isNonNullable(column.sortOrder))
      .forEach((item) => {
      this.sortersMap.set(item.prop, new VegaTableSorter(item.prop, item.sortOrder, item.sorter));
    });
  }
  /**
   * The method to sort the data by sorter which include prop name and order
   *
   * @param {VegaTableDataSourceItem[]} data - The source that will be sorted
   * @param {VegaTableSorter[]} sorters - array of sorters ordered by sequence of columns to be sorted
   * @returns {VegaTableDataSourceItem[]} The sorted data source
   */
  sortData(data, sorters) {
    return [...data].sort((a, b) => {
      for (const sorter of sorters) {
        const result = sorter.sort(a, b);
        if (isNonNullable(result)) {
          return result;
        }
      }
      return 0;
    });
  }
}
__decorate([
  MapToComponentField({ writable: true })
], VegaTableSortController.prototype, "sortersMap", void 0);
__decorate([
  MapToComponentField()
], VegaTableSortController.prototype, "columns", void 0);
__decorate([
  MapToComponentField()
], VegaTableSortController.prototype, "changeEventEmitter", void 0);
__decorate([
  MapToComponentField()
], VegaTableSortController.prototype, "vegaTableDataSourceController", void 0);
__decorate([
  MapToComponentField()
], VegaTableSortController.prototype, "sortConfig", void 0);
__decorate([
  MapToComponentMethod('watchColumns')
], VegaTableSortController.prototype, "watchColumns", null);
