<template>
  <div :class="$style.statistics">
    <a-card>
      <sd-statis-form
        ref="staticForm"
        :onl-list-column-defs="onlListColumnDefs"
        @changeChartType="changeChartType"
      ></sd-statis-form>

      <div :class="$style['act-btn']">
        <a-button type="primary" @click="search">统计</a-button>
        <a-dropdown>
          <a-menu slot="overlay">
            <a-menu-item key="1" @click="exportExcel">
              导出统计结果
            </a-menu-item>
            <a-menu-item v-if="exportColumn.length" key="2" @click="exportDetail">
              导出明细
            </a-menu-item>
          </a-menu>
          <a-button> 导出 <a-icon type="down" /> </a-button>
        </a-dropdown>
        <a-button @click="resetForm">重置</a-button>
      </div>
    </a-card>
    <a-card>
      <sd-echart :options="echartOption" :class="$style.echart" autoresize />
      <sd-table
        :key="updateKey"
        :class="$style['detail-table']"
        :columns="tableColumn"
        :data-source.sync="respData.data"
        :row-key="(record, index) => index"
        :pagination="false"
      >
        <a slot="count" slot-scope="text, record" @click="searchShowColumns(record)">{{ text }}</a>
      </sd-table>
    </a-card>
    <sd-statis-data-list ref="statisDatalist" />
    <a-spin :spinning="spinning" />
  </div>
</template>

<script>
import XLSX from 'xlsx'
import moment from 'moment'
import axios from '@/common/services/axios-instance'
import TableColumnTypes from '@/common/services/table-column-types'
import { message } from 'ant-design-vue'
import components from './_import-components/sd-business-statis-import'
import 'echarts/lib/chart/line'
import 'echarts/lib/chart/bar'
import 'echarts/lib/chart/pie'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/title'
function getStrCount(str) {
  let len = 0
  for (let i = 0; i < str.length; i++) {
    if (str.charCodeAt(i) > 127 || str.charCodeAt(i) === 94) {
      len += 2
    } else {
      len++
    }
  }
  return len
}

const lineEchartOption = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      crossStyle: {
        color: 'red',
      },
    },
  },
  xAxis: {
    type: 'category',
    data: [],
    axisPointer: {
      type: 'shadow',
    },
  },

  yAxis: {
    type: 'value',
    axisLabel: {
      formatter: '{value}',
    },
  },

  series: {
    type: 'line',
    label: {
      show: true,
      position: 'top',
    },
    data: [],
  },
}

const barEchartOption = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      crossStyle: {
        color: 'red',
      },
    },
  },
  xAxis: {
    type: 'category',
    data: [],
  },
  yAxis: {
    type: 'value',
  },
  series: {
    type: 'bar',
    barWidth: 30,
    label: {
      show: true,
      position: 'top',
    },
    data: [],
  },
}

const pieEchartOption = {
  tooltip: {
    trigger: 'item',
  },
  legend: {
    orient: 'vertical',
    left: 'left',
  },
  series: [
    {
      type: 'pie',
      data: [],
    },
  ],
}

export default {
  name: 'SdBusinessStatis',
  metaInfo() {
    return {
      title: this.title,
    }
  },
  components,
  data() {
    return {
      spinning: true,
      onlListColumnDefs: [],
      echartOption: {},
      pageId: '',
      formId: '',
      statisParam: {},
      respData: {
        data: [],
      },
      title: '',
      tableColumn: [],
      updateKey: 0,
      exportColumn: [],
      maxDetailCount: 0,
      showColumns: [],
    }
  },
  created() {
    this.initd()
  },
  methods: {
    searchShowColumns(record) {
      if (!this.showColumns.length) {
        message.warn('未配置统计列表，请前往统计配置-字段设置处进行勾选')
        return
      }
      this.$refs.staticForm.validateFields().then(() => {
        const formContent = this.$refs.staticForm.getSearchInput()
        this.$refs.statisDatalist.show({
          record,
          formContent,
          formId: this.formId,
          pageId: this.pageId,
          columns: this.showColumns,
          onlListColumnDefs: this.onlListColumnDefs,
        })
      })
    },
    resetForm() {
      this.$refs.staticForm.resetFields()
    },
    changeChartType(chartType) {
      this.showChart(chartType)
    },
    initd() {
      this.show(this.$route.query.headId)
    },
    search() {
      this.$refs.staticForm.validateFields().then(() => {
        const formContent = this.$refs.staticForm.getSearchInput()
        const aggregateColumns = formContent.dataColumns.map((item) => {
          return item.dataIndex
        })
        aggregateColumns.splice(0, 1)
        this.statisParam = formContent.statis
        this.groupField = formContent.groupField
        this.spinning = true
        axios
          .post('api/framework/v1/onlinerun/findStatisList', {
            ...formContent.statis,
            aggregateColumns: aggregateColumns.join(','),
            formId: this.formId,
          })
          .then((data) => {
            this.tableColumn = formContent.dataColumns.map((column) => {
              if (column.dataIndex === 'count') column.scopedSlots = { customRender: 'count' }
              return column
            })
            this.respData = data.data

            // 临时展示数据效果mock数据
            /*
            this.respData.data = [
              { gtlx: '人力资源类', gtje: 3200 },
              { gtlx: '其他类', gtje: 1800 },
              { gtlx: '合作类', gtje: 650 },
              { gtlx: '委托贷款类', gtje: 1200 },
              { gtlx: '对公贷款类', gtje: 8600 },
              { gtlx: '建筑工程类', gtje: 34580 },
              { gtlx: '担保类', gtje: 3000 },
              { gtlx: '理财业务类', gtje: 5800 },
              { gtlx: '票据业务类', gtje: 20500 },
              { gtlx: '租赁类', gtje: 4000 },
              { gtlx: '融资业务类', gtje: 7800 },
              { gtlx: '资产保全与风险化解类', gtje: 6000 },
              { gtlx: '采购类', gtje: 4000 },
              { gtlx: '银行卡业务类', gtje: 200 },
              { gtlx: '储蓄业务类', gtje: 12000 },
              { gtlx: '个人贷款类', gtje: 18000 },
            ]
            this.statisParam.groupByColumns = 'gtlx'
            this.statisParam.aggregateColumns = 'gtje'
            */

            this.showChart(formContent.chartType)
            this.updateKey++
            this.spinning = false
          })
      })
      // this.$emit('search', t)
    },
    showChart(chartType) {
      if (chartType === 'line' || chartType === 'bar') {
        this.echartOption = chartType === 'line' ? lineEchartOption : barEchartOption
        const series = []
        const seriesData = []
        this.respData.data.forEach((item) => {
          series.push(item[this.tableColumn[0].dataIndex])
          seriesData.push(item[this.statisParam.aggregateColumns])
        })
        this.echartOption.xAxis.data = series
        this.echartOption.series.data = seriesData
      } else {
        this.echartOption = pieEchartOption
        const seriesData = []
        this.respData.data.forEach((item) => {
          seriesData.push({
            name: item[this.tableColumn[0].dataIndex],
            value: item[this.statisParam.aggregateColumns],
          })
        })
        this.echartOption.series[0].data = seriesData
      }
    },
    exportExcel() {
      const table = this.$el.querySelector('table')
      const workbook = XLSX.utils.table_to_book(table, { raw: true })
      const widthInfos = []
      const sheet = workbook.Sheets[workbook.SheetNames[0]]
      // A1:H30 中的H30
      const lastCell = sheet['!ref'].split(':')[1]
      // H - A 来计算列数
      const columns = lastCell.substring(0, 1).codePointAt() - 'A'.codePointAt() + 1
      // H30 中的 30
      const rows = parseInt(lastCell.substring(1))
      for (let i = 0; i < columns; i++) {
        let maxChars = 0
        for (let j = 1; j <= rows; j++) {
          const cell = sheet[String.fromCodePoint('A'.codePointAt() + i) + j]
          // 一个中文字符等于2个英文字符
          maxChars = Math.max(getStrCount(cell.v.toString()), maxChars)
        }
        // 最宽50个字符
        widthInfos.push({ wch: Math.min(maxChars, 50) })
      }
      sheet['!cols'] = widthInfos
      const pageTitle = document.title.split('|')[0].trim() || 'export'
      XLSX.writeFile(workbook, pageTitle + '.xlsx')
      this.$emit('finish')
    },
    exportDetail() {
      const formContent = this.$refs.staticForm.getSearchInput()
      const params = {
        columns: this.exportColumn.map((item) => item.fieldId)?.join(),
        expressions: formContent?.statis?.expressions,
        formId: this.formId,
        maxResults: -1,
      }
      const groupByColumns = formContent?.statis?.groupByColumns
      if (groupByColumns !== 'undefined') {
        params.orderBy =
          groupByColumns.slice(
            0,
            groupByColumns.indexOf(':') === -1 ? groupByColumns.length : groupByColumns.indexOf(':')
          ) + ' asc'
      }
      axios.post('api/framework/v1/page/businessList', params).then((res) => {
        let data = res.data?.data
        if (data.length > this.maxDetailCount) data = data.slice(0, this.maxDetailCount)
        const exportColumnIds = this.exportColumn.map((item) => item.fieldId)
        const excelData = data.map((d) => {
          const newItem = {}
          exportColumnIds.forEach((f) => {
            const target = this.exportColumn.find((column) => column.fieldId === f)
            newItem[target.fieldName] =
              target.fieldType === 'date' && d[f]
                ? moment(d[f]).format(
                    target.attr?.showTime === 'true' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'
                  )
                : d[f]
          })
          return newItem
        })
        const pageTitle = document.title.split('|')[0].trim() || 'export'
        const ws = XLSX.utils.json_to_sheet(excelData)
        const wb = XLSX.utils.book_new()
        XLSX.utils.book_append_sheet(wb, ws)
        XLSX.writeFile(wb, pageTitle + '明细.xlsx')
      })
    },
    processReq(req) {
      req.method = 'get'
      return req
    },
    processRes(res) {
      return { datas: [], total: 0 }
    },
    show(id) {
      this.spinning = true
      axios.get(`api/framework/v1/onlinerun/getStatisConfig/${id}`).then((res) => {
        this.pageId = res.data.pageId
        this.formId = res.data.formId
        this.maxDetailCount = res.data.maxDetailCount
        this.onlListColumnDefs = res.data.onlStatisColumns.sort(
          (a, b) => a.statisOrderNum - b.statisOrderNum
        )
        this.exportColumn = res.data.onlStatisColumns.filter(
          (column) => column.isStatisExport === 1
        )
        this.showColumns = res.data.onlStatisColumns
          .filter((column) => column.isStatisDrill === 1)
          .map((m) => ({
            dataIndex: m.fieldId,
            title: m.fieldName,
            sdRender: m.fieldType === 'date' ? TableColumnTypes.dateTime : null,
          }))
        this.title = res.data.formName ? res.data.formName + '统计' : 'SdBusinessStatis'
        this.spinning = false
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;

.statistics {
  .echart {
    width: 100%;
  }

  .act-btn {
    float: right;
    button {
      margin-right: 20px;
    }
  }

  .detail-table {
    // display: none;
  }
}
</style>
