<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" @on-select-change="select"></Tree>
    </div>
    <template #footer>
      <div>
        <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, 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 + ')',
        children: convertList(item.columns, source, target)
      };
    });
  };

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

    groupColumns.forEach(groupColumn => {
      results.push({
        column: {
          code: groupColumn.property,
          name: groupColumn.property,
          dataType: groupColumn.dataType == 'DateTime' && groupColumn.dateTimeGroupType != 'Day' ? 'Integer' : groupColumn.dataType,
          columns: []
        },
        title: groupColumn.property + ' (' + 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 + ')',
            children: convertList(node.columns, objColumnExp, objProperty)
          });
        }
      }
    });

    return results;
  };

  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;
  };

  // 获取对象字段
  var getObjColumn = (code, data) => {
    for (let i = 0; i < data.length; i++) {
      if (data[i].column.code + 'ID' === code) {
        return data[i].column;
      }

      if (data[i].children) {
        let result = getObjColumn(code, data[i].children);
        if (result) {
          return result;
        }
      }
    }

    return null;
  };

  export default {
    mixins: [mixinPage],
    components: {},
    data() {
      return {
        data: [],
        opened: false,
        callback: null
      };
    },
    props: {},
    computed: {},
    methods: {
      // 打开字段选择
      open(model, callback) {
        dataViewApi.queryColumnByModel(model).then(data => {
          // if (columns && columns.length > 0) {
          //     data = data.filter(p => !columns.includes(p.code));
          // }
          this.data = convertList(data);
          this.opened = true;
        });

        this.callback = callback;
      },
      // 根据视图代码打开选择字段
      openViewCode(viewCode, callback) {
        dataViewApi.queryColumnByView(viewCode).then(data => {
          // if (columns && columns.length > 0) {
          //     data = data.filter(p => !columns.includes(p.code));
          // }
          this.data = convertList(data);
          this.opened = true;
        });

        this.callback = callback;
      },
      // 根据视图代码打开选择字段
      openDataSourceFilter(dataSource, callback) {
        dataViewApi.queryFilterByDataSource(dataSource).then(data => {
          this.data = convertList(data);
          this.opened = true;
        });

        this.callback = callback;
      },
      // 根据视图打开选择字段
      async openView(dataView, 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, groupColumns);
          } else {
            this.data = convertList(res);
          }

          // 聚合函数生成的字段
          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 + ')'
              // children: convertList(item.columns, columns, isGroupBy, groupColumns)
            });
          });
        } else {
          // 数据源
          let res = await dataViewApi.queryColumnByDataSource(dataView.dataSource);
          this.data = convertList(res);
        }

        this.opened = true;
        this.callback = callback;
      },
      select(selected, checked) {
        if (checked.children) {
          return;
        }

        let column = checked.column;
        // 外键字段
        if (column.dataType === 'BigInteger') {
          column.objColumn = getObjColumn(column.code, this.data);
        }

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