import VXETable from 'vxe-table'
import 'xe-utils'
import moment from "moment";

function _number_format(number, decimals) {
  /*
     * 参数说明：
     * number：要格式化的数字
     * decimals：保留几位小数
     * dec_point：小数点符号
     * thousands_sep：千分位e5a48de588b6e799bee5baa631333366306464符号
     * */
  const dec_point = '.';
  const thousands_sep = ',';
  number = (number + '').replace(/[^0-9+-Ee.]/g, '');
  let n = !isFinite(+number) ? 0 : +number;
  let prec = !isFinite(+decimals) ? 0 : Math.abs(decimals);
  let sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep;
  let dec = typeof dec_point === 'undefined' ? '.' : dec_point;
  let toFixedFix = function (n, prec) {
    let k = Math.pow(10, prec);
    return '' + Math.ceil(n * k) / k
  };
  let s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
  let re = /(-?\d+)(\d{3})/;
  while (re.test(s[0])) {
    s[0] = s[0].replace(re, '$1' + sep + '$2')
  }
  if ((s[1] || '').length < prec) {
    s[1] = s[1] || '';
    s[1] += new Array(prec - s[1].length + 1).join('0')
  }
  return s.join(dec)
}

// 创建一个简单的超链接渲染
VXETable.renderer.add('amount', {
  // 默认显示模板
  renderDefault(h, renderOpts, params) {
    let { row, column } = params;
    let value = '—';
    if (row[column.property]) {
      value = _number_format(row[column.property], 2, '.', ',') // 1,234,567.09
    }
    return [ <span class="state-amount">{ value }</span> ]
  }
});

/**
 * 格式化链接
 */
VXETable.renderer.add('cell-link', {
  renderDefault(h, renderOpts, params) {
    let { row, column } = params;
    let { events } = renderOpts;
    return [
      <a class="cell-link" onClick={ () => events.click ? events.click(row) : undefined }>
        { row[column.property] }
      </a>
    ]
  }
});
VXETable.renderer.add('multipleCell', {
  renderDefault(h, renderOpts, params) {
    const { column, row } = params
    let { multipleConfig } = renderOpts;
    return [
      <cms-multiple-field multipleConfig={ multipleConfig } column={ column } multipleRow={ row }/>
    ]
  }
});

/**
 * 格式化操作按钮
 */
VXETable.renderer.add('operateCell', {
  renderDefault(h, renderOpts, params) {
    let { row } = params;
    let { buttons } = renderOpts;
    buttons = buttons || [];
    const buttonComps = buttons.map(btn => {
      let btnProps = Object.assign({ type: 'text', size: 'small', visible: true }, btn.props || {})
      if (btn.props.visible) {
        btnProps.visible = btn.props.visible(row)
      }
      if (btnProps.disabled) {
        btnProps.disabled = btn.props.disabled(row)
      }
      const styles = {
        "margin": "0 5px",
        "padding": '0'
      }
      if (btnProps.visible) {
        return [
          <cms-link
            style={ styles }
            size={ "small" }
            v-permission-button={ btn.props.vPermissionButton }
            type={ btnProps.type }
            disabled={ btnProps.disabled }
            props={ btnProps }
            onClick={ () => btn.click ? btn.click(row) : undefined }>
            <i className={ btnProps.icon }/>
            { btn.title }
          </cms-link>
        ]
      }
      return []
    });
    return [
      <cms-button-group>
        { buttonComps }
      </cms-button-group>
    ]
  }
});

/**
 *
 */
VXETable.renderer.add('operateEdit', {
  // 默认显示
  renderCell(h, renderOpts, params) {
    let { row, $table } = params;
    let { buttons } = renderOpts;
    buttons = buttons || [];
    // 自定义方法
    const editRowEvent = async (row, btn) => {
      let onClick = btn.click;
      await $table.setActiveRow(row);
      onClick && onClick(row, btn);
    };
    // 自定义方法
    const customRowEvent = async (row, btn) => {
      let onClick = btn.click;
      onClick && onClick(row, btn);
    };
    // 编辑行同意统一处理方法
    const btnClickHandler = btn => {
      Promise.resolve().then(async () => {
        let active = $table.getActiveRecord();
        let errMap = null;
        if (active) {
          errMap = await $table.validate(active.row).catch(errMap => errMap);
        }
        if (!errMap) {
          switch (btn.tag) {
            case 'edit':
              await editRowEvent(row, btn);
              break;
            default:
              await customRowEvent(row, btn);
          }
        }
      });
    };
    const buttonComps = buttons.map(btn => {
      let btnProps = Object.assign({ type: 'text', size: 'small', visible: true }, btn.props || {})
      if (btn.props.visible) {
        btnProps.visible = btn.props.visible(row)
      }
      if (btnProps.disabled) {
        btnProps.disabled = btn.props.disabled(row)
      }
      const styles = {
        "margin": "2px"
      }
      if (btnProps.visible) {
        return [
          <cms-link
            style={ styles }
            v-permission-button={ btn.props.vPermissionButton }
            type={ btnProps.type }
            disabled={ btnProps.disabled }
            props={ btnProps }
            on-click={ e => {
              e.stopPropagation();
              btnClickHandler(btn);
            } }>
            <i className={ btnProps.icon }/>
            { btn.title }
          </cms-link>
        ]
      }
      return []
    });
    return [
      <cms-button-group>
        { buttonComps }
      </cms-button-group>
    ]
  },
  // 数据编辑
  renderEdit(h, renderOpts, params) {
    // 定义相关的操作方法
    const { row, $table } = params;
    // 获取按钮
    let { buttonEdits } = renderOpts;
    let buttons = buttonEdits || [];
    // 取消方法
    const cancelRowEvent = async (row, btn) => {
      let onClick = btn.click;
      await $table.clearActived();
      let operHandle;
      // 如果是新增状态就 删除 row
      if (row.row_status === 'add') {
        operHandle = $table.remove;
      } else {
        if (row.row_status === 'addEdit') {
          Object.assign(row, row.oldData);
        }
        // 如果编辑状态就还原 row
        operHandle = $table.revertData;
      }
      await operHandle(row);
      onClick && onClick(row, btn);
    };

    // 保存方法
    const saveRowEvent = async (row, btn) => {
      let onClick = btn.click;
      await $table.clearActived();
      const errMap = await $table.validate(row).catch(errMap => errMap);

      /**
       * 设置当前行数据: 应用编辑行通用下拉框， 通用放大镜
       * @param {Object} row
       * @param {String} property
       * @param {Object} value
       */
      function setRow(row, property, value) {
        XEUtils.set(row, property, value);
      }

      if (!errMap) {
        if (row.row_add) {
          let a = Object.assign({}, row);
          a.row_status = 'addEdit';
          row.oldData = a;
          setRow(row, 'row_status', 'addEdit');
        } else {
          setRow(row, 'row_status', 'edit'); // 改变当前行的状态
        }
        onClick && onClick(row, btn);
      }
    };
    // 自定义方法
    const customRowEvent = async (row, btn) => {
      let onClick = btn.click;
      await $table.clearActived();
      onClick && onClick(row, btn);
    };

    // 编辑行同意统一处理方法
    const btnClickHandler = btn => {
      switch (btn.tag) {
        case 'save':
          saveRowEvent(row, btn).then();
          break;
        case 'cancel':
          cancelRowEvent(row, btn).then();
          break;
        default:
          customRowEvent(row, btn).then();
      }
    };
    const buttonComps = buttons.map(btn => {
      let btnProps = Object.assign({ type: 'text', size: 'small', visible: true }, btn.props || {})
      if (btn.props.visible) {
        btnProps.visible = btn.props.visible(row)
      }
      if (btnProps.disabled) {
        btnProps.disabled = btn.props.disabled(row)
      }
      const styles = {
        "margin": "2px"
      }
      if (btnProps.visible) {
        return [
          <cms-link
            style={ styles }
            v-permission-button={ btn.props.vPermissionButton }
            type={ btnProps.type }
            disabled={ btnProps.disabled }
            props={ btnProps }
            on-click={ e => {
              e.stopPropagation();
              btnClickHandler(btn);
            } }>
            <i className={ btnProps.icon }/>
            { btn.title }
          </cms-link>
        ]
      }
      return []
    });
    return [
      <cms-button-group>
        { buttonComps }
      </cms-button-group>
    ]
  }
});

/**
 * 格式化常量显示
 */
VXETable.renderer.add('cell-format', {
  renderDefault(h, renderOpts, params) {
    let { row, column } = params;
    let defaultProps = { name: 'name', value: 'value' };
    let { events, parameter, styles, props, link } = renderOpts;
    defaultProps = Object.assign({}, defaultProps, props);
    const valueField = defaultProps['value'];
    const nameField = defaultProps['name'];
    // console.log('parameter===', parameter);
    // if (parameter) {
    //   Object.keys(parameter).forEach(key => {
    //     console.log(key, parameter[key]);
    //   })
    // }
    for (const pk in parameter) {
      if (parameter[pk][valueField] === row[column.property]) {
        let typeName;
        for (const type in styles) {
          if (styles.hasOwnProperty(type)) {
            if (styles[type] === row[column.property]) {
              typeName = type;
              break
            }
          }
        }
        if (styles) {
          if (link) {
            return [
              <a class="cell-link" onClick={ () => events && events.click ? events.click(row) : undefined }>
                <el-tag type={ typeName } effect="dark" size="small">
                  { parameter[pk][nameField] }
                </el-tag>
              </a>
            ]
          } else {
            return [
              <el-tag onClick={ () => () => events && events.click ? events.click(row) : undefined } type={ typeName }
                      effect="dark" size="small">
                { parameter[pk][nameField] }
              </el-tag>
            ]
          }

        } else {
          if (link) {
            return [
              <a class="cell-link" onClick={ () => events && events.click ? events.click(row) : undefined }>
                { parameter[pk][nameField] }
              </a>
            ]
          } else {
            return parameter[pk][nameField];
          }

        }
      }
    }
  }
});

// 自定义全局的格式化处理函数
VXETable.formats.mixin({
  // 格式化性别
  formatSex({ cellValue }) {
    return cellValue ? (cellValue === '1' ? '男' : '女') : ''
  },
  // 格式化下拉选项
  formatSelect({ cellValue }, list) {
    const item = list.find((item) => item.value === cellValue);
    return item ? item.label : ''
  },
  // 格式化日期，默认 yyyy-MM-dd HH:mm:ss
  formatDate({ cellValue }, format) {
    return moment(cellValue).format(format);
  },
  /**
   * 参数说明：
   * value：要格式化的数字
   * decimals：保留几位小数
   * sign: 金额符号
   */
  formatAmount(cellValue, decimals = 2, sign = '') {
    let number = (cellValue + '').replace(/[^0-9+-Ee.]/g, '');
    let n = !isFinite(+number) ? 0 : +number,
      prec = !isFinite(+decimals) ? 2 : Math.abs(decimals),
      s = '',
      toFixedFix = function (n, prec) {
        let k = Math.pow(10, prec);
        return '' + Math.round(n * k) / k;
      };

    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
    let re = /(-?\d+)(\d{3})/;
    while (re.test(s[0])) {
      s[0] = s[0].replace(re, '$1' + ',' + '$2');
    }
    if ((s[1] || '').length < prec) {
      s[1] = s[1] || '';
      s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return sign + s.join('.');
  },

  /**
   * 转化大写金额
   * @param cellValue
   * @returns {string}
   */
  formatAmountChies(cellValue) {
    let amount = cellValue;
    if (!amount) return '';
    // 汉字的数字
    const cnNums = [ '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' ];
    // 基本单位
    const cnIntRadice = [ '', '拾', '佰', '仟' ];
    // 对应整数部分扩展单位
    const cnIntUnits = [ '', '万', '亿', '兆' ];
    // 对应小数部分单位
    const cnDecUnits = [ '角', '分' ];
    // 整数金额时后面跟的字符
    const cnInteger = '整';
    // 整型完以后的单位
    const cnIntLast = '元';
    // 最大处理的数字
    const maxNum = 9999999999999999.99;
    // 金额整数部分
    let integerNum;
    // 金额小数部分
    let decimalNum;
    // 输出的中文金额字符串
    let chineseStr = '';
    // 分离金额后用的数组，预定义
    let parts;
    if (amount === '') {
      return '';
    }
    amount = parseFloat(amount);
    if (amount >= maxNum) {
      // 超出最大处理数字
      return '';
    }
    if (amount === 0) {
      chineseStr = cnNums[0] + cnIntLast + cnInteger;
      return chineseStr;
    }
    // 转换为字符串
    amount = amount.toString();
    if (amount.indexOf('.') === -1) {
      integerNum = amount;

      decimalNum = '';
    } else {
      parts = amount.split('.');
      integerNum = parts[0];
      decimalNum = parts[1].substr(0, 4);
    }
    // 获取整型部分转换
    if (parseInt(integerNum, 10) > 0) {
      let zeroCount = 0;
      const IntLen = integerNum.length;
      for (let i = 0; i < IntLen; i++) {
        const n = integerNum.substr(i, 1);
        const p = IntLen - i - 1;
        const q = p / 4;
        const m = p % 4;
        if (n === '0') {
          zeroCount++;
        } else {
          if (zeroCount > 0) {
            chineseStr += cnNums[0];
          }
          // 归零
          zeroCount = 0;
          //alert(cnNums[parseInt(n)])
          chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
        }
        if (m === 0 && zeroCount < 4) {
          chineseStr += cnIntUnits[q];
        }
      }
      chineseStr += cnIntLast;
    }
    // 小数部分
    if (decimalNum !== '') {
      const decLen = decimalNum.length;
      for (let i = 0; i < decLen; i++) {
        const n = decimalNum.substr(i, 1);
        if (n !== '0') {
          chineseStr += cnNums[Number(n)] + cnDecUnits[i];
        }
      }
    }
    if (chineseStr === '') {
      chineseStr += cnNums[0] + cnIntLast + cnInteger;
    } else if (decimalNum === '') {
      chineseStr += cnInteger;
    }
    return chineseStr;
  },
  // 格式化银行卡，默认每4位隔开
  formatBankcard({ cellValue }) {
    return XEUtils.commafy(cellValue, { spaceNumber: 4, separator: ' ' })
  },
  // 四舍五入,默认两位数
  formatFixedNumber({ cellValue }, digits) {
    return XEUtils.toNumber(cellValue).toFixed(digits || 2)
  },
  // 截取小数,默认两位数
  formatCutNumber({ cellValue }, digits) {
    return XEUtils.toFixed(cellValue, digits || 2)
  },
  // 转换 moment 类型为字符串
  toMomentString({ cellValue }, format) {
    return cellValue ? cellValue.format(format) : ''
  },
  /**
   * 格式化单元格
   * @param cellValue
   * @param column 列元素
   * @param data 集合对象
   * @param key 集合中的KEY
   * @param config 配置项 {field: 'xxxx', value: 'xxxxx'}
   */
  formatCell({ cellValue }, data, key, config) {
    if (data) {
      data = data[key]
    }
    if (!config) {
      // throw '缺少配置项，格式如下：{field: \'xxxx\', value: \'xxxxx\'}';
      config = { field: 'label', value: 'value' }
    }
    let name = "";
    if (data) {
      for (const index in data) {
        const item = data[index];
        if (item[config.value] === cellValue) {
          name = item[config.field];
          break;
        }
        try {
          if (parseInt(cellValue) === item[config.value]) {
            name = item[config.field];
            break;
          }
        } catch (e) {
        }
      }
    }
    if (!name) {
      name = cellValue;
    }
    return name;
  },
});

/**
 * 单元格的空值处理
 * @param {*} val 单元格的值
 * @param {*} text 当为空值时的替代文本
 */
function emptyText(val, text = '—') {
  if (val === undefined || val === null || val === '') {
    return {
      text: text,
      isEmpty: true
    };
  } else {
    return {
      text: val,
      isEmpty: false
    };
  }
}

export default VXETable;

export { VXETable, emptyText };