<template>
  <div class="cus-table" :class="{'cus-table-normal': !otherStyle, 'cus-table-full': full !== false}">
    <div class="cus-table-main" ref="ref_tableMain" :class="{'cus-table-main-no-foot': noFoot !== false}">
      <el-table
          v-bind="$attrs"
          class="ct-table"
          ref="ref_table"
          :data="tableData"
          :border="false"
          @sort-change="handleSort"
          @filter-change="handleFilter"
          @selection-change="v => $emit('update:selected', v)"
      >
        <el-table-column v-if="selected" type="selection" :width="selectWidth" align="center" :selectable="selectable"/>
        <el-table-column v-if="singled" :width="singledWidth" align="center" class-name="single-column">
          <template #default="scope">
            <div class="single-circle" :class="{active: scope.row[singledKey] === singled[singledKey]}" @click.stop="$emit('update:singled', scope.row)">
              <div class="single-circle-in"></div>
            </div>
          </template>
        </el-table-column>
        <el-table-column  v-if="showIndex" type="index" label="序号" align="center" fixed="left" width="60"/>
        <template v-for="(item, index) in tempTableHead" :key="index">
          <template v-if="item.children && item.children.length > 0">
            <el-table-column :label="item.label" v-if="item.show" align="center">
              <template v-for="(item2, index2) in item.children">
                <template v-if="item2.children && item.children.length > 0">
                  <el-table-column :label="item2.label" v-if="item2.show" align="center">
                    <template v-for="(item3, index3) in item2.children">
                      <CusTableColumn :item="item3">
                        <template #[`${item3.value}-column`]="{column}">
                          <slot :name="`${item3.value}-column`" :column="column">
                          </slot>
                        </template>
                        <template #[`${item3.value}-column-value`]="{scope}">
                          <slot :name="`${item3.value}-column-value`" :scope="scope">
                          </slot>
                        </template>
                      </CusTableColumn>
                    </template>
                  </el-table-column>
                </template>
                <template v-else>
                  <CusTableColumn :item="item2">
                    <template #[`${item2.value}-column`]="{column}">
                      <slot :name="`${item2.value}-column`" :column="column">
                      </slot>
                    </template>
                    <template #[`${item2.value}-column-value`]="{scope}">
                      <slot :name="`${item2.value}-column-value`" :scope="scope">
                      </slot>
                    </template>
                  </CusTableColumn>
                </template>
              </template>
            </el-table-column>
          </template>
          <template v-else>
            <CusTableColumn :item="item">
              <template #[`${item.value}-column`]="{column}">
                <slot :name="`${item.value}-column`" :column="column">
                </slot>
              </template>
              <template #[`${item.value}-column-value`]="{scope}">
                <slot :name="`${item.value}-column-value`" :scope="scope">
                </slot>
              </template>
            </CusTableColumn>
          </template>
        </template>
      </el-table>
    </div>
    <div class="ct-foot" v-if="noFoot === false">
      <div class="total">
        <template v-if="$util.isValue(selectedNum)">
          已选中 {{ selectedNum }} 条 /
        </template>
        <template v-else-if="$util.isValue(selected?.length)">
          已选中 {{ selected.length }} 条 /
        </template>
        共 {{ total }} 条
      </div>
      <el-pagination
          v-if="noPage === false"
          ref="ref_tablePage"
          class="__cus-pagination"
          :currentPage="page"
          :page-size="pageSize"
          background
          :page-sizes="pageSizes"
          :layout="pageLayoutCpt"
          :total="Number(total)"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  computed,
  onMounted,
  ref,
  reactive,
  watch,
  getCurrentInstance,
  nextTick,
  ComponentInternalInstance, toRefs
} from 'vue'
  import {useStore} from 'vuex'
  import {useRouter} from 'vue-router'

  export default defineComponent({
    name: 'CusTable',
    props: {
      tableData: {
        required: true
      },
      tableHead: {
        default: () => [],
        required: true
      },
      total: {
        required: true
      },
      page: {},
      pageSize: {},
      pageSizes: {
        default: () => [10, 20, 30, 50, 100]
      },
      selected: {
        default: null
      },
      selectedNum: {
        default: null
      },
      selectWidth: {
        default: 50
      },
      singledWidth: {
        default: 50
      },
      singled: {
        default: null
      },
      singledKey: {
        default: 'id'
      },
      noPage: {
        default: false
      },
      showIndex: {
        default: true
      },
      otherStyle: {
        default: false
      },
      noLayout: {
        default: () => []
      },
      full: {
        default: false
      },
      selectable: {},
      noFoot: {
        default: false
      }
    },
    setup(props, { emit }) {
      const store = useStore();
      const router = useRouter();
      const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
      const ref_table = ref();
      const ref_tableMain = ref();
      const ref_tablePage = ref();
      const state = reactive({
        tempTableHead: <any>[],
        pageLayout: ['sizes', 'prev', 'pager', 'next', 'jumper']
      });
      watch(() => props.tableHead, (nVal: any) => {
        formatTableHead(nVal)
      }, {deep: true})
      // watch(() => props.tableData, (nVal) => {
      //   ref_table.value?.doLayout()
      // }, {deep: true})
      const pageLayoutCpt = computed(() => {
        return state.pageLayout.filter((v: string) => props.noLayout.every((s: string) => v !== s)).join(',')
      })

      const formatTableHead = (tableHead: Array<any>) => {
        const result = tableHead
        const deep = (arr: any[]) => {
          let flag = 0
          arr.forEach(v => {
            if (v.children && v.children.length > 0) {
              v.show = deep(v.children)
            }
            if (v.show) {
              flag++
            }
          })
          return flag > 0
        }
        deep(result)
        state.tempTableHead = result
      }
      const handleSizeChange = (val: Number) => {
        emit('handlePage', {
          page: 1,
          pageSize: val
        })
      }
      const handleCurrentChange = (val: Number) => {
        emit('handlePage', {
          page: val,
          pageSize: props.pageSize
        })
      }
      const handleSort = ({ column, prop, order }: any) => {
        emit('handleSort', {
          key: prop,
          value: order
        })
      }
      const handleFilter = (val: any) => {
        const key = Object.keys(val)[0]
        const head = props.tableHead.filter(v => v.value === key)[0]
        let value = null
        if (val[key].length > 0) {
          if (head.filterMultiple) {
            value = val[key]
          } else {
            value = val[key][0]
          }
        }
        emit('handleFilter', {key, value})
      }
      const resetFilter = (key: any = null) => {
        key ? ref_table.value.clearFilter([key]) : ref_table.value.clearFilter()
      }
      const reset = (key: any = null) => {
        resetFilter(key)
        ref_table.value.clearSort()
      }
      watch(() => props.selected, (n: any) => {
        if (n.length === 0) {
          ref_table.value.clearSelection()
        } else {
          setTimeout(() => {
            n.forEach(v => {
              ref_table.value.toggleRowSelection(v, true)
            })
          }, 100)
        }
      })
      onMounted(() => {
        formatTableHead(props.tableHead)
      })
      return {
        handleSizeChange,
        handleCurrentChange,
        handleSort,
        resetFilter,
        handleFilter,
        ref_table,
        ref_tableMain,
        ref_tablePage,
        ...toRefs(state),
        pageLayoutCpt,
        reset
      }
    },
  })
</script>

<style scoped lang="scss">
.cus-table {
  width: 100%;
  height: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  $cus-page-height: 32px;
  $cus-page-mt: 25px;
  position: relative;
  :deep(.el-popper) {
    max-width: 60% !important;
  }
  .cus-table-main {
    width: 100%;
    height: calc(100% - #{$cus-page-height} - #{$cus-page-mt}) !important;
    position: absolute;
    &.cus-table-main-no-foot {
      height: 100% !important;
    }
    :deep(.ct-table) {
      height: 100%;
    }
  }
  :deep(.ct-foot) {
    height: $cus-page-height;
    font-size: 14px;
    font-family: Microsoft YaHei;
    font-weight: 400;
    color: #999999;
    display: flex;
    justify-content: space-between;
    .total {
      display: flex;
      align-items: center;
    }
  }
  &.cus-table-normal {
    .cus-table-main {
      :deep(.ct-table) {
        width: 100%;
        //height: calc(100% - #{$cus-page-height} - 20px);
        .el-checkbox__inner {
          &:after {
          }
        }
        $borderColor: #FFFFFF;
        $borderWidth: 2px;
        //  表格左边框
        &::before, .el-table__border-left-patch {
          display: none;
        }
        //  表格上边框
        .el-table__inner-wrapper::after {
          display: none;
        }
        //  表格右边框
        &.el-table--border::after {
          display: none;
        }
        //  表格下边框
        .el-table__inner-wrapper::before {
          display: none;
        }
        .el-table__header-wrapper, .el-table__fixed-right, .el-table__fixed {
          .el-table__header {
            tr {
              >th {
                border-left: $borderWidth solid $borderColor;
                border-top: $borderWidth solid $borderColor;
                border-right: none;
                border-bottom: none;
                background-color: #F5F5F5;
                height: 52px;
                .cell {
                  font-size: 14px;
                  font-family: 微软雅黑;
                  font-weight: 400;
                  color: #666666;
                  padding: 0 4px;
                  &.highlight {
                    color: #409eff;
                  }
                }
              }
              &:first-child {
                >th {
                  border-top: none;
                  &:first-child {
                    border-left: none;
                  }
                }
              }
            }
          }
        }
        .el-table__body-wrapper, .el-table__fixed-body-wrapper {
          .el-table__body {
            .el-table__row {
              >td {
                border-right: none;
                border-bottom-color: #F4F4F4;
                .cell {
                  font-size: 14px;
                  font-family: 微软雅黑;
                  font-weight: 400;
                  color: #666666;
                  white-space: nowrap;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  word-break: break-all;
                  padding: 0 6px;
                  .el-link +.el-link {
                    margin-left: 10px;
                  }
                }
              }
            }
          }
        }
      }
    }
    :deep(.ct-foot) {
      margin-top: auto;
    }
  }
  &.cus-table-full {
    .cus-table-main {
      position: unset;
      height: 100% !important;
    }
    :deep(.ct-foot) {
      margin-top: $cus-page-mt;
    }
  }
}

:deep(.single-column) {
  .cell {
    display: flex;
    justify-content: center;
    align-items: center;
    .single-circle {
      width: 16px;
      height: 16px;
      border: 1px solid rgba(96, 98, 102, 0.6);
      border-radius: 50%;
      cursor: pointer;
      display: flex;
      justify-content: center;
      align-items: center;
      &.active {
        background-color: #22a5fe;
        border-color: #22a5fe;
      }
      .single-circle-in {
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background-color: #FFFFFF;
      }
    }
  }
}
</style>
