<template>
  <!-- 人员选择弹层 -->
  <super-dialog v-bind="$attrs" v-model="isShowDialog" :width="width" :modal="false" :top="top" @open="open"
    @closed="closed">
    <div class="super-table-selector-dialog" :style="{ height }">
      <div class="tree-module" v-if="isShowTree">
        <tree-side :activeName="treeActiveTabName" v-bind="$attrs" :tabList="treeTabList" :data-loading="treeLoading"
          :treeData="treeData" :default-expand-all="false" isDeselect :defaultProps="treeOptions" :nodeKey="treeKey"
          @tabChange="treeTabChange" @currentChange="currentChange" ref="treeSide"></tree-side>
      </div>
      <div class="table-module">
        <div class="search-content" v-if="isShowSearch">
          <SearchCommon @search="handleSearch" :optionList="searchOption" ref="searchCommon" />
        </div>
        <div class="table-content" ref="tableRef">
          <el-table stripe v-loading="tableLoading" element-loading-background="rgba(10 ,38 ,61, 0.9)"
            ref="multipleSelection" :data="enhancedTableData" :row-key="row => row[selectKey]"
            :max-height="tableMaxHeight" border @row-click="row => tableRowClick(row, !row.checked)"
            :row-class-name="rowClassName" @sort-change="e => $emit('sort-change', e)">
            <el-table-column width="60" align="center" v-if="!isSingleChoice && isShowTableCheckbox">
              <template v-slot:header>
                <el-checkbox :indeterminate="tableIsIndeterminate" v-model="tableCheckAll"
                  :disabled="isSingleChoice || enhancedTableData.every(i => i.disabled)" />
              </template>
              <template v-slot:default="{ row }">
                <el-checkbox :disabled="row.disabled" v-model="row.checked" />
              </template>
            </el-table-column>
            <el-table-column type="index" width="60" label="序号" align="center" :index="index =>
                index +
                1 +
                (tableParams.pageBean.page - 1) *
                tableParams.pageBean.pageSize
              " />
            <el-table-column v-for="item in tableOptions" :key="item.prop" :prop="item.prop" show-overflow-tooltip
              :min-width="item.minWidth" align="center" :label="item.label" :formatter="row => (item.formatter ? item.formatter(row) : row[item.prop])
                " :sortable="item.sortable ? 'custom' : false" />
          </el-table>
          <div class="table-content-bottom" v-if="!isShowSelect">
            <pagination ref="paginationPanel" style="margin-top: 10px" :pageResult="tableParams.pageBean"
              @size-change="handleSizeChange" @current-change="handleCurrentChange" v-if="isShowPagination" />
            <div class="btn-box">
              <el-button size="small" @click="isShowDialog = false">
                取 消
              </el-button>
              <el-button :disabled="tableLoading" size="small" type="primary" @click="confirm">
                确 定
              </el-button>
            </div>
          </div>
          <pagination v-if="isShowSelect && isShowPagination" ref="paginationPanel" style="margin-top: 10px"
            :pageResult="tableParams.pageBean" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
        </div>
      </div>
    </div>
  </super-dialog>
</template>

<script>
import SuperDialog from '@/components/SuperDialog/index.vue'
import treeSide from '@/components/treeSide/index.vue'
import { setQueryValue } from '@/utils/requestWrappers'
import SearchCommon from '@/components/SearchCommon/index.vue'
import pagination from '@/components/SuperPagination/index.vue'
import _ from 'lodash'
import { TableMixin } from '@/mixins/tableMixin'

export default {
  name: 'SuperTableSelectorDialog',
  inheritAttrs: false,
  mixins: [TableMixin],
  props: {
    isShow: {
      default: false,
      type: Boolean
    },
    selectedContent: {
      default: () => [],
      type: [Array, Object]
    },
    top: {
      default: '14vh',
      type: String
    },
    width: {
      default: '80%',
      type: String
    },
    height: {
      default: '65vh',
      type: String
    },
    isShowTree: {
      default: true,
      type: Boolean
    },
    treeOptions: {
      default: () => ({ children: 'children', label: 'name' }),
      type: Object
    },
    treeTabList: {
      default: () => [],
      type: Array
    },
    treeActiveTabName: {
      default: '',
      type: String
    },
    treeLoading: {
      default: false,
      type: Boolean
    },
    treeItem: {
      default: () => ({}),
      type: Object
    },
    tableLoading: {
      default: false,
      type: Boolean
    },
    tableParams: {
      default: () => ({
        pageBean: { pageSize: 0, page: 0, total: 0 },
        querys: [],
        sorter: []
      }),
      type: Object
    },
    tableData: {
      default: () => [],
      type: Array
    },
    treeData: {
      default: () => [],
      type: Array
    },
    searchOption: {
      default: () => [],
      type: Array
    },
    tableOptions: {
      default: () => [],
      type: Array
    },
    treeKey: {
      default: 'id',
      type: String
    },
    selectKey: {
      default: 'id',
      type: String
    },
    selectLabel: {
      default: 'name',
      type: String
    },
    selectTitleName: {
      default: '已选择',
      type: String
    },
    treeValueKey: {
      default: '',
      type: String
    },
    defaultTreeExpandLevel: {
      default: -1,
      type: Number
    },
    isSingleChoice: {
      default: false,
      type: Boolean
    },
    isShowSelect: {
      default: true,
      type: Boolean
    },
    isShowTableCheckbox: {
      default: true,
      type: Boolean
    },
    confirmCloseDialog: {
      default: true,
      type: Boolean
    },
    isShowPagination: {
      default: true,
      type: Boolean
    },
    isShowSearch: {
      default: true,
      type: Boolean
    }
  },
  components: {
    pagination,
    SearchCommon,
    treeSide,
    SuperDialog
  },
  data() {
    return {
      initializeRendering: false, // 弹层内容初始化渲染
      tableMaxHeight: '600px',
      enhancedTableData: [], // 增强的表格数据（增加额外特性）
      allSelection: [], // 表格选中
      checkboxOpt: [], // 多选框配置数组
      checkboxSelect: [], // 多选框选中
      checkAll: false, // 全选
      tableCheckAll: false, // 表格全选
      tableIsIndeterminate: false, // 表格多选框不确定
      isIndeterminate: false, // 多选框不确定
      parentId: ''
    }
  },
  computed: {
    isShowDialog: {
      get() {
        return this.isShow
      },
      set(val) {
        this.$emit('update:isShow', val)
      }
    }
  },
  watch: {
    treeData: {
      handler() {
        if (!this.isShowTree) return
        this.$nextTick(_ => {
          this.$refs.treeSide?.setCurrentKey(
            this.treeItem?.[this.treeKey] || ''
          )
          this.$refs.treeSide?.expandHandle(true, this.defaultTreeExpandLevel)
        })
      },
      immediate: true
    },
    tableData: {
      handler(data) {
        this.enhancedTableData = data.map(item => ({
          ...item,
          checked: this.allSelection.some(
            i => i[this.selectKey] === item[this.selectKey]
          ),
          disabled:
            this.allSelection.find(
              i => i[this.selectKey] === item[this.selectKey]
            )?.disabled ?? false
        }))
        this.tableCheckAll = this.enhancedTableData.length
          ? this.enhancedTableData.every(i => i.checked)
          : false
        this.tableIsIndeterminate =
          this.enhancedTableData.some(i => i.checked) && !this.tableCheckAll
      },
      immediate: true,
      deep: true
    },
    selectedContent: {
      handler(data) {
        let allSelection
        if (this.isSingleChoice) {
          if (
            Object.prototype.toString.call(data) === '[object Object]' &&
            Object.keys(data).length
          ) {
            allSelection = [_.cloneDeep(data)] || []
          } else {
            allSelection = []
          }
        } else {
          allSelection = _.cloneDeep(data) || []
        }
        console.log(allSelection, 'allSelection');

        if (allSelection) {
          this.allSelection = allSelection.map(i => ({ ...i, checked: true }))
        }
        this.updateCheckboxOpt()
      },
      immediate: true,
      deep: true
    }
  },
  mounted() {
    this.$root.$on('resize', () => {
      this.calcTableHeight(500)
    })
  },
  methods: {
    treeTabChange(treeActiveTabName) {
      this.$emit('update:treeActiveTabName', treeActiveTabName)
      this.$emit('treeTabChange', treeActiveTabName)
    },
    // 打开弹层时触发
    open() {
      if (!this.initializeRendering) this.$emit('initializeRendering')
      let allSelection
      if (this.isSingleChoice) {
        if (
          Object.prototype.toString.call(this.selectedContent) ===
          '[object Object]' &&
          Object.keys(this.selectedContent).length
        ) {
          allSelection = [_.cloneDeep(this.selectedContent)] || []
        } else {
          allSelection = []
        }
      } else {
        allSelection = _.cloneDeep(this.selectedContent) || []
      }
      this.allSelection = allSelection.map(i => ({ ...i, checked: true }))
      this.updateCheckboxOpt()

      // 初始化首次打开弹层选中效果,
      if (this.isShowTree && !this.initializeRendering) {
        this.$nextTick(_ => {
          this.$refs.treeSide?.setCurrentKey(
            this.treeItem?.[this.treeKey] || ''
          )
          this.$refs.treeSide?.expandHandle(true, this.defaultTreeExpandLevel)
        })
      }

      this.$emit('open', this.initializeRendering)
      this.initializeRendering = true
    },

    // 关闭弹层后触发
    closed() {
      Object.assign(this.$data, this.$options.data.call(this)) // 重置data中的数据
      // 重置打开弹层选中效果,
      this.$nextTick(_ => {
        if (this.isShowTree) {
          this.$refs.treeSide?.setCurrentKey(
            this.treeItem?.[this.treeKey] || ''
          )
          this.$refs.treeSide?.expandHandle(true, this.defaultTreeExpandLevel)
        }
        this.$refs.searchCommon?.deleteChoose('all', false) // 清空搜索选中
        this.$refs.multipleSelection?.clearSort() // 用于清空排序条件，数据会恢复成未排序的状态
      })
      this.$emit('closed')
    },

    // 表格行样式自定义
    rowClassName({ row }) {
      const classArr = []
      if (
        this.allSelection.some(i => i[this.selectKey] === row[this.selectKey])
      ) {
        classArr.push('current-row')
      }
      if (row.disabled) {
        classArr.push('disabled-row')
      }
      return classArr.join(' ')
    },

    //左边树节选中改变
    currentChange(nodeItem) {
      this.tableParams.pageBean.page = 1
      // 为了避免左侧树勾选的参数用于表格查询中的方式有不确定性，则把修改查询项功能留给父组件自己做
      this.$emit('update:treeItem', nodeItem || {})
      this.$emit('treeChange', nodeItem)
    },

    // 顶部搜索逻辑触发
    handleSearch(data) {
      this.tableParams.pageBean.page = 1
      data.forEach(item => {
        if (Array.isArray(item.prop) && item.prop.length) {
          item.prop.forEach(prop => {
            setQueryValue(this.tableParams, prop, item.value)
          })
        } else if (typeof item.prop === 'string') {
          setQueryValue(this.tableParams, item.prop, item.value)
        }
        console.log(this.tableParams.querys)
      })
      console.log(data, this.tableParams.querys)

      this.$emit('tableRefresh', this.tableParams)
    },

    //分页页数
    handleCurrentChange(page) {
      this.tableParams.pageBean.page = page
      this.$emit('tableRefresh', this.tableParams)
    },

    //分页大小
    handleSizeChange(pageSize) {
      this.tableParams.pageBean.pageSize = pageSize
      this.$emit('tableRefresh', this.tableParams)
    },

    // 表格行点击
    tableRowClick(row, status) {
      this.tableSelection(row, status)
      this.updateCheckboxOpt()
    },

    // 表格勾选或取消勾选
    tableSelection(item, status) {
      if (item.disabled) return
      this.enhancedTableData.forEach(item => {
        let path = []
        path = item.teamFullId.split('.')
        item.parentId = path[path.length - 2]
      })

      const tableIndex = this.enhancedTableData.findIndex(
        i => i[this.selectKey] === item[this.selectKey]
      )
      const findIndex = this.allSelection.findIndex(
        i => i[this.selectKey] === item[this.selectKey]
      )
      if (tableIndex !== -1) this.enhancedTableData[tableIndex].checked = status
      if (status) {
        if (this.isSingleChoice) {
          this.allSelection = [item]
          this.enhancedTableData.forEach(i => {
            if (i[this.selectKey] !== item[this.selectKey]) i.checked = false
          })
        } else {
          if (this.allSelection.length) {
            if (findIndex === -1 && this.parentId === item.parentId) {
              this.allSelection.push(item)
            } else {
              item.checked = false
              this.$confirm('请选择所属同一队伍人员！', '提示', {
                confirmButtonText: '确认',
                showCancelButton: false,
                type: 'warning'
              }).then(async () => {})
              return
            }
          } else {
            this.parentId = item.parentId
            this.allSelection.push(item)
          }

        }
      } else {
        if (findIndex !== -1) this.allSelection.splice(findIndex, 1)
      }

      this.tableCheckAll = this.enhancedTableData.every(i => i.checked)
      this.tableIsIndeterminate =
        this.enhancedTableData.some(i => i.checked) && !this.tableCheckAll
    },

    // 多选框列表滚动到底部
    checkboxScrollBottom() {
      this.$nextTick(_ => {
        const container = this.$refs.checkboxGroup?.$el
        container?.scrollTo({
          top: container.scrollHeight,
          behavior: 'smooth'
        })
      })
    },

    // 表格滚动到某一行
    tableTrScroll(item) {
      this.$nextTick(_ => {
        const tableElement = this.$refs.multipleSelection
        const theTableRowArr = tableElement.bodyWrapper.querySelectorAll(
          '.el-table__body tbody .el-table__row'
        )
        const rowIndex = this.enhancedTableData.findIndex(
          i => i[this.selectKey] === item[this.selectKey]
        )
        if (rowIndex === -1) return

        let top = [...theTableRowArr].reduce((topSum, i, index) => {
          if (index < rowIndex) {
            return topSum + theTableRowArr[index].offsetHeight
          } else {
            return topSum
          }
        }, 0)
        tableElement.bodyWrapper?.scrollTo({ top, behavior: 'smooth' })
      })
    },

    // 更新多选框配置项
    updateCheckboxOpt() {
      this.checkboxOpt = _.cloneDeep(this.allSelection)
      this.checkboxSelect = this.checkboxOpt.map(i => i[this.selectKey])
      this.checkAll = !!this.checkboxSelect.length
      this.isIndeterminate = false
      this.checkboxScrollBottom()
    },

    // 多选框列表全选框改变
    handleCheckAllChange(val) {
      return
      if (val) {
        this.checkboxSelect = this.checkboxOpt.map(i => i[this.selectKey])
        this.allSelection = this.checkboxOpt
      } else {
        this.checkboxSelect = this.checkboxOpt.flatMap(i =>
          i.disabled ? i[this.selectKey] : []
        )
        this.allSelection = this.allSelection.flatMap(i =>
          i.disabled && i.checked ? i : []
        )
        this.isIndeterminate = !!this.checkboxSelect.length
      }
      this.checkboxOpt.forEach(i => {
        const findItem = this.enhancedTableData.find(
          _i => _i[this.selectKey] === i[this.selectKey]
        )
        if (!findItem) return
        this.tableSelection(findItem, val)
      })
    },

    // 多选框列表多选框改变
    handleCheckedChange(status, item, value) {
      return
      this.tableTrScroll(item)
      this.tableSelection(item, status)
      let checkedCount = value.length
      this.checkAll = checkedCount === this.checkboxOpt.length
      this.isIndeterminate =
        checkedCount > 0 && checkedCount < this.checkboxOpt.length
    },

    // 确认按钮点击
    confirm() {
      let selectedContent = this.allSelection.filter(i => {
        return this.checkboxSelect.some(
          selectKey => selectKey === i[this.selectKey]
        )
      })
      selectedContent = this.isSingleChoice
        ? selectedContent[0] || {}
        : selectedContent
      this.$emit('update:selectedContent', selectedContent)
      this.$emit('confirm', selectedContent)
      if (this.confirmCloseDialog) this.isShowDialog = false
    }
  }
}
</script>

<style lang="scss" scoped>
@import '~@/assets/css/element-variables';

.super-table-selector-dialog {
  width: 100%;
  display: flex;
  column-gap: 16px;
  min-height: 50vh;

  .tree-module {
    height: 100%;
    border-radius: 8px;
    overflow: hidden;
    background-color: $--system-module-color1;
  }

  .table-module {
    width: 0;
    height: 100%;
    flex: 1;
    display: flex;
    flex-direction: column;
    row-gap: 16px;

    .search-content {
      border-radius: 8px;
      padding: 16px;
      background-color: $--system-module-color1;
    }

    .table-content {
      flex: 1;
      height: 0;
      border-radius: 8px;
      padding: 16px;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      background-color: $--system-module-color1;

      ::v-deep .el-table {
        .el-table__row {
          cursor: pointer;

          &.current-row {
            cursor: pointer;

            .el-table__cell {
              background-color: $--system-box-color3 !important;

              .cell {
                color: $--system-hover-active-text;
              }
            }
          }

          &.disabled-row {
            cursor: no-drop;

            .el-table__cell {
              background-color: $--system-disabled-bgColor !important;

              .cell {
                color: $--color-text-placeholder;
              }
            }
          }
        }
      }

      .table-content-bottom {
        display: flex;
        justify-content: space-between;
        align-items: flex-end;
      }
    }
  }

  .select-module {
    width: 300px;
    height: 100%;
    display: flex;
    flex-direction: column;
    background-color: $--system-module-color1;
    border-radius: 8px;
    overflow: hidden;

    .title-box {
      box-sizing: border-box;
      height: 52px;
      border-bottom: 1px solid $--system-border-color3;
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 16px;

      .title-box-left {
        display: flex;
        align-items: center;
        column-gap: 9px;
        font-size: 16px;
        color: $--color-white;

        .el-checkbox {
          margin-top: 2px;
        }
      }

      .title-box-right {
        font-size: 15px;
        color: $--color-text-placeholder;
      }
    }

    .select-content {
      height: 0;
      flex: 1;
      box-sizing: border-box;
      padding: 16px;
      display: flex;
      flex-direction: column;
      row-gap: 16px;

      .select-content-top {
        padding-left: 11px;
      }

      .select-content-center {
        flex: 1;
        height: 0;
        display: flex;
        flex-direction: column;

        .el-checkbox-group {
          display: flex;
          overflow: auto;
          height: 100%;
          flex-direction: column;
          row-gap: 8px;
          padding-right: 8px;
          margin-right: -8px;

          /* 滚动条整体 */
          &::-webkit-scrollbar {
            width: 4px !important;
            background: transparent !important;
          }

          /* 滚动条滑块 */
          &::-webkit-scrollbar-thumb {
            border-radius: 5px;
            background: $--system-border-color2;
          }

          /* 滚动条轨道 */
          &::-webkit-scrollbar-track {
            color: transparent;
            background: transparent !important;
          }

          ::v-deep .el-checkbox {
            margin: 0;
            height: 32px;
            display: flex;
            box-sizing: border-box;

            .el-checkbox__label {
              flex: 1;
              overflow: hidden;

              span {
                display: block;
                font-size: 14px;
                overflow: hidden;
                white-space: nowrap;
                text-overflow: ellipsis;
              }
            }
          }
        }
      }

      .select-content-bottom {
        display: flex;
        justify-content: flex-end;
      }
    }
  }
}
</style>
