<template>
  <div ref="draggable" class="draggable">
    <div
      v-for="(element, index) in sortedData"
      :key="element.id || element.pageId"
      :data_id="element[itemKey] || index"
      :data_index="index"
      :data_key="element.id || element.pageId"
    >
      <slot name="item" :element="element" :index="index"></slot>
    </div>
  </div>
</template>

<script setup>
import Sortable from 'sortablejs';
import { computed, onMounted, ref } from 'vue';

const props = defineProps({
  itemKey: {
    type: String,
    default: ''
  },
  handle: {
    type: String,
    default: ''
  },
  filter: {
    type: String,
    default: ''
  },
  chosenClass: {
    type: String,
    default: ''
  },
  animation: {
    type: [String, Number],
    default: 0
  },
  scroll: {
    type: Boolean,
    default: true
  },
  group: {
    type: String,
    default: ''
  },
  move: {
    type: Function,
    default: () => {
      // 后续扩展
    }
  }
});
// 是否是预览状态，非预览状态不进行排序
let isPreview = defineModel('isPreview', { default: false, type: Boolean });

const data = defineModel('data', {
  type: Array,
  default: () => []
});

// 排序之后的数组
const sortedData = computed(() => {
  // 如果不是预览状态，不进行排序
  if (!isPreview.value) return data.value;
  // 置底选项数组
  const lastOptions = data.value.filter((item) => {
    return item.is_fixed === 1;
  });
  // 排他选项数组
  const remoteOtherOptions = data.value.filter((item) => {
    return item.is_remove_other === 1;
  });

  //  剩余的 options
  const otherOptions = data.value.filter((item) => {
    return !item.is_fixed && !item.is_remove_other;
  });
  // 顺序 ： 剩余选项 + 置底选项 + 排他选项
  return [...otherOptions, ...lastOptions, ...remoteOtherOptions];
});

const emit = defineEmits(['update:data', 'end']);

const sortable = ref(null);
const draggable = ref(null);
// const copyData = reactive([]);

const options = {
  handle: props.handle,
  filter: props.filter,
  chosenClass: props.chosenClass,
  animation: props.animation,
  scroll: props.scroll,
  scrollSensitivity: 100,
  forceFallback: true,
  scrollSpeed: 30,
  group: props.group,
  onMove: (evt) => {
    const index = evt.related.getAttribute('data_index');
    evt.newIndex = Number(index);
    return props.move(evt);
  },
  // 拖动结束
  onEnd: (evt) => {
    evt.stopPropagation();
    const tempData = JSON.parse(JSON.stringify(data.value));
    const oldEle = tempData[evt.oldIndex];
    data.value.splice(evt.oldIndex, 1);
    data.value.splice(evt.newIndex, 0, oldEle);
    // data.value = tempData;
    // emit('update:data', tempData);
    emit('end', evt);
  }
};

onMounted(() => {
  if (sortable.value) sortable.value.destroy();
  sortable.value = Sortable.create(draggable.value, options);
});
</script>
