<template>
  <Tooltip placement="top">
    <template #title>
      <span>{{ $t('component.table.settingColumn') }}</span>
    </template>
    <Popover
placement="bottomLeft" trigger="click" overlay-class-name="cloumn-list"
      @visible-change="handleVisibleChange">
      <template #title>
        <div class="popover-title">
          <Checkbox v-model:checked="checkAll" :indeterminate="indeterminate">
            {{ $t('component.table.settingColumnShow') }}
          </Checkbox>
          <Checkbox v-model:checked="checkIndex" @change="handleIndexCheckChange">
            {{ $t('component.table.settingIndexColumnShow') }}
          </Checkbox>
          <Checkbox v-model:checked="checkBordered" @change="handleBorderedCheckChange">
            {{ $t('component.table.settingBordered') }}
          </Checkbox>
          <a-button size="small" type="link" @click="reset">
            {{ $t('common.resetText') }}
          </a-button>
        </div>
      </template>
      <template #content>
        <div ref="columnListRefLeft">
          <template v-for="item in leftCols" :key="table.getColumnKey(item)">
            <div class="check-item">
              <div style="padding: 4px 16px 8px 0">
                <DragOutlined class="table-column-drag-icon pr-6px cursor-move" />
                <Checkbox v-model:checked="item.hideInTable" :true-value="false" :false-value="true">
                  {{ item.title }}
                </Checkbox>
              </div>
              <div class="column-fixed">
                <Tooltip placement="bottomLeft" :mouse-leave-delay="0.4">
                  <template #title> {{ $t('component.table.settingFixedLeft') }} </template>
                  <VerticalRightOutlined
class="fixed-left" :class="{ active: item.fixed === 'left' }"
                    @click="handleColumnFixed(item, 'left')" />
                </Tooltip>
                <Divider type="vertical" />
                <Tooltip placement="bottomLeft" :mouse-leave-delay="0.4">
                  <template #title> {{ $t('component.table.settingFixedRight') }} </template>
                  <VerticalLeftOutlined
class="fixed-right" :class="{ active: item.fixed === 'right' }"
                    @click="handleColumnFixed(item, 'right')" />
                </Tooltip>
              </div>
            </div>
          </template>
        </div>
        <div ref="columnListRefCom">
          <a-divider style="border-color: #7cb305;margin: 2px 0;height: 2px;" v-if="leftCols.length > 0" />
          <template v-for="item in comCols" :key="table.getColumnKey(item)">
            <div class="check-item">
              <div style="padding: 4px 16px 8px 0">
                <DragOutlined class="table-column-drag-icon pr-6px cursor-move" />
                <Checkbox v-model:checked="item.hideInTable" :true-value="false" :false-value="true">
                  {{ item.title }}
                </Checkbox>
              </div>
              <div class="column-fixed">
                <Tooltip placement="bottomLeft" :mouse-leave-delay="0.4">
                  <template #title> {{ $t('component.table.settingFixedLeft') }} </template>
                  <VerticalRightOutlined
class="fixed-left" :class="{ active: item.fixed === 'left' }"
                    @click="handleColumnFixed(item, 'left')" />
                </Tooltip>
                <Divider type="vertical" />
                <Tooltip placement="bottomLeft" :mouse-leave-delay="0.4">
                  <template #title> {{ $t('component.table.settingFixedRight') }} </template>
                  <VerticalLeftOutlined
class="fixed-right" :class="{ active: item.fixed === 'right' }"
                    @click="handleColumnFixed(item, 'right')" />
                </Tooltip>
              </div>
            </div>
          </template>
        </div>
        <div ref="columnListRefRight">
          <a-divider style="border-color: #7cb305;margin: 5px 0;height: 2px;" v-if="rightCols.length > 0" />
          <template v-for="item in rightCols" :key="table.getColumnKey(item)">
            <div class="check-item">
              <div style="padding: 4px 16px 8px 0">
                <DragOutlined class="table-column-drag-icon pr-6px cursor-move" />
                <Checkbox v-model:checked="item.hideInTable" :true-value="false" :false-value="true">
                  {{ item.title }}
                </Checkbox>
              </div>
              <div class="column-fixed">
                <Tooltip placement="bottomLeft" :mouse-leave-delay="0.4">
                  <template #title> {{ $t('component.table.settingFixedLeft') }} </template>
                  <VerticalRightOutlined
class="fixed-left" :class="{ active: item.fixed === 'left' }"
                    @click="handleColumnFixed(item, 'left')" />
                </Tooltip>
                <Divider type="vertical" />
                <Tooltip placement="bottomLeft" :mouse-leave-delay="0.4">
                  <template #title> {{ $t('component.table.settingFixedRight') }} </template>
                  <VerticalLeftOutlined
class="fixed-right" :class="{ active: item.fixed === 'right' }"
                    @click="handleColumnFixed(item, 'right')" />
                </Tooltip>
              </div>
            </div>
          </template>
        </div>
      </template>
      <SettingOutlined />
    </Popover>
  </Tooltip>
</template>

<script lang="ts" setup>
import { computed, nextTick, ref, unref, watch } from 'vue';
import {
  SettingOutlined,
  VerticalRightOutlined,
  VerticalLeftOutlined,
  DragOutlined,
} from '@ant-design/icons-vue';
import { cloneDeep } from 'lodash-es';
import { Tooltip, Popover, Divider } from 'ant-design-vue';
import { useTableContext } from '../../hooks/useTableContext';
import type { TableColumn } from '../../types/column';
import Checkbox from '@/components/basic/check-box/index.vue';
import { useSortable } from '../../hooks/useSortable';
import { isNullAndUnDef } from '../../../../../utils/is';
import { formatAutoCols } from "../../hooks/commonMethods"


type TableColumnType<T = any> = TableColumn<T> & {
  /** 目的是解决：类型实例化过深，且可能无限 */
  formItemProps?: any;
};

const emit = defineEmits(['clos-change-by-tools', "edit-row-data-change"]);

const table = useTableContext();
let inited = false;

const defaultColumns = cloneDeep<TableColumnType[]>(table.columns.length > 0 ? table.columns : formatAutoCols(table, emit));

const defaultShowIndex = !!table.showIndex;
const defaultBordered = table.bordered;
const tableColumns = ref<TableColumnType[]>([]);

const checkAll = computed<boolean>({
  get() {
    return tableColumns.value.length > 0 && tableColumns.value.every((n) => !n.hideInTable);
  },
  set(value) {
    tableColumns.value.forEach((item) => (item.hideInTable = !value));
  },
});

const checkIndex = ref(defaultShowIndex);
const checkBordered = ref(table.bordered);
const columnListRefLeft = ref<HTMLDivElement>();
const columnListRefCom = ref<HTMLDivElement>();
const columnListRefRight = ref<HTMLDivElement>();

// 初始化选中状态
const initCheckStatus = () => {
  //@ts-ignore
  tableColumns.value = cloneDeep(defaultColumns);
  checkIndex.value = defaultShowIndex;
  checkBordered.value = defaultBordered;
  tableColumns.value.forEach((item) => (item.hideInTable ??= false));
  table.setProps({
    //@ts-ignore
    columns: tableColumns.value
  })
};
initCheckStatus();

const indeterminate = computed(() => {
  return (
    tableColumns.value.length > 0 &&
    tableColumns.value.some((n) => n.hideInTable) &&
    tableColumns.value.some((n) => !n.hideInTable)
  );
});

const leftCols = computed(() => {
  return tableColumns.value.filter((item) => {
    return item.fixed == true || item.fixed == 'left'
  })
})

const rightCols = computed(() => {
  return tableColumns.value.filter((item) => {
    return item.fixed == "right"
  })
})

const comCols = computed(() => {
  return tableColumns.value.filter((item) => {
    return typeof item.fixed == 'undefined' || item.fixed == false
  })
})

watch(
  tableColumns,
  (columns) => {
    //@ts-ignore
    table.setProps({ columns });
  },
  {
    deep: true,
  },
);
// 设置序号列
const handleIndexCheckChange = (e) => {
  table.setProps({ showIndex: e.target.checked });
};
// 设置边框
const handleBorderedCheckChange = (e) => {
  table.setProps({ bordered: e.target.checked });
};

const handleColumnFixed = (columItem: TableColumn, direction: 'left' | 'right') => {

  columItem.fixed = columItem.fixed === direction ? false : direction;
  for (let i = 0; i < tableColumns.value.length; i++) {
    if (tableColumns.value[i].dataIndex == columItem.dataIndex) {
      if (columItem.fixed == 'left') {
        tableColumns.value.splice(i, 1)
        tableColumns.value.unshift(columItem)
      } else {
        let targetCols = tableColumns.value.filter((item) => {

          return item.dataIndex?.toString().toLowerCase() == 'action'
        })
        if (targetCols.length > 0) {
          tableColumns.value.splice(i, 1)
          //如果有操作列的情况下，要把操作列固定在最右侧
          let tempItem = tableColumns.value.pop()
          tableColumns.value.push(columItem)
          //@ts-ignore
          tableColumns.value.push(tempItem)
        } else {
          tableColumns.value.splice(i, 1)
          tableColumns.value.push(columItem)
        }
      }
    }
  }
  //@ts-ignore
  table.setProps({ columns: tableColumns.value });
  if (table.columnFilter.length > 0)
    emit("clos-change-by-tools", tableColumns.value) //工具栏中设置改变的时候需要通知外部进行变更
};

async function handleVisibleChange() {
  if (inited) return;
  await nextTick();
  const columnListEl = unref(columnListRefLeft);
  if (!columnListEl) return;
  const columnListCom = unref(columnListRefCom)
  const columnListRight = unref(columnListRefRight)
  // Drag and drop sort
  const { initSortable } = useSortable(columnListEl, columnListCom, columnListRight, {
    handle: '.table-column-drag-icon',
    onEnd: (evt) => {
      const { oldIndex, newIndex } = evt;
      if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {
        return;
      }
      const columns = tableColumns.value;
      columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]);
      if (table.columnFilter.length > 0)
        emit("clos-change-by-tools", tableColumns.value) //工具栏中设置改变的时候需要通知外部进行变更
    }
  });
  initSortable();
  inited = true;
}

const reset = () => {
  initCheckStatus();
  table.setProps({ showIndex: defaultShowIndex, bordered: defaultBordered });
};
</script>

<style lang="less" scoped>
.check-item {
  @apply flex justify-between;
}

.column-fixed {

  .fixed-right,
  .fixed-left {

    &.active,
    &:hover {
      color: #1890ff;
    }
  }
}
</style>
