

export default class ColumnManager {
  constructor(columns, context) {
    this.firstTd = null;
    this.lastTd = null;
    this.hasBind = false;
    this.scrollTarget = null;
    this.vColumns = []
    this.columns = columns;
    this._cached = {};
    this.width = -1;
    this.x_start = 0;
    this.x_end = columns.length;
    this.translateX = 0
    this.context = context
    this.direction = "right";
    this.$nextTick = context.$nextTick
    this._scrollWidth=void 0
  }
  set scrollWidth(value) {

    if (value > 0) {

      this.context.$el.dispatchEvent(new Event('scrollResize'));

    }
    this._scrollWidth=value
  }

  get scrollWidth() {
    return this._scrollWidth
  }


  isAnyColumnsFixed() {
    const { vScrollX } = this.context
    return vScrollX?.enabled||this._cache('isAnyColumnsFixed', () => this.columns.some(column => !!column.fixed));
  }


  isAnyColumnsLeftFixed() {
    //console.log('isAnyColumnsLeftFixed',1)

    return this._cache('isAnyColumnsLeftFixed', () =>
      this.columns.some(column => column.fixed === 'left' || column.fixed === true),
    );
  }

  isAnyColumnsRightFixed() {
    //console.log('isAnyColumnsRightFixed',2)

    return this._cache('isAnyColumnsRightFixed', () =>
      this.columns.some(column => column.fixed === 'right'),
    );
  }


  leftColumns() {
    return this._cache('leftColumns', () => {
      let leftColumns = this.columns.filter(column => column.fixed === 'left' || column.fixed === true)
      return leftColumns
    }

    );
  }
  rightColumns() {

    return this._cache('rightColumns', () => {

      let rightColumns = this.columns.filter(column => column.fixed === 'right');

      return rightColumns
    }

    );
  }





  leafColumns() {

    return this._cache('leafColumns', () => this._leafColumns(this.columns));

  }

  leftLeafColumns() {
    return this._cache('leftLeafColumns', () => this._leafColumns(this.leftColumns()));
  }


  rightLeafColumns() {

    return this._cache('rightLeafColumns', () => this._leafColumns(this.rightColumns()));
  }

  // add appropriate rowspan and colspan to column
  groupedColumns() {
    let _this = this
    return this._cache('groupedColumns', () => {
      const _groupColumns = (columns, currentRow = 0, parentColumn = {}, rows = []) => {

        // track how many rows we got
        rows[currentRow] = rows[currentRow] || [];
        const grouped = [];
        const setRowSpan = column => {
          const rowSpan = rows.length - currentRow;
          if (
            column &&
            !column.children && // parent columns are supposed to be one row
            rowSpan > 1 &&
            (!column.rowSpan || column.rowSpan < rowSpan)
          ) {
            column.rowSpan = rowSpan;
          }
        };
        const { x_start, x_end } = this;
        // let firstI = 0, lastI = columns.length - 1
        let leftColumns = _this.leftColumns(), rightColumns = _this.rightColumns()

        for (let i = x_start; i < x_end; i++) {
          const column = columns[i];



          let index = i;

          const newColumn = { ...column };

          rows[currentRow].push(newColumn);
          parentColumn.colSpan = parentColumn.colSpan || 0;
          if (newColumn.children && newColumn.children.length > 0) {
            newColumn.children = _groupColumns(newColumn.children, currentRow + 1, newColumn, rows);
            parentColumn.colSpan += newColumn.colSpan;
          } else {
            parentColumn.colSpan += 1;
          }

          // update rowspan to all same row columns
          for (let i = 0; i < rows[currentRow].length - 1; i += 1) {
            setRowSpan(rows[currentRow][i]);
          }
          // last column, update rowspan immediately
          if (index + 1 === columns.length) {
            setRowSpan(newColumn);
          }

          //grouped.push(newColumn);
          if (!newColumn.fixed) {
            _this.vColumns.push(newColumn);
          }
        }

        return [...leftColumns, ..._this.vColumns, ...rightColumns];
      }
      this.vColumns = []
      let cols = _groupColumns(this.columns);


      return cols


    });
  }

  columnsUpdate() {
    this.vColumns = []
    this.columns = this.context.columns;
    this.scrollWidth = void 0;
    this.width = -1;
    this.translateX = 0
  }
  reset(columns) {
    this.columns = columns;
    this.vColumns = []
    //this.context.initRun=false
    this._cached = {};

  }

  _cache(name, fn) {
    if (name in this._cached) {
      return this._cached[name];
    }

    this._cached[name] = fn();
    return this._cached[name];
  }


  _leafColumns(columns) {
    const leafColumns = [];
    columns.forEach(column => {
      if (!column.children) {
        leafColumns.push(column);
      } else {
        leafColumns.push(...this._leafColumns(column.children));
      }
    });
    return leafColumns;
  }




}
