<template>
  <ElTooltip placement="top" content="自定义列">
    <el-icon :size="20" @click="dialogVisible = true"><Operation /></el-icon>
  </ElTooltip>
  <ElDialog v-model="dialogVisible" title="自定义列" width="840">
    <div class="customized-column-content zt-column-content">
      <div class="column-area">
        <div class="column-select-panel">
          <div class="panel-title-line !dark:bg-[var(--el-bg-color)]"> 可添加的列 </div>
          <div class="panel-content">
            <div class="column-select-area column-select-area0">
              <div class="column-group clearfix">
                <div class="column-items clearfix">
                  <div class="column-item check-group">
                    <el-checkbox
                      v-model="checkedadAll"
                      :indeterminate="isIndeterminate"
                      @change="onCheckAllChange"
                    >
                      全选
                    </el-checkbox>
                  </div>
                  <el-checkbox-group v-model="checkedList" @change="onCheckChange">
                    <div
                      class="column-item"
                      v-for="(columnItem, index) in originColumns"
                      :key="columnItem.prop"
                    >
                      <el-checkbox
                        :key="columnItem.prop"
                        @change="
                          (e: any) => {
                            checkOne(e, columnItem, index)
                          }
                        "
                        :label="columnItem.label"
                        :value="columnItem.prop"
                      />
                    </div>
                  </el-checkbox-group>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="column-selected">
          <div class="panel-title-line !dark:bg-[var(--el-bg-color)]">
            <span
              >已选{{ dragColumns.length }}列&nbsp;
              <el-tooltip class="item" effect="dark" content="拖动可以排序" placement="top">
                <i class="el-icon-question"></i>
              </el-tooltip>
            </span>

            <span class="delete-all" @click="clearAll">清空全部</span>
          </div>
          <div class="panel-selected" ref="draged">
            <draggable
              class="page-prop-area drag-area"
              v-model="dragColumns"
              item-key="prop"
              :animation="200"
              ghost-class="draggable-ghost"
              :force-fallback="true"
              @change="handleColumnChange"
            >
              <template #item="{ element, index }">
                <div
                  class="selected-column-item select-none dark:border-solid !dark:bg-[var(--el-bg-color)] dark:border dark:border-zinc-400"
                >
                  <div class="column-title">
                    <el-icon><Operation /></el-icon>
                    <p>{{ element.label }}</p>
                  </div>
                  <el-icon class="el-icon-close close" @click="removeColumn(element, index)"
                    ><CircleClose
                  /></el-icon>
                </div>
              </template>
            </draggable>
          </div>
        </div>
      </div>
    </div>
    <template #footer>
      <XButton title="取消" @click="resetColumn" />
      <XButton title="应用自定义列" type="primary" @click="applyColumn" />
    </template>
  </ElDialog>
</template>
<script lang="ts" setup>
import { nextTick } from 'vue'
import { ElDialog } from 'element-plus'
import { useTableContext } from '../hooks/useTableContext'
import draggable from 'vuedraggable'
import { cloneDeep, differenceBy } from 'lodash-es'
import { ColumnProps } from '@/types/table'
import { Operation, CircleClose } from '@element-plus/icons-vue'
import { onDragFalg } from '@/utils/drag'
import { STORAGE_KEY, localStorage } from '@/utils/storage'

// 定义一个通用的 Recordable 类型用于不确定的对象
type Recordable<T = any> = Record<string, T>;

defineOptions({ name: 'ColumnSetting' })

const table = useTableContext()

// 不再需要 useCache 钩子
// const { wsCache } = useCache()

//是否初始化
let inited = false
// 是否当前的setColums触发的
let isSetColumnsFromThis = false
// 是否当前组件触发的setProps
let isSetPropsFromThis = false

//不确定状态
const isIndeterminate = ref(false)
//是否全选
const checkedadAll = ref(false)
//原始列
const originColumns = ref<ColumnProps[]>([])
//拖拽后的值
const dragColumns = ref<ColumnProps[]>([])
//选中列的值列表
const checkedList = ref<string[]>([])

//其他列
const otherColumns = ref<ColumnProps[]>([])

const dialogVisible = ref(false)

const getValues = computed(() => {
  return unref(table?.getBindValues) || {}
})

watchEffect(() => {
  //const columns = table.getColumns()

  setTimeout(() => {
    if (isSetColumnsFromThis) {
      isSetColumnsFromThis = false
    } else {
      initTable()
    }
  }, 0)
})

watch(dialogVisible, (val) => {
  if (val) {
    initTable()
  }
})

//全选事件
const onCheckAllChange = (val: string) => {
  isSetPropsFromThis = true
  isSetColumnsFromThis = true
  if (val) {
    checkedList.value = unref(originColumns).map((item: any) => {
      return item.prop as string
    })
    /* originColumns.value.forEach((item) => {
      item.defaultHidden = false
    }) */
    dragColumns.value = cloneDeep(unref(originColumns))
  } else {
    checkedList.value = []
    dragColumns.value = []
    isIndeterminate.value = false
    /* originColumns.value.forEach((item) => {
      item.defaultHidden = true
    }) */
  }
}

//组改变
const onCheckChange = (val: string) => {
  let checkedCount = val.length
  checkedadAll.value = checkedCount === unref(originColumns).length
  isIndeterminate.value = checkedCount > 0 && checkedCount < unref(originColumns).length
}

//单选某一项
const checkOne = (val: boolean, column: ColumnProps, index: number) => {
  isSetPropsFromThis = true
  isSetColumnsFromThis = true
  if (val) {
    dragColumns.value.push(column)
    //originColumns.value[index].defaultHidden = false
  } else {
    
    let idx = unref(dragColumns).findIndex((r: any) => r.prop === column.prop)
    if (idx > -1) {
      dragColumns.value.splice(idx, 1)
    }
    //originColumns.value[index].defaultHidden = true
  }
}

//重制列表
const resetColumn = () => {
  dialogVisible.value = false
  isSetPropsFromThis = false
  isSetColumnsFromThis = false
  setTimeout(() => {
    initTable()
  }, 0)
}

//应用列表
const applyColumn = () => {
  isSetPropsFromThis = true
  isSetColumnsFromThis = true
  //吧otherColumn 填回去 因为固定列不参与自定义,最后要赋值回去，不然回显有bug
  unref(otherColumns)
    .filter((r: any) => r.type)
    .reverse()
    .forEach((item: any) => {
      dragColumns.value.unshift(item)
    })

  /* unref(otherColumns)
    .filter((r) => !r.type)
    .forEach((item) => {
      dragColumns.value.push(item)
    }) */

  //找到所有没有勾选的，加default

  let allColumns: Record<string, any> = localStorage.get(STORAGE_KEY.COLUMNS) ?? {}
  allColumns[getValues.value.tableKey] = dragColumns.value
  localStorage.set(STORAGE_KEY.COLUMNS, allColumns)
  //table.setColumns(dragColumns.value)
  dialogVisible.value = false
  table.setLocalColumns(dragColumns.value)
  
}

//移除某一项
const removeColumn = (column: any, index: number) => {
  dragColumns.value.splice(index, 1)
  let idx = unref(checkedList).findIndex((r) => r === column.prop)
  if (idx > -1) {
    checkedList.value.splice(idx, 1)
  }
  /* let idx2 = originColumns.value.findIndex((r) => r.prop === column.prop)
  originColumns.value[idx2].defaultHidden = true */

  if (!unref(checkedList).length) {
    isIndeterminate.value = false
    checkedadAll.value = false
  }
}

async function initTable() {
  //初始化
  otherColumns.value = []
  originColumns.value = []
  checkedList.value = []
  let dragColumn: any[] = []

  //获取左侧所有的cloumn,固定的
  let column = table
    .getCacheColumns()
    .map((column: any) => {
      if (column.type || column.prop == 'action') {
        otherColumns.value.push(column)
      } else {
        return column
      }
    })
    .filter((column: any) => {
      return column
    })

  originColumns.value = [...column]

  //用来排序显示的列表要去掉fixed的 序号/多选/和操作还有没权限的
  //获取当前显示的去掉序号等
  
  await nextTick()
  
  let curColumn = unref(table.getViewColumns).filter((column: any) => !column.type && column.prop != 'action')
  curColumn.forEach((item: any) => {
    checkedList.value.push(item.prop)
  })
  
  dragColumns.value = [...curColumn]
  //渲染是否全部/部分选中
  checkedadAll.value = checkedList.value.length === unref(originColumns).length
  isIndeterminate.value =
    checkedList.value.length > 0 && checkedList.value.length < unref(originColumns).length
}

//请空
function clearAll() {
  checkedList.value = []
  dragColumns.value = []
  checkedadAll.value = false
  isIndeterminate.value = false
}

// 拖拽改变
const handleColumnChange = (e: any) => {
  let arr = onDragFalg(e, unref(dragColumns))
  if (arr) dragColumns.value = arr
}
</script>
<style scoped lang="scss">
.column-area {
  height: 445px;

  .ad-d-flex {
    display: flex;
    align-items: center;
  }

  .panel-title-line {
    background-color: #f9fafd;
    border: #e4e9ed 1px solid;
    box-sizing: border-box;
    line-height: 22px;
    padding: 8px 12px;
  }

  .column-selected {
    width: 246px;
    float: left;
    height: 445px;
    padding-bottom: 9px;

    .panel-selected {
      border: #e4e9ed 1px solid;
      border-top: 0;
      box-sizing: border-box;
      height: 395px;
      padding: 0 7px 12px 7px;
      overflow-y: auto;

      .selected-column-item {
        width: 100%;
        height: auto;
        display: flex;
        align-items: center;
        justify-content: space-between;
        background: #f8f8f8;
        border-radius: 4px;
        margin-top: 8px;
        line-height: 18px;
        padding: 5px 12px;

        .column-title {
          display: flex;
          align-items: center;
        }

        .close {
          cursor: pointer;
        }

        p {
          padding: 3px 5px;
          margin: 0;
          cursor: move;
        }
      }
    }

    .delete-all {
      cursor: pointer;
      font-size: 14px;
      color: #338aff;
      float: right;
    }
  }

  .column-select-panel {
    width: 500px;
    float: left;
    margin-right: 16px;
    height: 445px;

    .panel-content {
      border: #e4e9ed 1px solid;
      border-top: 0;
      box-sizing: border-box;
      height: 395px;
      padding: 0;
      overflow: hidden;

      .column-select-area {
        height: 395px;
        overflow-y: auto;
        width: 100%;

        .column-group {
          padding: 0 16px;

          .column-items {
            margin-bottom: 4px;
          }

          .check-group {
            margin-right: 10px;
          }

          .group-title {
            cursor: pointer;
            line-height: 46px;
            font-size: 16px;
            color: #333;
            position: relative;
          }

          .column-item {
            margin-top: 10px;
            width: 208px;
            float: left;
            min-height: 25px;

            &:nth-child(2n) {
              margin-right: 10px;
            }
          }
        }
      }
    }
  }
}

.selected-column-item {
  .anticon {
    cursor: pointer;
  }
}
</style>
