<template>
  <Modal v-model="opened" scrollable :mask-closable="layout.maskClosable" :draggable="layout.draggable" :sticky="true" :reset-drag-position="true" :width="800">
    <template #header>
      <div>
        <span class="title">{{ $t('Front_Label_Column_Select') }}</span>
        <span class="description">{{ $t('Front_Label_Column_Select_Desc') }}</span>
      </div>
    </template>
    <div class="ivu-ml-8 ivu-mr-8">
      <Tree :data="data" show-checkbox></Tree>
    </div>
    <template #footer>
      <div>
        <Button type="primary" custom-icon="fa fa-save" @click="finish">{{ $t('Front_Btn_OK') }}</Button>
        <Button type="default" custom-icon="fa fa-times" @click="close">{{ $t('Front_Btn_Close') }}</Button>
      </div>
    </template>
  </Modal>
</template>
<script>
  import mixinPage from '../../mixins/page';
  import dataViewApi from '../../api/dataView';

  // 转换为tree列表对象
  var convertList = (nodes, columns, source, target) => {
    if (!nodes) {
      return null;
    }

    return nodes.map(item => {
      let code = !!(source || '').trim() ? item.code.replace(source, target) : item.code;
      return {
        column: {
          code: code,
          name: item.name,
          dataType: item.dataType,
          columns: item.columns
        },
        title: item.name + ' (' + code + ')',
        checked: columns.some(column => {
          return column.code === item.code;
        }),
        children: convertList(item.columns, columns, source, target)
      };
    });
  };

  // 聚合属性列表对象
  var convertGroup = (nodes, columns, groupColumns) => {
    let results = [];

    groupColumns.forEach(groupColumn => {
      results.push({
        column: {
          code: groupColumn.property,
          name: groupColumn.property,
          dataType: groupColumn.dataType == 'DateTime' && groupColumn.dateTimeGroupType != 'Date' ? 'Integer' : groupColumn.dataType,
          columns: []
        },
        title: groupColumn.property + ' (' + groupColumn.property + ')',
        checked: columns.some(column => {
          return column.code === groupColumn.property;
        })
        // children: convertGroup(item.columns, columns, isGroupBy, groupColumns)
      });

      if (groupColumn.property.endsWith('ID')) {
        // 外键
        let objColumnExp = groupColumn.columnExp.substr(0, groupColumn.columnExp.length - 2);
        let objProperty = groupColumn.property.substr(0, groupColumn.property.length - 2);
        let node = findNode(nodes, objColumnExp);

        if (node != null) {
          // 找到外键节点
          results.push({
            column: {
              code: objProperty,
              name: node.name,
              dataType: node.dataType,
              columns: node.columns
            },
            title: node.name + ' (' + objProperty + ')',
            checked: columns.some(column => {
              return column.code === objProperty;
            }),
            children: convertList(node.columns, columns, objColumnExp, objProperty)
          });
        }
      }
    });

    return results;
  };

  // 获取选中项目
  var getChecked = data => {
    let checked = [];

    data.forEach(item => {
      if (item.checked) {
        // 外键字段
        if (item.column.dataType === 'BigInteger') {
          let obj = data.find(x => {
            return x.column.code + 'ID' === item.column.code;
          });
          if (obj) {
            item.column.objColumn = obj.column;
          }
        }

        checked.push({
          ...item.column
        });
      }

      if (item.children) {
        checked = checked.concat(getChecked(item.children));
      }
    });

    return checked;
  };

  var findNode = (nodes, columnExp) => {
    for (let i = 0; i < nodes.length; i++) {
      if (nodes[i].code == columnExp) {
        return nodes[i];
      }

      if (nodes[i].columns) {
        let node = findNode(nodes[i].columns, columnExp);
        if (node) {
          return node;
        }
      }
    }

    return null;
  };

  export default {
    mixins: [mixinPage],
    components: {},
    data() {
      return {
        data: [],
        columns: null,
        opened: false,
        callback: null
      };
    },
    props: {},
    computed: {},
    methods: {
      async open(dataView, columns, callback) {
        if (!dataView.isDataSource) {
          // 对象
          let res = await dataViewApi.queryColumnByModel(dataView.model);
          let groupColumns = [];
          let groupMethods = [];

          if (dataView.isGroupBy) {
            groupColumns = JSON.parse(dataView.groupColumn);
            groupMethods = JSON.parse(dataView.groupMethod);

            this.data = convertGroup(res, columns, groupColumns);
          } else {
            this.data = convertList(res, columns);
          }

          // 聚合函数生成的字段
          groupMethods.forEach(groupMethod => {
            this.data.push({
              column: {
                code: groupMethod.property,
                name: groupMethod.property,
                dataType: groupMethod.aggregateType == 'Count' ? 'Integer' : groupMethod.aggregateType == 'Avg' ? 'Double' : groupMethod.dataType
              },
              title: groupMethod.aggregateType + (groupMethod.aggregateType == 'Count' ? '' : ' - ' + groupMethod.columnExp) + ' (' + groupMethod.property + ')',
              checked: columns.some(column => {
                return column.code === groupMethod.property;
              })
              // children: convertList(item.columns, columns, isGroupBy, groupColumns)
            });
          });
        } else {
          // 数据源
          let res = await dataViewApi.queryColumnByDataSource(dataView.dataSource);
          this.data = convertList(res, columns);
        }

        this.opened = true;
        this.columns = columns;
        this.callback = callback;
      },
      finish() {
        let checked = getChecked(this.data);

        this.callback(checked);
        this.opened = false;
      },
      close() {
        this.opened = false;
      }
    }
  };
</script>
