import { merge, mergeWith } from 'lodash';
import initialTables from '../config/initialTables';

const tablesData = {
  tables: initialTables,
};

const tablesActions = {
  cleanTable(tableName) {
    this.tables[tableName].rows.clear();
  },

  getTableRowValues(tableName, rowIndex, paramName) {
    let targetIndex = rowIndex;
    if (typeof rowIndex === 'function') {
      const rows = this.tables[tableName]?.rows;
      targetIndex = rowIndex(rows);
    }
    let values = {};
    const row = this?.tables?.[tableName]?.rows?.[targetIndex];
    if (!row) {
      return values;
    }
    const keys = Object.keys(row);

    let overridedValue;
    if (this.stores.calculationProcess.bypass[paramName]) {
      const { target, value } = this.stores.calculationProcess.bypass.status;
      if (target.indexOf(tableName) > -1) {
        overridedValue = value;
      }
    }

    for (let key of keys) {
      values[key] = overridedValue || row[key][paramName];
    }
    return values;
  },

  getTableRowValue(tableName, rowIndex, propName, paramName) {
    const values = this.getTableRowValues(tableName, rowIndex, paramName);
    return values[propName];
  },

  getTableOptions(tableName, propName) {
    return this.tables[tableName].options[propName];
  },

  replaceTableRows(tableName) {
    return rows => {
      this.tables[tableName].rows.replace(rows);
    };
  },

  setTableRows(tableName, startIndex, override) {
    return rows => {
      if (this?.tables[tableName]?.rows)
        for (
          let i = startIndex, j = 0;
          i < startIndex + rows.length;
          i++, j++
        ) {
          this.tables[tableName].rows[i] = mergeWith(
            this.tables[tableName].rows[i],
            rows[j],
            (obj, src, key) => {
              if (override) {
                return src;
              }
              return merge(obj, src);
            },
          );
        }
    };
  },

  setTableRow(tableName, rowIndex, override) {
    let targetIndex = rowIndex;
    if (typeof rowIndex === 'function') {
      const rows = this.tables[tableName]?.rows;
      targetIndex = rowIndex(rows);
    }
    return row => {
      this.setTableRows(tableName, targetIndex, override)([row]);
    };
  },

  setTableColumns(tableName, override) {
    return columnParams => {
      for (let paramsName in columnParams) {
        if (!override) {
          this.tables[tableName][paramsName] = merge(
            this.tables[tableName][paramsName],
            columnParams[paramsName],
          );
        } else {
          this.tables[tableName][paramsName] = columnParams[paramsName];
        }
      }
    };
  },
};

export default Object.assign(tablesData, tablesActions);
