<template>
  <div class="table-page">
    <div class="table-page-content">
      <div class="left-tree">
        <tree-side
          ref="treeSide"
          :dataLoading="treeLoading"
          :default-expand-all="false"
          :defaultProps="defaultProps"
          :tabList="['组织路段树']"
          :treeData="treeData"
          isDeselect
          @currentChange="currentChange"
        ></tree-side>
      </div>
      <div class="right-table">
        <div class="full-page bg">
          <div class="search-box">
            <div class="search-box-combination">
              <div class="search-box-label">预警时间：</div>
              <div class="">
                <el-date-picker
                  v-model="params.querys[4].value"
                  end-placeholder="预警时间"
                  range-separator="至"
                  start-placeholder="预警时间"
                  style="width: 360px"
                  type="datetimerange"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  :default-time="['00:00:00', '23:59:59']"
                  @change="datePickerChange"
                >
                </el-date-picker>
              </div>
              <div class="search-box-label">预警状态：</div>
              <div class="">
                <el-select
                  v-model="params.querys[5].value"
                  filterable
                  placeholder="请选择预警状态"
                  style="width: 120px"
                  @change="statusPickerChange"
                >
                  <el-option
                    v-for="item in statusList"
                    :key="item.value"
                    :label="item.name"
                    :value="item.value"
                  >
                  </el-option>
                </el-select>
              </div>
              <SearchCommon :optionList="optionList" @search="handleSearch" />
            </div>
          </div>
          <div class="main-table-container">
            <div class="table-container" style="padding: 20px">
              <div ref="btnPanel" class="btn-box">
                <el-button
                  :disabled="!isAddShow"
                  class="btn btn-plus"
                  icon="el-icon-plus"
                  size="small"
                  type="primary"
                  @click="changePage('EditAddPage', {roadId: treeItem.id})"
                >
                  添加
                </el-button>
                <el-button
                  :disabled="!currentDataDel.length"
                  class="btn btn-delete"
                  icon="el-icon-delete"
                  plain
                  size="small"
                  type="danger"
                  @click="handleDelete()"
                >
                  删除
                </el-button>
                <el-popover
                  v-model="isShowPopover"
                  placement="bottom-start"
                  popper-class="import-popover"
                  trigger="click"
                >
                  <div class="popover-container">
                    <div class="popover-container-title">
                      <div class="popover-container-title-left">
                        <i class="el-icon-warning" /> 提示：
                      </div>
                      <div
                        class="popover-container-title-right"
                        @click="isShowPopover = false"
                      >
                        <i class="el-icon-close" />
                      </div>
                    </div>
                    <div class="popover-container-content">
                      请下载预警模版并完成模版文件的填写录入后，导入已录入信息的模版文件。
                    </div>
                    <div class="popover-container-btn">
                      <el-button
                        :loading="downloadLoading"
                        class="btn btn-plus"
                        icon="el-icon-download"
                        plain
                        size="small"
                        type="primary"
                        @click="downloadTemplate"
                      >
                        下载模版
                      </el-button>

                      <el-upload
                        ref="upload"
                        :action="action"
                        :before-upload="beforeUpload"
                        :data="uploadData"
                        :headers="headers"
                        :multiple="false"
                        :on-error="handleError"
                        :on-success="handleSuccess"
                        :show-file-list="false"
                      >
                        <el-button
                          :disabled="!isAddShow"
                          :loading="uploadLoading"
                          class="btn btn-plus"
                          icon="el-icon-upload2"
                          plain
                          size="small"
                          type="warning"
                        >
                          导入模版
                        </el-button>
                      </el-upload>
                    </div>
                  </div>
                  <template v-slot:reference>
                    <el-button
                      class="btn btn-plus"
                      icon="el-icon-upload"
                      size="small"
                      style="margin: 0 10px"
                      type="warning"
                    >
                      导入
                    </el-button>
                  </template>
                </el-popover>
                <el-button
                  :loading="downloadLoading"
                  class="btn btn-plus"
                  icon="el-icon-download"
                  size="small"
                  type="success"
                  @click="exportData"
                >导出
                </el-button>
                <el-button
                  :disabled="!currentDataDel.length || hasPubStatusOne"
                  class="btn btn-delete"
                  icon="el-icon-folder-checked"
                  size="small"
                  type="primary"
                  @click="batchConfirmation()"
                >
                  批量确认
                </el-button>
              </div>
              <div ref="tableRef" class="table-content">
                <el-table
                  ref="multipleSelection"
                  v-loading="tableLoading"
                  :data="tableData"
                  :default-sort="{prop: 'warningTime', order: 'descending'}"
                  :max-height="tableMaxHeight"
                  border
                  class="table-list"
                  element-loading-background="rgba(10 ,38 ,61, 0.9)"
                  row-key="id"
                  stripe
                  @select="handleSelection"
                  @selection-change="handleSelectionChange"
                  @row-dblclick="handleDbClick"
                >
                  <el-table-column :selectable='checkboxInit' align="center" type="selection" width="55" />
                  <el-table-column
                    align="center"
                    label="序号"
                    type="index"
                    width="60"
                  />
                  <el-table-column
                    :formatter="({roadName}) => roadName || '-'"
                    align="center"
                    label="所属路段"
                    min-width="80"
                    prop="roadName"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    :formatter="({regionalName}) => regionalName || '-'"
                    align="center"
                    label="所属区域"
                    min-width="80"
                    prop="regionalName"
                    show-overflow-tooltip
                  />
                  <!-- <el-table-column
                    :formatter="
                      ({direction}) =>
                        dictionaryEscape('yxjc-fx', direction + '')
                    "
                    align="center"
                    label="方向"
                    min-width="60"
                    prop="direction"
                    show-overflow-tooltip
                  /> -->
                  <el-table-column
                    align="center"
                    label="开始桩号"
                    min-width="80"
                    prop="pegSVal"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    align="center"
                    label="结束桩号"
                    min-width="80"
                    prop="pegEVal"
                    show-overflow-tooltip
                  />
                  <!-- <el-table-column
                    align="center"
                    label="预警信息来源"
                    min-width="80"
                    prop="publishDeviceName"
                    show-overflow-tooltip
                  /> -->
                  <el-table-column
                    :formatter="
                            ({publishDeviceType}) =>
                              dictionaryEscape('yxjc-fbsblx', publishDeviceType + '')
                          "
                    align="center"
                    label="发布设备类型"
                    min-width="80"
                    prop="publishDeviceType"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    :formatter="
                            ({warningLevel}) =>
                              dictionaryEscape('yxjc-yjdj', warningLevel + '')
                          "
                    align="center"
                    label="预警等级"
                    min-width="80"
                    prop="warningLevel"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    :formatter="
                            ({warningType}) =>
                              dictionaryEscape('yxjc-yjlx', warningType + '')
                          "
                    align="center"
                    label="预警类型"
                    min-width="80"
                    prop="warningType"
                    show-overflow-tooltip
                  />
                  <el-table-column
                    :formatter="({warningTime}) => warningTime || '-'"
                    align="center"
                    label="预警时间"
                    min-width="120"
                    prop="warningTime"
                    show-overflow-tooltip
                    sortable
                  />
                  <el-table-column
                    :formatter="({relieveWarningTime}) => relieveWarningTime || '-'"
                    align="center"
                    label="预警解除时间"
                    min-width="120"
                    prop="relieveWarningTime"
                    show-overflow-tooltip
                    sortable
                  />
                  <el-table-column
                    align="center"
                    label="预警状态"
                    min-width="80"
                    prop="pubStatus"
                  >
                    <template slot-scope="scope">
                      <div
                        :style="{
                                color: scope.row.pubStatus ? '#67c23a' : '#e6a23c'
                              }"
                      >
                        {{ scope.row.pubStatus ? '已确认' : '未确认' }}
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column
                    align="center"
                    label="操作"
                    min-width="140"
                    show-overflow-tooltip
                  >
                    <template v-slot="{row}">
                      <el-link
                        v-if="!row.pubStatus"
                        :underline="false"
                        type="primary"
                        @click="handleDbClick(row)"
                      >
                        发布
                      </el-link>
                      <el-link
                        :underline="false"
                        type="primary"
                        @click="handleDetailPage(row)"
                      >
                        详情
                      </el-link>
                      <el-link
                        :underline="false"
                        type="danger"
                        @click="handleDelete(row)"
                      >
                        删除
                      </el-link>
                    </template>
                  </el-table-column>
                </el-table>
                <pagination
                  ref="paginationPanel"
                  :pageResult="params.pageBean"
                  style="margin-top: 10px"
                  @size-change="handleSizeChange"
                  @current-change="handleCurrentChange"
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <batchDialog
      :is-show.sync="batchDialog"
      :list-id="currentDataDel"
      @change="batchChange"
    ></batchDialog>
  </div>
</template>

<script>
import {refineRequestBody, setQueryValue} from '@/utils/requestWrappers'
import pagination from '@/components/SuperPagination/index.vue'
import {TableMixin} from '@/mixins/tableMixin'
import treeSide from '@/components/treeSide/index.vue'
import SearchCommon from '@/components/SearchCommon/index.vue'
import {
  downloadModel,
  exportFile,
  tableData,
  tableDelete
} from '@/api/patrolAndRescue/operationalMonitoring/informatiOnForAttention'
import PubSub from 'pubsub-js'
import {dictionaryEscape, getDictionaryByCode} from '@/utils/dictionary'
import {mapState} from 'vuex'
import moment from 'moment'
import batchDialog from '../batchDialog.vue'
import {getTree} from '@/api/tree'

export default {
  name: 'TablePage',
  components: {
    batchDialog,
    pagination,
    treeSide,
    SearchCommon
  },
  mixins: [TableMixin],
  data() {
    return {
      batchDialog: false,
      statusList: [
        {
          name: '全部',
          value: ''
        },
        {
          name: '已确认',
          value: 1
        },
        {
          name: '未确认',
          value: 0
        }
      ],
      isAddShow: false,
      pubSub: null,
      tableMaxHeight: '600px',
      loading: false,
      treeLoading: true,
      tableLoading: false,
      treeData: [], //左边树
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      tableData: [],
      currentDataDel: [],
      optionList: [
        // {title: '所属路段', prop: 'roadName', type: 'input', default: true},
        {
          title: '预警等级',
          prop: 'warningLevel',
          type: 'select',
          option: getDictionaryByCode('yxjc-yjdj'),
          multiple: true,
          default: true
        },
        // {
        //   title: '方向',
        //   prop: 'direction',
        //   type: 'select',
        //   option: getDictionaryByCode('yxjc-fx'),
        //   multiple: true
        // },
        {
          title: '预警类型',
          prop: 'warning_type_',
          type: 'select',
          option: getDictionaryByCode('yxjc-yjlx'),
          multiple: true
        },
        {
          title: '发布设备类型',
          prop: 'publishDeviceType',
          type: 'select',
          option: getDictionaryByCode('yxjc-fbsblx'),
          multiple: true
        }
      ],
      params: {
        pageBean: {pageSize: 20, page: 1, total: 0},
        querys: [
          {operation: 'IN', property: 'roadId'},
          // {
          //   group: 'quick',
          //   operation: 'LIKE',
          //   relation: 'OR',
          //   property: 'roadName'
          // },
          {
            group: 'quick',
            operation: 'IN',
            relation: 'AND',
            property: 'warningLevel'
          },
          {
            group: 'quick',
            operation: 'IN',
            relation: 'AND',
            property: 'warning_type_'
          },
          {
            group: 'quick',
            operation: 'IN',
            relation: 'AND',
            property: 'publishDeviceType'
          },
          {
            operation: 'BETWEEN',
            property: 'warning_time_',
            value: [
              moment().subtract(1, 'month')
                .startOf('month')
                .format('YYYY-MM-DD HH:mm:ss'),
              moment()
                .endOf('month')
                .format('YYYY-MM-DD HH:mm:ss')
            ]
          },
          {
            operation: 'IN',
            relation: 'AND',
            property: 'PUB_STATUS_',
            value: ''
          }
        ],
        sorter: [
          {
            property: 'createTime',
            direction: 'DESC'
          }
        ]
      },
      treeDialog: false, // 科目信息弹层
      treeItemId: '', // 树形目录id
      treeItem: {}, // 树形节点选中对象
      isShowPopover: false,
      downloadLoading: false,
      uploadLoading: false,
      statusShow: 2,
      hasPubStatusOne: true
    }
  },
  computed: {
    actionUrl: _ => window.context.portal,
    uploadData() {
      return {
        belongAreaId: this.treeItem.orgId,
        roadId: this.treeItem.id
      }
    },
    action() {
      return `${this.actionUrl}/monitor/bizEarlyWarningManagement/v1/importExcel`
    },
    ...mapState({
      headers: state => ({
        Authorization: `Bearer ${state.login.currentUser.token}`
      })
    })
  },
  created() {
    // 获取树形目录-
    this.getOrgTreeData(treeData => {
      // 回调中默认选中第一项并将其id作为参数请求表格
      this.treeItem = treeData[0] || {}
      let array = []
      if (this.treeItem.children.length > 0) {
        array = this.extractIds(this.treeItem)
      }
      if (this.$route.query && this.$route.query.publishId) {
        this.$nextTick(_ => {
          this.$refs.treeSide?.setCurrentKey(this.$route.query.publishId)
          this.$refs.treeSide?.expandHandle(true, 2)
        })
        let roadList = this.collectAllChildIds(treeData, this.$route.query.publishId)
        setQueryValue(this.params, 'roadId', roadList)
        this.loadData()
      } else {
        this.$nextTick(_ => {
          this.$refs.treeSide?.setCurrentKey(treeData[0]?.id)
          this.$refs.treeSide?.expandHandle(true, 2)
        })
        setQueryValue(this.params, 'roadId', array)
        this.loadData()
      }
    })
  },
  mounted() {
    this.pubSub = PubSub.subscribe('TablePage', (_, data) => {
      switch (data.type) {
        case 'add':
          this.params.pageBean.page = 1
          this.loadData()
          break
        case 'edit':
          this.loadData()
          break
      }
    })
  },
  methods: {
    dictionaryEscape,
    collectAllChildIds(tree, targetId) {
      const result = []
      let isCollecting = false

      function traverse(nodes) {
        nodes?.forEach(node => {
          if (node.id === targetId) isCollecting = true
          if (isCollecting) result.push(node.id)
          traverse(node.children)
          if (node.id === targetId) isCollecting = false
        })
      }

      traverse(Array.isArray(tree) ? tree : [])
      return [...new Set(result)] // 去重 没有 筛选不出来
    },
    // 递归遍历函数
    extractIds(node) {
      let ids = []
      // 如果当前节点有 children，则递归提取
      if (node.children) {
        ids = node.children.map(child => child.id) // 提取当前节点的 id
        // 递归提取子节点的 id
        node.children.forEach(child => {
          ids = ids.concat(this.extractIds(child))
        })
      }
      return ids
    },
    handleSelectionChange(val) {
      this.hasPubStatusOne = val.some(item => item.pubStatus === 1)
      this.currentDataDel = val.map((item) => item.id)
    },
    checkboxInit(row, index) {
      // if (row.pubStatus) {
      //   return 0 //不可勾选
      // } else {
      return 1
      // }
    },
    batchChange() {
      this.params.pageBean.page = 1
      this.loadData()
    },
    batchConfirmation() {
      this.batchDialog = true
    },
    // 状态切换
    statusPickerChange(val) {
      setQueryValue(this.params, 'PUB_STATUS_', val)
      this.params.pageBean.page = 1
      this.loadData()
    },
    // 时间范围切换
    datePickerChange(val) {
      setQueryValue(this.params, 'warning_time_', val)
      this.params.pageBean.page = 1
      this.loadData()
    },
    // 获取公司树-异步方法，用于从后端获取树形数据
    async getOrgTreeData(callback) {
      try {
        this.treeLoading = true //开始加载时显示加载状态
        let {value} = await getTree() // 调用 API 获取树形数据
        this.treeData = [value]
      } finally {
        this.treeLoading = false // 无论成功或失败，都关闭加载状态
        callback && callback(this.treeData) // 如果提供了回调函数，则调用它并传入树形数据
      }
    },
    transformTreeData(data) {
      return {
        name: data.name,
        id: data.id,
        children: data.children.reduce((acc, child) => {
          acc.push({
            id: child.id,
            name: child.name,
            path: child.path,
            children: child.roadList.map(road => ({
              id: road.id,
              name: road.name,
              path: road.path
            }))
          })
          return acc
        }, [])
      }
    },
    //左边树节点
    currentChange(nodeItem) {
      if (nodeItem.id === '1766017468444450816') {
        this.isAddShow = false
        setQueryValue(this.params, 'roadId ', this.extractIds(nodeItem))
      } else if (nodeItem.children && nodeItem.children.length > 0) {
        this.isAddShow = false
        const array = nodeItem.children.map(item => item.id)
        setQueryValue(this.params, 'roadId ', array)
      } else {
        this.isAddShow = true
        setQueryValue(this.params, 'roadId ', [nodeItem?.id] || [])
      }
      // if (nodeItem.children && nodeItem.children.length > 0) {
      //   this.isAddShow = false
      //   const array = nodeItem.children.map(item => item.id)
      //   setQueryValue(this.params, 'roadId ', array)
      // } else {
      //   this.isAddShow = true
      //   setQueryValue(this.params, 'roadId ', [nodeItem?.id] || [])
      // }
      this.treeItem = nodeItem || {}
      this.calcTableHeight(500)
      PubSub.publish('TreeItemSelected', {
        id: nodeItem?.id || '',
        name: nodeItem?.name || '',
        path: nodeItem?.path || ''
      })
      this.params.pageBean.page = 1
      this.loadData()
    },
    //获取数据
    async loadData() {
      this.tableLoading = true
      const {total = 0, rows = []} = await tableData(
        refineRequestBody(this.params)
      )
      this.params.pageBean.total = total
      this.tableData = rows.map(row => ({
        ...row,
        roadName: row.roadName || this.treeItem.name
      }))
      this.tableLoading = false
    },

    // 下载导入模版
    downloadTemplate() {
      this.downloadLoading = true
      downloadModel()
        .then(_ => this.$message.success('预警信息模板成功'))
        .finally(_ => {
          this.downloadLoading = false
          this.isShowPopover = false
        })
    },

    async exportData() {
      this.downloadLoading = true
      let param = JSON.parse(JSON.stringify(this.params))
      param.pageBean = {
        pageSize: -1, page: 1, total: 0
      }
      param.querys.push({
        group: 'quick',
        operation: 'IN',
        relation: 'AND',
        property: 'id',
        value: this.currentDataDel
      })
      try {
        await exportFile(refineRequestBody(param))
        this.$message.success(`数据导出成功`)
      } finally {
        this.downloadLoading = false
      }
    },

    // 文件上传前
    beforeUpload(file) {
      return new Promise((resolve, reject) => {
        this.uploadLoading = true
        const {size, name} = file
        this.$confirm(`请确认是否导入 “${name}” ？`, '提示', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(_ => {
            let passedOrNot = true // 是否通过验证
            const maxSize = 500 * 1024 * 1024 // 20MB
            const typeRegular = /\.(xls|xlsx)$/i
            const verification = [
              {
                condition: !typeRegular.test(name),
                result: () => this.$message.error('只能上传xls或xlsx文件类型')
              }
              // {
              //   condition: size > maxSize,
              //   result: () => this.$message.error('附件大小不能超过500MB')
              // }
            ]
            verification.forEach(item => {
              if (item.condition) {
                item.result()
                passedOrNot = false
                this.uploadLoading = false
              }
            })
            passedOrNot ? resolve() : reject()
            this.isShowPopover = passedOrNot
          })
          .catch(_ => {
            reject()
            this.isShowPopover = true
            this.uploadLoading = false
            this.$message.warning('已取消排班上传')
          })
      })
    },

    // 文化上传成功
    handleSuccess() {
      this.$message.success('预警导入成功')
      this.uploadLoading = false
      this.isShowPopover = false
      this.loadData()
    },

    // 文件上传失败
    handleError(err) {
      let errMessage = ''
      if (err && err.message) {
        const {message} = JSON.parse(err.message)
        errMessage = message
      }
      this.$message.error(errMessage || '预警导入失败，请重试')
      this.uploadLoading = false
      this.isShowPopover = false
    },

    // 删除
    handleDelete(row) {
      this.clickTimer = true
      this.$confirm('确定删除选中预警信息吗？', '提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          let ids = row ? row.id : this.currentDataDel.join()
          let {state, message} = await tableDelete(ids)
          if (state) {
            this.$message.success(`预警信息删除成功`)
            const {page, pageSize, total} = this.params.pageBean
            const totalPages = Math.ceil(total / pageSize) // 计算总页数
            if (totalPages > 1 && page === totalPages) {
              if (this.tableData.length === 1) {
                // 当前页只有一条数据
                this.params.pageBean.page -= 1 // 返回前一页
              }
            }
            await this.loadData()
          } else {
            this.$message.error(message)
          }
        })
        .catch(_ => _)
    },

    //修改
    handleDbClick(row) {
      if (this.clickTimer) return (this.clickTimer = false)
      const payload = {
        ...row,
        roadName: row.roadName || this.treeItem.name
      }
      this.changePage('EditAddPage', payload)
    },

    // 改变页面
    changePage(pageName = '', row = {}) {
      if (!pageName) return
      const payload = row.id
        ? row
        : {
          roadId: this.treeItem.id,
          roadName: this.treeItem.name,
          path: this.treeItem.path
        }
      this.$emit(
        'changePage',
        pageName,
        _ => {
          PubSub.publish(pageName, payload)
        },
        row.id ? '编辑' : '添加'
      )
    }
  },
  beforeDestroy() {
    // 在组件销毁之前 清除订阅消息
    PubSub.unsubscribe(this.pubSub)
  }
}
</script>

<style lang="scss" scoped>
.search-box-label {
  color: #ffffff;
}
</style>
