<script>
import { exportData, getConfigByNameAsync, queryAll } from '@vue2-client/services/api/common'
import { formatDate } from '@vue2-client/utils/util'
import { exportJson } from '@vue2-client/utils/excel/Export2Excel'
import { Ellipsis } from '@vue2-client/components'
import PrintBill from '@vue2-client/base-client/components/common/XPrint/PrintBill.vue'
import hiPrintCss from '@vue2-client/base-client/components/common/XPrint/css/hiPrintCss'

export default {
  name: 'ExportExcel',
  components: { PrintBill, Ellipsis },
  data () {
    return {
      // 导出列选择
      exportModalVisible: false,
      summaryLoadingShow: false,
      tipMsg: '正在获取汇总数据。。。',
      exportType: false,
      type: 'export',
      modalTitle: '',
      selectedExportColumns: [],
      exportSelectedRows: false,
      allColumnsSelected: false,
      exportFileName: '',
      confirmLoading: null,
      printData: {},
      // 选中的查询条件字段名
      selectedQueryConditions: [],
      // 查询条件的 labelData 数据
      queryLabelData: null,
      // 自定义表头行数据
      customHeaders: [],
    }
  },
  inject: ['tableContext', 'getFormLabelData'],
  computed: {
    // 组合 tableColumns 与 excelImageExportTemplate 中的列，避免重复
    exportColumns () {
      const tableColumns = this.tableContext?.tableColumns || []
      const templateList = this.tableContext?.excelImageExportTemplate || []
      if (!Array.isArray(templateList) || !templateList.length) return tableColumns

      const existedKeys = new Set(tableColumns.map(column => column.dataIndex))
      const extraColumns = []

      templateList.forEach(item => {
        const columns = Array.isArray(item.column) ? item.column : []
        const titles = Array.isArray(item.title) ? item.title : []

        columns.forEach((colKey, index) => {
          if (!colKey || existedKeys.has(colKey)) return
          const colTitle = titles[index] || colKey
          extraColumns.push({
            dataIndex: colKey,
            title: colTitle,
            slotType: 'excelImageExportTemplate',
            defaultExport: false
          })
          existedKeys.add(colKey)
        })
      })

      return tableColumns.concat(extraColumns)
    }
  },
  methods: {
    // 导出选中或本页数据
    handleExport (type, title, customHeaders = []) {
      this.modalTitle = '选择导出列'
      this.exportFileName = title || '查询导出'
      this.type = 'export'
      this.customHeaders = customHeaders
      this.handle(type)
    },
    // 打印选中或本页数据
    handlePrint (type, printData) {
      this.modalTitle = '选择打印数据列'
      this.type = 'print'
      this.printData = printData
      this.customHeaders = []
      this.handle(type)
    },
    handle (type) {
      this.exportType = type
      this.confirmLoading = false
      this.exportModalVisible = true
      // 组织默认选中的字段
      this.selectedExportColumns = this.exportColumns
        .filter(column => column.slotType !== 'action' && column.defaultExport)
        .map(column => column.dataIndex)

      // 获取查询条件的 labelData，并默认全部选中
      if (this.getFormLabelData) {
        this.queryLabelData = this.getFormLabelData()
        // 默认全部选中所有查询条件字段（根据 labels 数组的索引）
        if (this.queryLabelData && this.queryLabelData.labels && this.queryLabelData.labels.length > 0) {
          this.selectedQueryConditions = this.queryLabelData.labels.map((_, index) => index)
        }
      }
    },
    handleGen () {
      const tHeader = this.exportColumns
          .filter(column => this.selectedExportColumns.includes(column.dataIndex))
          .map(column => column.title)
      const filterVal = this.exportColumns
          .filter(column => this.selectedExportColumns.includes(column.dataIndex))
          .map(column => column.dataIndex)
      this.confirmLoading = true
      if (this.type === 'export') {
       if (this.exportType === 'curPage' || this.exportType === 'selected') {
         this.handleExportCur(tHeader, filterVal, this.exportType === 'selected')
       } else if (this.exportType === 'exportByQuery') {
         this.handleExportByQuery(tHeader, filterVal)
       }
     } else {
       if (this.exportType === 'curPage' || this.exportType === 'selected') {
         this.handlePrintCur(tHeader, filterVal, this.exportType === 'selected')
       } else if (this.exportType === 'exportByQuery') {
         this.handlePrintByQuery(tHeader, filterVal)
       }
     }
    },
    // 打印选中或本页数据
    handlePrintCur (tHeader, filterVal, isSelected) {
      let exportData
      if (isSelected) {
        exportData = this.tableContext.selectedRows
      } else {
        exportData = this.tableContext.getTableData()
      }
      // 获取模板内容
      this.handlePrintGen(tHeader, filterVal, exportData)
    },
    // 打印查询结果
    async handlePrintByQuery (tHeader, filterVal) {
      try {
        const requestParameters = this.tableContext.requestParameters
        this.summaryLoadingShow = true
        this.tipMsg = '正在组织数据。。。'
        const res = await queryAll(Object.assign(requestParameters, { userId: this.tableContext.currUser?.id, pageSize: 200 }), this.tableContext.serviceName, this.tableContext.env === 'dev')
        this.handlePrintGen(tHeader, filterVal, res.data)
      } finally {
        this.confirmLoading = false
      }
    },
    // 获取模板内容
    handlePrintGen (tHeader, filterVal, exportData) {
      getConfigByNameAsync(this.tableContext.printTemplate, this.tableContext.serviceName).then(async res => {
        if (this.printData && this.printData.summary) {
          this.summaryLoadingShow = true
          this.tipMsg = '正在获取汇总数据。。。'
          this.printData.summaryData = {}
          const tempSummary = await this.printData.summary()
          tempSummary.forEach(row => {
            this.printData.summaryData[row.key] = row.value
          })
          this.summaryLoadingShow = false
        }
        // 如果模板中有默认表格 使用当前选中字段替换表格内容
        const crudTableIndex = res.panels[0].printElements.findIndex(h => h.printElementType?.type === 'table' && h.options.field === 'CRUD_TABLE')
        if (crudTableIndex !== -1) {
          console.log()
          res.panels[0].printElements[crudTableIndex].options.columns = [tHeader.map((title, index) => {
            return {
              colspan: 1,
              field: filterVal[index],
              columnId: filterVal[index],
              rowspan: 1,
              width: res.panels[0].printElements[crudTableIndex].options.width / tHeader.length,
              checked: true,
              fixed: false,
              title: title,
              tableSummary: this.tableContext.summaryData.find(item => item.title === title) ? 'sum' : undefined
            }
          })]
        }
        this.$nextTick(() => {
          console.log('打印数据预览', this.printData)
          this.$print(undefined, res, { ...this.printData, CRUD_TABLE: exportData }, {}, {
            callback: () => {
              this.confirmLoading = false
              this.closeModal()
              this.$emit('ok')
            },
            styleHandler: () => {
              this.confirmLoading = false
              return hiPrintCss()
            }
          })
        })
      }).finally(() => {
        this.confirmLoading = false
        this.summaryLoadingShow = false
      })
    },
    // 对字段值进行脱敏处理
    desensitizeValue (value) {
      if (value === null || value === undefined || value === '') return value
      const str = String(value)
      if (str.length <= 2) return str.replace(/./g, '*')
      if (str.length <= 6) return str[0] + '*'.repeat(str.length - 2) + str[str.length - 1]
      return str.slice(0, 3) + '****' + str.slice(-4)
    },
    // 导出选中或本页数据
    handleExportCur (tHeader, filterVal, isSelected) {
      let exportData
      if (isSelected) {
        exportData = this.tableContext.selectedRows
      } else {
        exportData = this.tableContext.getTableData()
      }
      if (tHeader.includes('序号')) {
        exportData = exportData.map((item, index) => ({
          ...item,
          序号: index + 1
        }))
      }
      const desensitizeFields = this.tableContext.exportDesensitizeFields || []
      if (desensitizeFields.length > 0) {
        exportData = exportData.map(row => {
          const newRow = { ...row }
          desensitizeFields.forEach(field => {
            if (Object.prototype.hasOwnProperty.call(newRow, field)) {
              newRow[field] = this.desensitizeValue(newRow[field])
            }
          })
          return newRow
        })
      }
      this.confirmLoading = false
      exportJson(tHeader, exportData.map(v => filterVal.map(j => v[j])), `${this.tableContext.title || ''}数据_${new Date().toLocaleString()}`)
    },
    // 导出符合条件的数据
    handleExportByQuery (tHeader, tDataList) {
      const that = this
      const conditionParams = Object.assign(that.tableContext.form, that.tableContext.fixedQueryForm)
      Object.keys(conditionParams).forEach(key => {
        if (Array.isArray(conditionParams[key])) {
          // 检查数组中是否包含 null
          const hasNull = conditionParams[key].every(item => item === '') || conditionParams[key].length === 0
          // 如果包含 null，则删除该属性
          if (hasNull) {
            delete conditionParams[key]
          }
        }
      })
      const dateTime = formatDate(new Date(), 'yyyy-MM-dd_hh-mm-ss')
      const fileNamePrefix = this.exportFileName || '查询导出'
      const name = `${fileNamePrefix}_${dateTime}`
      const queryData = this.buildDisplayText(this.queryLabelData?.labelData, this.queryLabelData?.labels, this.selectedQueryConditions)
      if (queryData) {
        this.customHeaders.push(queryData)
      }
      const param = {
        queryParamsName: this.tableContext.queryParamsName,
        queryParams: this.tableContext.queryParams,
        tHeader: tHeader,
        tDataList: tDataList,
        form: conditionParams,
        userId: this.tableContext.currUser.id,
        fileName: name,
        headerData: this.customHeaders
      }
      exportData(param, this.tableContext.serviceName).then(res => {
        this.closeModal()
        if (!res.isAsync) {
          let value = res.result
          if (this.tableContext.compatible === 'V4' && (Object.keys(res).length === 1 && Object.prototype.hasOwnProperty.call(res, 'value'))) {
            value = res.value
          }
          this.confirmLoading = false
          window.open(value)
        }
      })
    },
    closeModal () {
      this.exportModalVisible = false
    },
    // 新增的全选方法
    handleSelectAllColumns (e) {
      if (e.target.checked) {
        this.selectedExportColumns = this.exportColumns
          .filter(column => column.slotType !== 'action').map(column => column.dataIndex)
      } else {
        this.selectedExportColumns = []
      }
    },
    // 全选查询条件
    handleSelectAllQueryConditions (e) {
      if (e.target.checked && this.queryLabelData && this.queryLabelData.labels) {
        this.selectedQueryConditions = this.queryLabelData.labels.map((_, index) => index)
      } else {
        this.selectedQueryConditions = []
      }
    },
    // 校验文件名不能包含特殊字符
    validateFileName () {
      // 允许的字符：中文 字母 数字 下划线 - 点
      const regex = /^[a-zA-Z0-9_\-.\u4e00-\u9fa5]+$/
      if (!regex.test(this.exportFileName)) {
        this.$message.warn('文件名称仅仅支持包含中文、字母、数字、下划线、-和点')
        this.exportFileName = this.exportFileName.slice(0, -1)
      }
    },
    buildDisplayText(labelData, labels, indexArr) {
      if (!labelData || !labels || !Array.isArray(labels) || labels.length === 0 || indexArr.length === 0) {
        return null
      }

      const keys = Object.keys(labelData)

      const result = indexArr
        .filter(i => labels[i] && keys[i] && labelData[keys[i]] != null)
        .map(i => {
          const label = labels[i]
          let value = labelData[keys[i]]

          if (Array.isArray(value)) {
            value = value.join(', ')
          }

          return `${label}: ${value}`
        })
        .join('; ')

      return result || null
    }
  }
}
</script>

<template>
  <a-modal
    :title="modalTitle"
    width="35vw"
    :z-index="1001"
    :confirmLoading="confirmLoading"
    v-model="exportModalVisible"
    :destroy-on-close="true"
    @ok="handleGen"
  >
    <a-row v-if="type === 'export'" type="flex" style="padding-left: 3rem; padding-bottom: 1rem" align="middle">
      <a-col style="padding-right: 0.5rem">
        <span>文件名: </span>
      </a-col>
      <a-col>
        <a-input
          @change="validateFileName"
          placeholder="请输入导出文件名"
          v-model="exportFileName"
        />
      </a-col>
    </a-row>
    <!-- 导出列勾选区域 -->
    <div style="padding-left: 3rem">
      <a-row type="flex" justify="space-between" v-show="!summaryLoadingShow">
        <a-col :span="8" style="margin-top: 3px">
          <a-checkbox
            :checked="selectedExportColumns.length === exportColumns.length"
            @change="handleSelectAllColumns"
          >
            全选
          </a-checkbox>
        </a-col>
      </a-row>
      <a-checkbox-group v-model="selectedExportColumns" v-show="!summaryLoadingShow">
        <a-row type="flex" justify="space-between">
          <a-col
            :span="8"
            style="margin-top: 3px"
            v-for="column in exportColumns.filter(res => res.slotType !== 'action')"
            :key="column.dataIndex">
            <a-checkbox
              :label="column.title"
              :value="column.dataIndex"
            >
              <ellipsis :length="18" tooltip>
                {{ column.title }}
              </ellipsis>
            </a-checkbox>
          </a-col>
        </a-row>
      </a-checkbox-group>
    </div>
    <!-- 查询条件勾选区域 -->
    <div v-if="queryLabelData && queryLabelData.labels && queryLabelData.labels.length > 0" class="query-label">
      <a-row type="flex" style="padding-left: 3rem; padding-bottom: 1rem" align="middle" v-show="!summaryLoadingShow">
        <a-col style="padding-right: 0.5rem">
          <span>导出查询条件: </span>
        </a-col>
      </a-row>
      <div style="padding-left: 3rem">
        <a-row type="flex" justify="space-between" v-show="!summaryLoadingShow">
          <a-col :span="8" style="margin-top: 3px">
            <a-checkbox
              :checked="selectedQueryConditions.length === queryLabelData.labels.length && queryLabelData.labels.length > 0"
              @change="handleSelectAllQueryConditions"
            >
              全选
            </a-checkbox>
          </a-col>
        </a-row>
        <a-checkbox-group v-model="selectedQueryConditions" v-show="!summaryLoadingShow" style="width: 100%">
          <a-row type="flex" justify="space-between">
            <a-col
              :span="8"
              style="margin-top: 3px"
              v-for="(label, index) in queryLabelData.labels"
              :key="index">
              <a-checkbox
                :label="label"
                :value="index"
              >
                <ellipsis :length="18" tooltip>
                  {{ label }}
                </ellipsis>
              </a-checkbox>
            </a-col>
          </a-row>
        </a-checkbox-group>
      </div>
    </div>
    <a-row type="flex" justify="center" v-show="summaryLoadingShow">
      <a-spin :tip="tipMsg" v-show="summaryLoadingShow"/>
    </a-row>
  </a-modal>
</template>

<style scoped lang="less">
.query-label {
  border-top: 1px solid #f0f0f0; margin-top: 1rem; padding-top: 1rem;
  :deep(.ant-checkbox-group) {
    width: 100%;
    display: block;
  }
}
</style>
