<template>
  <div class="fullheight summary-setting">
    <el-form
      :inline="true"
      style="margin-bottom: 10px"
      :data-vv-scope="isViewList ? 'viewEdit' : 'summarySetting'"
    >
      <el-button
        type="primary"
        @click="add"
        icon="el-icon-plus"
        size="small"
        class="header-add"
        >添加</el-button
      >

      <el-table
        style="width: 100%"
        :data="summaryField"
        border
        class="summary-table"
      >
        <el-table-column label="汇总名称">
          <template slot-scope="scope">
            <ht-input
              v-model="scope.row.name"
              :maxlength="20"
              show-word-limit
              clearable
              validate="required"
            >
              <el-button
                icon="icon-guojihua"
                slot="append"
                style="width: 50px"
                @click="editI18nMessage(scope.row.field)"
              ></el-button>
            </ht-input>
          </template>
        </el-table-column>
        <el-table-column label="选择字段">
          <template slot-scope="scope">
            <ht-select
              v-if="isViewList"
              v-model="scope.row.field"
              :options="formatDisplayFieldList"
              validate="required"
              @change="change($event, scope.row)"
            >
              <template slot-scope="{options}">
                <el-option
                  v-for="result in options"
                  :key="result.name"
                  :label="result.desc"
                  :value="result.name"
                >
                  <span
                    >{{ result.desc }}({{ result.name }})({{
                      result.dataType
                    }})</span
                  >
                </el-option>
              </template>
            </ht-select>
            <ht-select
              v-else
              v-model="scope.row.field"
              :options="formatDisplayFieldList"
              validate="required"
              @change="change($event, scope.row)"
            >
              <template slot-scope="{options}">
                <el-option-group
                  v-for="group in options"
                  :key="group.name"
                  :label="group.desc"
                >
                  <el-option
                    v-for="result in group.fields"
                    :key="result.name"
                    :label="result.desc"
                    :value="result.name"
                  >
                    <span
                      >{{ result.desc }}({{ result.name }})({{
                        result.type
                      }})</span
                    >
                  </el-option>
                </el-option-group>
              </template>
            </ht-select>
          </template>
        </el-table-column>
        <el-table-column label="方法">
          <template slot="header">
            <span
              >方法
              <el-popover
                placement="top"
                trigger="hover"
                width="180"
                popper-class="button-popover"
                content="对当前页或所选数据进行汇总"
              >
                <i
                  slot="reference"
                  class="icon-notes note-icon"
                ></i> </el-popover
            ></span>
          </template>
          <template slot-scope="scope">
            <ht-select
              v-model="scope.row.method"
              :options="methods"
              validate="required"
              v-if="
                scope.row.type === 'number' ||
                  scope.row.type === 'bigint' ||
                  scope.row.type === 'numeric'
              "
            >
            </ht-select>
            <ht-select
              v-model="scope.row.method"
              validate="required"
              :options="strMethods"
              v-else
            >
            </ht-select>
          </template>
        </el-table-column>
        <el-table-column label="保留小数位">
          <template slot-scope="scope">
            <ht-input
              v-model="scope.row.decimal"
              type="number"
              :min="0"
              :max="5"
              v-if="
                (scope.row.type === 'number' ||
                  scope.row.type === 'bigint' ||
                  scope.row.type === 'numeric') &&
                  methods.map(m => m.key).indexOf(scope.row.method)
              "
              clearable
              placeholder="需要保留的小数位"
            />
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="是否汇总全部数据" align="center">
          <template slot="header">
            <span
              >是否汇总全部数据
              <el-popover
                placement="top"
                trigger="hover"
                width="180"
                popper-class="button-popover"
                content="数据量过大选择此项会影响性能"
              >
                <i
                  slot="reference"
                  class="icon-notes note-icon"
                ></i> </el-popover
            ></span>
          </template>
          <template slot-scope="{row}">
            <span v-if="row.field.startsWith('bpm_') || row.type === 'clob'"
              >-</span
            >
            <el-checkbox v-model="row.whetherSummarize" v-else></el-checkbox>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button type="text" @click="remove(scope.$index)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <div
      class="custom-summary"
      v-show="summaryField && summaryField.length > 0"
    >
      <div class="custom-summary__title">
        <el-popover
          placement="top"
          trigger="hover"
          width="600"
          popper-class="button-popover"
        >
          <div class="header-wrap">
            <h3 class="header-title">
              前端展示样式示例<el-button
                class="copy-button"
                v-clipboard:copy="examples"
                v-clipboard:success="copySuccess"
                >一键复制</el-button
              >
            </h3>
            <div>
              <codemirror
                ref="htmlCode"
                key="htmlCode"
                v-model="examples"
                :options="examplesOptions"
                class="examples-code"
              >
              </codemirror>
            </div>
          </div>
          <i slot="reference" class="icon-notes note-icon"></i>
        </el-popover>
        自定义汇总样式<span class="sub-title">默认使用表格布局样式</span>
      </div>
      <codemirror
        ref="htmlCode"
        key="htmlCode"
        v-model="summaryRegionHtml"
        :options="htmlOptions"
        class="summary-html-code"
      >
      </codemirror>
    </div>
    <i18n-message-edit
      ref="i18nMessageEdit"
      :messageKey="i18nMessageKey"
      @after-save="afterSaveI18n"
    />
  </div>
</template>

<script>
import utils from '@/hotent-ui-util.js'
import {Base64} from 'js-base64'
import i18nMessageEdit from '@/components/system/I18nMessageEdit.vue'

const CODE_MIRROR_OPTION = {
  value: '',
  mode: 'vue',
  smartIndent: true,
  tabSize: 2,
  theme: 'base16-light',
  lineNumbers: false, // 是否显示行数
  lineWrapping: true, // 是否自动换行
  styleActiveLine: true, // line选择是是否加亮
  matchBrackets: true, // 括号匹配
  line: true,
  autoRefresh: true,
  readOnly: true
}
export default {
  components: {
    i18nMessageEdit
  },
  name: 'summary-setting',
  props: {
    data: Object,
    isViewList: {
      type: Boolean,
      default: false
    },
    tabActiveName: {
      type: String
    }
  },
  data() {
    return {
      examples: `<template v-for="row in summaryResult" >
    <!--
      可使用变量：
        summaryResult(汇总结果数据)，summaryFields(汇总配置信息)
        currentPageRows(当前页数据)，currentSelectedRows(当前选择数据)
      summaryResult返回数据格式：
    [{
      //汇总方式key: selected-选择汇总 currentPage-当前页汇总 all-全部汇总
       key:"selected"
       nl:1 //配置的汇总字段
      project:"选择汇总"
     }] -->
    <el-row style="margin-bottom:24px;padding:0 20px" :key="row.key">
      <el-col :span="2">{{row.project}}</el-col>
      <el-col :span="22"><span
      v-for="item in summaryFields"
      :key="item.key"
      style="margin-right:24px">
      {{item.name}}:{{row[item.field] || '-'}}</span>
      </el-col>
    </el-row>
  </template>`,
      summaryRegionHtml: '',
      summaryField: [],
      displaySettingFields: [],
      resultFields: [],
      dataTemplate: {},
      examplesOptions: {
        value: ``,
        mode: 'vue',
        smartIndent: true,
        tabSize: 2,
        theme: 'base16-light',
        lineNumbers: false, // 是否显示行数
        lineWrapping: true, // 是否自动换行
        styleActiveLine: true, // line选择是是否加亮
        matchBrackets: true, // 括号匹配
        line: true,
        readOnly: true,
        autoRefresh: true
      },
      htmlOptions: {
        value: '',
        mode: 'vue',
        smartIndent: true,
        tabSize: 2,
        theme: 'base16-light',
        lineNumbers: false, // 是否显示行数
        lineWrapping: true, // 是否自动换行
        styleActiveLine: true, // line选择是是否加亮
        matchBrackets: true, // 括号匹配
        line: true,
        readOnly: false,
        autoRefresh: true
      },
      methods: [
        {key: 'count', value: '计数'},
        {key: 'sum', value: '求和'},
        {key: 'min', value: '最小值'},
        {key: 'max', value: '最大值'},
        {key: 'avg', value: '平均值'}
      ],
      strMethods: [{key: 'count', value: '计数'}],
      displayFieldList: [],
      formatDisplayFieldList: [],
      allShowData: [],
      i18nMessageKey: ''
    }
  },
  computed: {
    tableNameMap() {
      return this.displaySettingFields.reduce((pre, cur) => {
        pre[cur.name] = cur.desc
        return pre
      }, {})
    }
  },
  watch: {
    data: {
      handler(newVal, oldVal) {
        this.init()
        if (this.data.displaySettingFields && this.isViewList) {
          this.formatDisplayFieldList = this.formateShowData()
        }
      },
      deep: true,
      immediate: true
    },
    summaryField(val) {
      if (val && val.length === 0) {
        this.summaryRegionHtml = ''
      }
    },
    tabActiveName(val) {
      if (val && val === 'summarySetting') {
        this.htmlOptions = {
          value: this.summaryRegionHtml
        }
        if (this.data.bpmDataTemplate.summaryField) {
          this.summaryField = JSON.parse(this.data.bpmDataTemplate.summaryField)
        } else {
          this.summaryField = []
        }
      }
    }
  },
  methods: {
    getDisplayFieldList(isFilter) {
      let list = []
      for (const key in this.getDisplayFieldObj(isFilter)) {
        if (
          Object.hasOwnProperty.call(this.getDisplayFieldObj(isFilter), key)
        ) {
          list.push({
            name: key,
            desc: this.tableNameMap[key],
            fields: this.getDisplayFieldObj(isFilter)[key]
          })
        }
      }
      return list
    },
    getDisplayFieldObj(isFilter = false) {
      const formatList =
        utils
          .nest2tile(this.displayFieldList, 'children', true)
          .filter(item => {
            const isHeader =
              (item.id && item.id.startsWith('header_')) || item.children
            return (
              (!isHeader || !item.tableName) &&
              !item.customColumn &&
              item.tableName
            )
          }) || []
      const selectedFields =
        this.summaryField && this.summaryField.map(it => it.field)
      return formatList.reduce((pre, cur) => {
        const list = [...(pre[cur.tableName] || []), cur]
        pre[cur.tableName] = isFilter
          ? list.filter(item => !selectedFields.includes(item.name))
          : list
        return pre
      }, {})
    },
    copySuccess() {
      this.$message.success('复制成功')
    },
    add() {
      if (!this.summaryField) {
        this.summaryField = []
      }
      this.summaryField.push({
        name: '',
        method: '',
        field: '',
        type: '',
        decimal: '',
        whetherSummarize: false,
        mpDisplay: '2'
      })
      this.formatDisplayFieldList = this.isViewList
        ? this.formateShowData(true)
        : this.getDisplayFieldList(true)
    },
    remove(index) {
      this.summaryField.splice(index, 1)
    },
    getValidateSummaryResult() {
      return utils.validateForm(this, 'summarySetting')
    },
    saveSummaryField() {
      this.dataTemplate.summaryField =
        this.summaryField && this.summaryField.length
          ? JSON.stringify(this.summaryField)
          : null
      this.dataTemplate.summaryRegionHtml = Base64.encode(
        this.summaryRegionHtml
      )
      this.data.bpmDataTemplate = this.dataTemplate
    },
    change(name, row) {
      //切换字段，方法置空
      row.method = ''
      let result = {}
      const allDisplayFieldList = this.isViewList
        ? this.formateShowData()
        : this.getDisplayFieldList()
      for (let i = 0; i < allDisplayFieldList.length; i++) {
        const list = this.isViewList
          ? allDisplayFieldList
          : allDisplayFieldList[i].fields
        result = list.find(field => field.name === name)
        if (result) {
          this.$set(
            row,
            'type',
            this.isViewList ? result.dataType : result.type
          )
          this.$set(row, 'tableName', result.tableName)
          this.$set(row, 'mpDisplay', result.mpDisplay)
          break
        }
      }
      this.formatDisplayFieldList = this.isViewList
        ? this.formateShowData(true)
        : this.getDisplayFieldList(true)
    },
    init() {
      if (this.data.fields && this.data.fields.length) {
        this.displaySettingFields = this.data.fields
      }
      if (
        this.data.bpmDataTemplate.summaryField &&
        this.summaryField &&
        this.summaryField.length == 0
      ) {
        this.summaryField = JSON.parse(this.data.bpmDataTemplate.summaryField)
      }
      // else {
      //   this.summaryField = []
      // }
      if (this.dataTemplate.summaryRegionHtml) {
        this.summaryRegionHtml = Base64.decode(
          this.dataTemplate.summaryRegionHtml
        )
      }
      if (this.data.bpmDataTemplate.displayField) {
        this.displayFieldList = JSON.parse(
          this.data.bpmDataTemplate.displayField
        )
      }
    },
    formateShowData(isFilter = false) {
      let list = []
      if (this.data.displaySettingFields) {
        const data = JSON.parse(this.data.displaySettingFields)
        if (data && data.length) {
          list = data.map(item => {
            return {
              ...item,
              name: item.fieldName
            }
          })
        }
      }
      const selectedFields = this.summaryField.map(it => it.field)
      const filterList = list.filter(
        item => !selectedFields.includes(item.name)
      )
      list = isFilter ? filterList : list
      return list
    },
    /**
     * 国际化配置
     */
    editI18nMessage(columnField) {
      if (!columnField) {
        return this.$message.warning('请先选择字段！')
      }
      this.i18nMessageKey = `formTemplate.${this.dataTemplate.alias}.gather.${columnField}`
      this.$refs.i18nMessageEdit.handleOpen()
    },
    afterSaveI18n(data) {
      //保存后做一些数据处理
      data.key = data.key.replace('$', '#')
      this.dataTemplate.desc = data.key
      this.dataTemplate.desc_zh = data.desc
    }
  },
  mounted() {
    this.dataTemplate = this.data.bpmDataTemplate
    this.init()
    if (!this.isViewList) {
      this.formatDisplayFieldList = this.getDisplayFieldList()
    }
  }
}
</script>

<style lang="scss" scoped>
.header-add {
  padding: 8px 15px;
  margin-bottom: 16px;
}
.note-icon {
  color: #666666;
  font-size: 16px;
  &:hover {
    color: #409eff;
  }
}
.summary-setting {
  ::v-deep {
    .el-table {
      .cell {
        padding: 0 24px;
      }
      .el-select {
        width: 100%;
      }
      .el-input-number {
        .el-input-number__decrease,
        .el-input-number__increase {
          display: none;
        }
        .el-input__inner {
          width: 100%;
          text-align: left;
        }
      }
      .inputs {
        position: relative;
        div[aria-invalid='true'] {
          margin: 16px 0;
        }
        div[aria-invalid='true'] + .field-tail__wrap {
          text-align: left;
          position: absolute;
          top: calc(100% - 18px);
          left: 0;
          .el-form-item__error {
            top: calc(100% - 16px);
            position: static;
          }
        }
      }
    }
    .inputs.ht-form-inputs__inline {
      width: 100%;
    }
    .summary-html-code {
      .CodeMirror {
        height: 474px;
      }
    }
  }
  .custom-summary {
    margin-top: 34px;
    .custom-summary__title {
      margin-bottom: 8px;
      .sub-title {
        padding-left: 8px;
        font-size: 12px;
        color: #999;
      }
    }
  }
}
.header-wrap {
  .header-title {
    margin: 0 0 12px 0;
    font-size: 12px;
    color: #222;
  }
  .var-field {
    color: #999;
    padding-left: 8px;
  }
}
.copy-button {
  height: 20px;
  font-size: 12px;
  padding: 1px 6px;
  margin-left: 4px;
}
</style>
