<template>
  <Tooltip placement="top">
    <template #title>
      <span>{{ t('列设置') }}</span>
    </template>
    <Popover
      placement="topRight"
      trigger="click"
      @visible-change="handleVisibleChange"
      :overlayClassName="`${prefixCls}__cloumn-list`"
    >
      <template #title>
        <div :class="`${prefixCls}__popover-title`">
          <Checkbox
            :indeterminate="indeterminate"
            v-model:checked="state.checkAll"
            @change="onCheckAllChange"
          >
            {{ t('列展示') }}
          </Checkbox>

          <a-button size="small" type="link" @click="reset">
            {{ t('重置') }}
          </a-button>
        </div>
      </template>

      <template #content>
        <ScrollContainer>
          <CheckboxGroup v-model:value="state.checkedList" @change="onChange" ref="columnListRef">
            <template v-for="item in plainOptions" :key="item.dataIndex">
              <div :class="`${prefixCls}__check-item`" v-if="item.dataIndex">
                <DragOutlined class="table-column-drag-icon" />
                <Checkbox :value="item.dataIndex"> {{ item.title }} </Checkbox>
              </div>
            </template>
          </CheckboxGroup>
        </ScrollContainer>
      </template>
      <IconFontSymbol icon="shezhi3" fontSize="16" fillColor="#c3c8cf" class="table-setting-icon" />
    </Popover>
  </Tooltip>
</template>
<script lang="ts" setup>
  import { ref, reactive, watchEffect, nextTick, unref, computed, inject, Ref } from 'vue';
  import { Tooltip, Popover, Checkbox, CheckboxGroup } from 'ant-design-vue';
  import { DragOutlined } from '@ant-design/icons-vue';
  import IconFontSymbol from '/@/components/IconFontSymbol/Index.vue';
  import { ScrollContainer } from '/@/components/Container';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { isNullAndUnDef } from '/@/utils/is';
  import { cloneDeep, isBoolean } from 'lodash-es';
  import Sortablejs from 'sortablejs';
  import { SubFormColumn } from '../types';
  import { isValidJSON } from '/@/utils/event/design';
  import { useUserStore } from '/@/store/modules/user';
  const props = defineProps({
    columns: {
      type: Array as PropType<SubFormColumn[]>,
      required: true,
    },
    mainKey: {
      type: String,
      default: () => '',
    },
  });
  interface State {
    checkAll: boolean;
    isInit?: boolean;
    checkedList: string[];
    defaultCheckList: string[];
  }

  interface Options {
    label: string;
    value: string;
    fixed?: boolean | 'left' | 'right';
  }
  const userStore = useUserStore();
  const formId = inject<Ref<string>>('currentFormId') as Ref<string>;
  const emit = defineEmits(['columns-change']);

  const { t } = useI18n();

  let inited = false;

  const plainOptions = ref<Options[] | any>([]);
  const originCol = ref<Options[] | any>(cloneDeep(props.columns));
  const columnListRef = ref<ComponentRef>(null);

  const state = reactive<State>({
    checkAll: true,
    checkedList: [],
    defaultCheckList: [],
  });

  const { prefixCls } = useDesign('basic-column-setting');

  watchEffect(() => {
    if (props.columns.length && !state.isInit) {
      init();
    }
  });

  function init() {
    originCol.value = cloneDeep(props.columns);
    let checkList: any = [];
    let tableColumnShowSetting = isValidJSON(localStorage.getItem('tableColumnShowSetting'));
    if (
      tableColumnShowSetting &&
      formId &&
      tableColumnShowSetting[userStore.getUserInfo.id] &&
      tableColumnShowSetting[userStore.getUserInfo.id][formId.value] &&
      tableColumnShowSetting[userStore.getUserInfo.id][formId.value][props.mainKey]
    ) {
      checkList = tableColumnShowSetting[userStore.getUserInfo.id][formId.value][props.mainKey].map(
        (o) => o.dataIndex,
      );
    } else {
      checkList = props.columns
        .filter(
          (o) =>
            o.dataIndex &&
            ((isBoolean(o.show) && o.show) ||
              (isBoolean(o.componentProps?.isShow) && o.componentProps?.isShow)),
        )
        .map((o) => o.dataIndex);
    }

    if (!plainOptions.value.length) {
      plainOptions.value = props.columns.filter((o) => o.dataIndex);
    }
    state.isInit = true;
    state.checkedList = checkList;
  }

  // checkAll change
  function onCheckAllChange(e) {
    const checkList = plainOptions.value.map((item) => item.dataIndex);
    if (e.target.checked) {
      state.checkedList = checkList;
      setColumns();
    } else {
      state.checkedList = [];
      setColumns();
    }
  }

  const indeterminate = computed(() => {
    const len = plainOptions.value.length;
    let checkedLen = state.checkedList.length;

    return checkedLen > 0 && checkedLen < len;
  });

  // Trigger when check/uncheck a column
  function onChange(checkedList: string[]) {
    const len = plainOptions.value.length;
    state.checkAll = checkedList.length === len;
    setColumns();
  }

  function reset() {
    init();
    setColumns();
  }

  // Open the pop-up window for drag and drop initialization
  function handleVisibleChange() {
    if (inited) return;
    nextTick(() => {
      const columnListEl = unref(columnListRef);
      if (!columnListEl) return;
      const el = columnListEl.$el as any;
      if (!el) return;
      // Drag and drop sort
      Sortablejs.create(unref(el), {
        animation: 500,
        delay: 400,
        delayOnTouchOnly: true,
        handle: '.table-column-drag-icon ',
        onEnd: (evt) => {
          const { oldIndex, newIndex } = evt;
          if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || oldIndex === newIndex) {
            return;
          }
          // Sort column
          const columns = cloneDeep(plainOptions.value);

          if (oldIndex > newIndex) {
            columns.splice(newIndex, 0, columns[oldIndex]);
            columns.splice(oldIndex + 1, 1);
          } else {
            columns.splice(newIndex + 1, 0, columns[oldIndex]);
            columns.splice(oldIndex, 1);
          }

          plainOptions.value = columns;
          const sortList = columns.map((item) => item.dataIndex);
          let startI = -1;
          let newCol: any = [];
          originCol.value.forEach((o, i) => {
            if (o.dataIndex) {
              if (startI === -1) startI = i;
              newCol.push(o);
            }
          });
          newCol.sort((prev, next) => {
            return sortList.indexOf(prev.dataIndex) - sortList.indexOf(next.dataIndex);
          });
          newCol.forEach((o, i) => {
            originCol.value.splice(startI + i, 1, o);
          });
          setColumns();
        },
      });

      inited = true;
    });
  }

  function setColumns() {
    originCol.value.forEach((o) => {
      if (o.dataIndex) {
        o.show = false;
        if (o.componentProps?.isShow !== undefined) {
          o.componentProps.isShow = false;
        }
        if (state.checkedList.includes(o.dataIndex)) {
          o.show = true;
          if (o.componentProps?.isShow !== undefined) {
            o.componentProps.isShow = true;
          }
        }
      }
    });

    let col = originCol.value.filter((o) => o.componentType !== 'SunForm');
    emit('columns-change', cloneDeep(col));
  }
</script>
<style lang="less" scoped>
  @prefix-cls: ~'@{namespace}-basic-column-setting';

  .table-column-drag-icon {
    margin: 0 5px;
    cursor: move;
  }

  .@{prefix-cls} {
    &__popover-title {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }

    &__check-item {
      display: flex;
      align-items: center;
      min-width: 100%;
      padding: 4px 16px 8px 0;

      .ant-checkbox-wrapper {
        width: 100%;

        &:hover {
          color: @primary-color;
        }
      }
    }

    &__cloumn-list {
      svg {
        width: 1em !important;
        height: 1em !important;
      }

      .ant-popover-inner-content {
        // max-height: 360px;
        padding-right: 0;
        padding-left: 0;
        // overflow: auto;
      }

      .ant-checkbox-group {
        width: 100%;
        min-width: 260px;
        // flex-wrap: wrap;
      }

      .scrollbar {
        height: 220px;
      }
    }
  }

  .table-setting-icon {
    border: 1px solid #ddd;
    border-radius: 4px;
    width: 30px;
    height: 30px;
    padding: 5px;
    position: absolute;
    right: 0;
    top: 2px;
  }
</style>
