<template>
  <el-tooltip content="列设置">
    <div class="cursor-pointer table-toolbar-right-icon">
      <el-popover
        :width="getPopoverWidth"
        class="toolbar-popover"
        placement="bottom-end"
        trigger="click"
        style="max-height: 50vh"
      >
        <template #reference>
          <el-icon class="el-input__icon" :size="18">
            <SettingOutlined />
          </el-icon>
        </template>

        <div class="table-toolbar-inner-popover-title">
          <div class="flex justify-between">
            <el-checkbox
              v-model="checkAll"
              :indeterminate="!checkAll && checkPart"
              @change="onCheckAll"
              >列展示
            </el-checkbox>
            <!--                <el-checkbox v-model:checked="selection" @update:checked="onSelection"-->
            <!--                  >勾选列-->
            <!--                </el-checkbox>-->
            <el-button class="mt-1" size="small" text type="primary" @click="resetColumns"
              >重置
            </el-button>
          </div>
        </div>

        <div class="table-toolbar-inner">
          <el-checkbox-group v-model="checkList" @change="onChange">
            <Draggable
              v-model="basicColumns"
              animation="300"
              item-key="key"
              filter=".no-draggable"
              :move="onMove"
              @end="draggableEnd"
            >
              <template #item="{ element }">
                <div
                  v-if="element.type !== 'selection' && element.type !== 'expand'"
                  :class="{
                    'table-toolbar-inner-checkbox-dark': getDarkTheme === true,
                    'no-draggable': element.draggable === false,
                  }"
                  class="table-toolbar-inner-checkbox"
                >
                  <span class="drag-icon">
                    <el-icon class="el-input__icon" :size="18">
                      <DragOutlined />
                    </el-icon>
                  </span>
                  <el-checkbox :value="element.prop" :key="element.prop">{{
                    element.label
                  }}</el-checkbox>
                  <div class="fixed-item">
                    <el-tooltip placement="top" content="固定到左侧">
                      <el-icon
                        :color="element.fixed === 'left' ? getAppTheme : undefined"
                        class="cursor-pointer el-input__icon"
                        :size="18"
                        @click="fixedColumn(element, 'left')"
                      >
                        <VerticalRightOutlined />
                      </el-icon>
                    </el-tooltip>
                    <el-divider direction="vertical" />
                    <el-tooltip placement="top" content="固定到右侧">
                      <el-icon
                        :color="element.fixed === 'right' ? getAppTheme : undefined"
                        class="cursor-pointer el-input__icon"
                        :size="18"
                        @click="fixedColumn(element, 'right')"
                      >
                        <VerticalLeftOutlined />
                      </el-icon>
                    </el-tooltip>
                  </div>
                </div>
              </template>
            </Draggable>
          </el-checkbox-group>
        </div>
      </el-popover>
    </div>
  </el-tooltip>
</template>

<script lang="ts" setup>
  import { ref, unref, toRaw, watchEffect, computed } from 'vue';
  import { useTableContext } from '../../hooks/useTableContext';
  import { cloneDeep } from 'lodash-es';
  import {
    SettingOutlined,
    DragOutlined,
    VerticalRightOutlined,
    VerticalLeftOutlined,
  } from '@vicons/antd';
  import Draggable from 'vuedraggable/src/vuedraggable';
  import { useDesignSetting } from '@/hooks/setting/useDesignSetting';
  import type { TableSetting } from '../../types/table';

  interface Options {
    title: string;
    prop: string;
    fixed?: boolean | 'left' | 'right';
  }

  const props = defineProps({
    tableSetting: {
      type: Object as PropType<TableSetting>,
    },
  });

  const { getDarkTheme, getAppTheme } = useDesignSetting();
  const table: any = useTableContext();
  const basicColumns = ref<Options[]>([]);
  const cacheColumnsList = ref<Options[]>([]);

  const selection = ref(false);
  const checkAll = ref(true);
  const checkPart = ref(false);
  const checkList = ref<string[]>([]);
  const defaultCheckList = ref([]);

  const emit = defineEmits(['columnsChange']);

  const getPopoverWidth = computed(() => {
    return props.tableSetting?.width;
  });

  watchEffect(() => {
    const columns = table.getColumns();
    if (columns.length) {
      init();
    }
  });

  //初始化
  function init() {
    const columns: any[] = getColumns();
    //同时兼容 全选 反选，单选
    const checkListArr: any =
      !checkAll.value && !checkPart.value && checkList.value.length
        ? checkList.value
        : columns.map((item) => item.prop);
    //重新赋值
    checkList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;
    defaultCheckList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;

    const newColumns = columns.filter((item) => item.prop != 'action' && item.title != '操作');
    if (!basicColumns.value.length) {
      let reNewColumns = cloneDeep(newColumns);
      basicColumns.value = reNewColumns;
      cacheColumnsList.value = cloneDeep(newColumns);
    }
  }

  // function filterSelection(columns) {
  //   return cloneDeep(columns.filter((item) => item.type != 'selection' && item.prop != 'action'));
  // }

  //切换
  function onChange(list) {
    if (selection.value) {
      list.unshift('selection');
    }
    const filterColumns = basicColumns.value.filter((item) => {
      return list.includes(item.prop);
    });
    const isAction = list.includes('action');
    const len = isAction ? list.length - 1 : list.length;
    checkPart.value = basicColumns.value.length != len;
    checkAll.value = basicColumns.value.length == len;
    setColumns(filterColumns);
    table.isShowTable.value = true;
    emit('columnsChange', table.getColumns());
  }

  //设置
  function setColumns(columns) {
    table.setColumns(columns);
  }

  //获取
  function getColumns() {
    let newRet: any[] = [];
    table.getColumns().forEach((item) => {
      newRet.push({ ...item });
    });
    return newRet;
  }

  function onMove(e) {
    if (e.draggedContext.element.draggable === false) return false;
    return true;
  }

  //重置
  function resetColumns() {
    checkList.value = [...defaultCheckList.value];
    checkAll.value = true;
    let cacheColumnsKeys: any[] = table.getCacheColumns();
    let newColumns = cacheColumnsKeys.map((item) => {
      return {
        ...item,
        fixed: undefined,
      };
    });
    setColumns(newColumns);
    basicColumns.value = newColumns;
    table.isShowTable.value = true;
    emit('columnsChange', table.getColumns());
  }

  //全选
  function onCheckAll(e) {
    let checkList = table.getCacheColumns();
    checkPart.value = false;
    if (e) {
      setColumns(checkList);
      checkAll.value = true;
      checkList.value = checkList;
      table.isShowTable.value = true;
    } else {
      table.isShowTable.value = false;
      checkList.value = [];
      checkAll.value = false;
      setColumns([]);
    }
    emit('columnsChange', table.getColumns());
  }

  //拖拽排序
  function draggableEnd() {
    const newColumns = toRaw(unref(basicColumns));
    basicColumns.value = newColumns;
    const filterColumns = newColumns.filter((item) => {
      return checkList.value.includes(item.prop as string);
    });
    checkList.value = filterColumns.map((item) => item.prop) as string[];
    setColumns(filterColumns);
    emit('columnsChange', table.getColumns());
  }

  //勾选列
  // function onSelection(e) {
  //   let checkList = table.getCacheColumns();
  //   if (e) {
  //     checkList.unshift({ type: 'selection', key: 'selection' });
  //     setColumns(checkList);
  //   } else {
  //     checkList.splice(0, 1);
  //     setColumns(checkList);
  //   }
  // }

  //固定
  function fixedColumn(item, fixed) {
    if (!unref(checkList).includes(item.prop as never)) return;
    let columns = getColumns();
    const isFixed = item.fixed === fixed ? undefined : fixed;
    let index = columns.findIndex((res) => res.prop === item.prop);
    if (index !== -1) {
      columns[index].fixed = isFixed;
    }
    table.setCacheColumnsField(item.prop, { fixed: isFixed });
    basicColumns.value[index].fixed = isFixed;
    setColumns(columns);
    emit('columnsChange', table.getColumns());
  }
</script>

<style lang="scss">
  .table-toolbar {
    &-inner-popover-title {
      border-bottom: 1px solid var(--el-border-color);
      padding-bottom: 5px;
      margin-top: -5px;
    }

    &-right {
      &-icon {
        margin-left: 12px;
        font-size: 16px;
        color: var(--n-text-color);
        cursor: pointer;

        :hover {
          color: v-bind(getAppTheme);
        }
      }
    }
  }

  .table-toolbar-inner {
    &-checkbox {
      display: flex;
      align-items: center;
      padding: 5px;
      border-radius: 3px;

      &:hover {
        background: #e6f7ff;
      }

      .drag-icon {
        display: inline-flex;
        margin-right: 8px;
        cursor: move;
      }

      .fixed-item {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        margin-left: auto;
      }

      .ant-checkbox-wrapper {
        flex: 1;

        &:hover {
          color: v-bind(getAppTheme) !important;
        }
      }
    }

    &-checkbox-dark {
      &:hover {
        background: hsla(0, 0%, 100%, 0.08);
      }
    }
  }

  .toolbar-popover {
    .n-popover__content {
      padding: 0;
    }
  }
</style>
