<template>
  <a-tooltip trigger="hover">
    <template #title>
      <span>列设置</span>
    </template>
    <div class="cursor-pointer table-toolbar-right-icon">
      <a-popover
        :overlayStyle="{ width: getPopoverWidth, maxHeight: '50vh', padding: 0 }"
        overlayClassName="toolbar-popover"
        placement="rightBottom"
        trigger="click"
      >
        <SettingOutlined />

        <template #content>
          <div class="table-toolbar-inner-popover-title">
            <div class="w-full flex justify-between items-center">
              <a-checkbox
                v-model:checked="checkAll"
                :indeterminate="!checkAll && checkPart"
                @change="onCheckAll"
                >列展示
              </a-checkbox>
              <!--                <a-checkbox v-model:checked="selection" @update:checked="onSelection"-->
              <!--                  >勾选列-->
              <!--                </a-checkbox>-->
              <a-button class="mt-1" size="small" type="link" @click="resetColumns">重置 </a-button>
            </div>
          </div>

          <div class="table-toolbar-inner">
            <a-checkbox-group v-model:value="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">
                      <DragOutlined style="font-size: 18px" />
                    </span>
                    <a-checkbox :value="element.key">{{ element.title }}</a-checkbox>
                    <div class="fixed-item">
                      <a-tooltip placement="top" trigger="hover">
                        <template #title>
                          <span>固定到左侧</span>
                        </template>
                        <span
                          :color="element.fixed === 'left' ? '#1e6fff' : undefined"
                          class="cursor-pointer"
                          size="18"
                          @click="fixedColumn(element, 'left')"
                        >
                          <VerticalRightOutlined />
                        </span>
                      </a-tooltip>
                      <a-divider type="vertical" />
                      <a-tooltip placement="top" trigger="hover">
                        <template #title>
                          <span>固定到右侧</span>
                        </template>
                        <span
                          :color="element.fixed === 'right' ? '#1e6fff' : undefined"
                          class="cursor-pointer"
                          size="18"
                          @click="fixedColumn(element, 'right')"
                        >
                          <VerticalLeftOutlined />
                        </span>
                      </a-tooltip>
                    </div>
                  </div>
                </template>
              </Draggable>
            </a-checkbox-group>
          </div>
        </template>
      </a-popover>
    </div>
  </a-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 '@ant-design/icons-vue';
  import Draggable from 'vuedraggable/src/vuedraggable';
  import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
  import type { TableSetting } from '../../types/table';

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

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

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

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

  const { getDarkTheme } = useProjectSetting();
  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([]);

  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.key);
    //重新赋值
    checkList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;
    defaultCheckList.value = !checkAll.value && !checkPart.value ? [] : checkListArr;

    const newColumns = columns.filter(
      (item) => item.type != 'selection' && item.key != 'action' && item.title != '操作',
    );
    if (!basicColumns.value.length) {
      basicColumns.value = cloneDeep(newColumns);
      cacheColumnsList.value = cloneDeep(newColumns);
    }
  }

  //切换
  function onChange(list) {
    if (selection.value) {
      list.unshift('selection');
    }
    const filterColumns = basicColumns.value.filter((item) => {
      return list.includes(item.key);
    });
    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) => {
      item.key = item.key || item.dataIndex;
      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.target.checked) {
      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.key);
    });
    checkList.value = filterColumns.map((item) => item.key);
    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.key as never)) return;
    let columns = getColumns();
    const isFixed = item.fixed === fixed ? undefined : fixed;
    let index = columns.findIndex((res) => res.key === item.key);
    if (index !== -1) {
      columns[index].fixed = isFixed;
    }
    table.setCacheColumnsField(item.key, { fixed: isFixed });
    basicColumns.value[index].fixed = isFixed;
    setColumns(columns);
    emit('columnsChange', table.getColumns());
  }
</script>

<style lang="less" scoped>
  .table-toolbar {
    &-inner-popover-title {
      border-bottom: 1px solid #eee;
      padding-bottom: 10px;
    }

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

    &-inner {
      margin-top: 5px;
      .ant-checkbox-group {
        width: 100%;
      }
      &-checkbox {
        display: flex;
        align-items: center;
        padding: 10px;

        &:hover {
          background: #e6f7ff;
          border-radius: 4px;
        }

        .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;
        }
      }

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