<!--
 * @FileDescription: 数组批量上移、下移
 * @Date: 2023-10-16
 * @LastEditTime: 2023-10-16
-->
<script setup lang="ts">
import { reactive } from 'vue';
import { useMessage } from 'src/common/hooks';

const { warn } = useMessage();

const state = reactive({
    list: [
        {
            title: '1',
            checked: false,
        },
        {
            title: '2',
            checked: false,
        }, {
            title: '3',
            checked: false,
        }, {
            title: '4',
            checked: false,
        }, {
            title: '5',
            checked: false,
        },
        {
            title: '6',
            checked: false,
        },
        {
            title: '7',
            checked: false,
        },
    ],
})

function bulkUp() {
    const selected = state.list.filter(i => i.checked);
    // console.log('selected=', selected);

    if (selected.length === 0) return warn('请选择数据');

    state.list = bulkUpContinue(selected, state.list, 'title');
    // console.log('上移list', state.list);

}
/**
 * @description 批量上移
 * @param {any[]} selected 勾选的数据列表
 * @param {any[]} target 当前数组列表
 * @param {string} uniqueKey 唯一的key
 * @return {any[]} 返回的新数组列表
 */
function bulkUpContinue(selected: any[], target: any[], uniqueKey: string) {

    if (selected.length > 0) {
        const item = selected[0];
        const afterMoveList = upOne(item, target, uniqueKey);

        if (selected.length > 1) {
            const afterMoveSelected = selected.slice(1);
            return bulkUpContinue(afterMoveSelected, afterMoveList, uniqueKey);
        } else {
            return afterMoveList;
        }
    } else {
        return target;
    }
}
/**
 * @description 单个上移
 * @param {any} checked 勾选的一条数据
 * @param {any[]} target 当前数组列表
 * @param {string} uniqueKey 唯一的key
 * @return {any[]} 返回的新数组列表
 */
function upOne(checked: any, target: any[], uniqueKey: string) {
    if (target.length === 0) {
        return [];
    } else {

        const key = checked[uniqueKey];
        // 勾选数据的下标
        const index = target.findIndex(i => i[uniqueKey] === key);
        // 勾选数据的前一个下标
        const lastIndex = index === 0 ? target.length - 1 : index - 1;

        const newList = [] as any[];
        if (index === 0) {
            let i = 0;
            for (const item of target) {
                if (i > 0) {
                    newList.push(item);
                }
                i = i + 1;
            };
            newList.push(target[0]);
        } else {
            let i = 0;
            for (const item of target) {
                if (i === lastIndex) {
                    newList.push(target[index]);
                } else if (i === index) {
                    newList.push(target[lastIndex]);
                } else {
                    newList.push(item);
                }
                i = i + 1;
            }
        }
        return newList;
    }
}
// function oneUp() {
//     const selected = state.list.filter(i => i.checked);
//     if (selected.length === 1) {
//         const list = upOne(selected[0], state.list);
//         state.list = list;
//         console.log('list', list);

//     } else {
//         return;
//     }
// }
// function oneDown() {
//     const selected = state.list.filter(i => i.checked);
//     if (selected.length === 1) {
//         const list = downOne(selected[0], state.list, 'title');
//         state.list = list;
//         console.log('list', list);

//     } else {
//         return;
//     }
// }

function batchDown() {
    const selected = state.list.filter(i => i.checked);
    // console.log('selected=', selected);

    if (selected.length === 0) return warn('请选择数据');

    state.list = batchDownContinue(selected, state.list, 'title');
    // console.log('下移list', state.list);
}
/**
 * @description 批量下移
 * @param {any[]} selected 勾选的数据列表
 * @param {any[]} target 当前数组列表
 * @param {string} uniqueKey 唯一的key
 * @return {any[]} 返回的新数组列表
 */
function batchDownContinue(selected: any[], target: any[], uniqueKey: string) {

    if (selected.length > 0) {
        const item = selected[selected.length - 1]; // 从最后一个开始
        const afterMoveList = downOne(item, target, uniqueKey);

        if (selected.length > 1) {
            const afterMoveSelected = selected.slice(0, selected.length - 1);
            return batchDownContinue(afterMoveSelected, afterMoveList, uniqueKey);
        } else {
            return afterMoveList;
        }
    } else {
        return target;
    }
}
/**
 * @description 单个下移
 * @param {any} checked 勾选的一条数据
 * @param {any[]} target 当前数组列表
 * @param {string} uniqueKey 唯一的key
 * @return {any[]} 返回的新数组列表
 */
function downOne(checked: any, target: any[], uniqueKey: string) {
    if (target.length === 0) {
        return [];
    } else {

        const key = checked[uniqueKey];
        // 勾选数据的下标
        const index = target.findIndex(i => i[uniqueKey] === key);
        // 勾选数据的后一个下标
        const nextIndex = index === target.length - 1 ? 0 : index + 1;

        const newList = [] as any[];
        if (index === target.length - 1) {
            newList.push(target[target.length - 1]);
            let i = 0;
            for (const item of target) {
                if (i < target.length - 1) {
                    newList.push(item);
                }
                i = i + 1;
            };

        } else {
            let i = 0;
            for (const item of target) {
                if (i === index) {
                    newList.push(target[nextIndex]);
                } else if (i === nextIndex) {
                    newList.push(target[index]);
                } else {
                    newList.push(item);
                }
                i = i + 1;
            }
        }
        return newList;
    }
}

</script>
<template>
    <div>
        <div>
            <q-btn color="primary" label="批量上移" @click="bulkUp" />
            <q-btn color="primary" label="批量下移" @click="batchDown" />
            <!-- <q-btn color="primary" label="单个上移" @click="oneUp" /> -->
            <!-- <q-btn color="primary" label="单个下移" @click="oneDown" /> -->
        </div>
        <div class="column">
            <q-checkbox v-model="i.checked" :label="i.title" v-for="(i) in state.list" :key="i.title" />
        </div>
    </div>
</template>

<style lang="scss" scoped></style>
