<template>
    <!-- 可拖拽表格 -->
    <su-table
            ref="table"
            :data="data"
            :class="tableClass"
            v-bind="$attrs"
            v-on="$listeners"
    >
        <el-table-column width="55">
            <template
                    slot="header"
                    slot-scope="scope"
            >
                <el-checkbox
                        v-model="isAllCheck"
                        :indeterminate="isIndeterminate"
                        @change="()=>{clickAllCheck();}"
                ></el-checkbox>
            </template>
            <template slot-scope="scope">
                <el-tooltip effect="dark"
                            :disabled="scope.row._status.disableClickTip"
                            :content="maxOverflowTipContent"
                            placement="top-end">
                    <div>
                        <el-checkbox
                                :class="{'disabled-click':scope.row._status.disableClick}"
                                v-model="scope.row._status.check"
                                :disabled="scope.row._status.disabled"
                                @change="()=>{checkChange(scope.row);}"
                        ></el-checkbox>
                    </div>
                </el-tooltip>
            </template>
        </el-table-column>
        <slot></slot>
        <el-table-column label="" width="50" v-if="moveIcon">
            <template :slot-scope="scope">
                <div class="move">
                    <i class="el-icon-rank" style="font-size: 25px;"></i>
                </div>
            </template>
        </el-table-column>
    </su-table>
</template>

<script>
import seTable from '../su-table/index.vue';
import Sortable from "sortablejs";
import ListUtil from "../../../util/pattern/list";
// https://www.itxst.com/sortablejs/neuinffi.html
export default {
    name: "veDragTable",
    components: {
        seTable
    },
    props: {
        data: {
            type: Array,
            default: [],
            selected: false
        },
        allScroll: {
            type: Boolean,
            default: false,
        },
        moveIcon: {
            type: Boolean,
            default: true,
        },
        /* 是否跨页选择 */
        across: {
            type: Boolean,
            default: false,
        },
        /* 禁止选择的数据项id数组 */
        disabledIds: {
            type: Array,
            default() {
                return [];
            },
        },
        /* 最大选择数量 */
        max: {
            type: Number,
            default: 999,
        },
        /* 超出最大选择数量的提示文字 */
        maxOverflowTipContent: {
            type: String,
            default: "已达到最大选择数量",
        }
    },
    watch: {
        data(newV, oldV) {
            if (!newV) return;
            if (!this.across) {
                this.resetSelectionData();
            }
            this.initData();
        }
    },
    computed: {
        rowKey() {
            return this.$attrs['row-key']
        },
        tableClass() {
            let map = {};
            map[this.renderClass] = true;
            map['all-scroll'] = this.isAllScroll;
            return map
        },
        isAllScroll(){
            return this.allScroll||!this.moveIcon;
        },
    },
    mounted() {
        const table = document.querySelector(
                "." + this.renderClass + " .el-table__body-wrapper tbody"
        );
        const self = this;
        Sortable.create(table, {
            animation: 200,
            delay: 20,sort: true,  // sorting inside list
            handle: self.isAllScroll?"":".move",
            onEnd({newIndex, oldIndex}) {
                self.$emit("sortChange", {
                    resolve() {
                        return;
                    },
                    reject() {
                        self.changeRow(oldIndex, newIndex);
                    },
                    rowData: self.data[oldIndex],
                    newIndex: newIndex,
                    oldIndex: oldIndex
                });
                self.changeRow(newIndex, oldIndex);
            }
        });
    },
    data() {
        return {
            renderClass: "id" + parseInt(Number(Math.random() * 10000000000)),
            statusMap: {},
            selectionData: [],
            /* 全选按钮是否是选中状态 */
            isAllCheck: false,
            /* 全选按钮是否模糊状态 */
            isIndeterminate: false,
        };
    },
    methods: {
        changeRow(newIndex, oldIndex) {
            //换位子
            const targetRow = this.data.splice(oldIndex, 1)[0];
            this.data.splice(newIndex, 0, targetRow);
        },
        initData() {
            this.setSelectStatus(this.data);
            this.tableData = this.data;
            this.computeIsAllCheck();
        },
        getStatus(item) {
            let id = this.getId(item);
            if (!this.statusMap[id]) {
                this.$set(this.statusMap, id, {
                    check: false,
                    disabled: false,
                    disableClick: false,
                    disableClickTip: false,
                });
            }
            return this.statusMap[id]
        },
        setSelectionData(list) {
            this.selectionData = [...list];
            this.initData();
        },
        getSelectionData() {
            return [...this.selectionData];
        },
        getId(item) {
            return item[this.rowKey]
        },
        /**
         * 点击某一项的选择事件
         */
        checkChange(row) {
            let id = this.getId(row);
            this.delSelectionDataById(id);
            if (this.getStatus(row).check) {
                this.selectionData.push(row);
            }
            this.setSelectStatus();
            this.computeIsAllCheck();
            this.$emit("selection-change", this.selectionData, row)
        },
        setSelectStatus(data = this.tableData) {
            let vm = this;
            data.forEach(function (item) {
                let id = vm.getId(item);
                let status = vm.getStatus(item);
                item._status = status;
                status.check = vm.hasIdInSelectionData(id);
                status.disabled = vm.disabledIds.indexOf(id) > -1;
                status.disableClick = !status.check && vm.selectionData.length >= vm.max;
                status.disableClickTip = !(!status.disabled && !status.check && vm.selectionData.length >= vm.max);
            });
        },
        /**
         * 选择数据是否包含某个id
         */
        hasIdInSelectionData(id) {
            return ListUtil.toArray(this.selectionData, this.rowKey).indexOf(id) > -1;
        },
        delSelectionDataById(id) {
            let index = ListUtil.toArray(this.selectionData, this.rowKey).indexOf(id);
            if (index > -1) {
                this.selectionData.splice(index, 1);
            }
        },
        /**
         * 重置选择数据
         */
        resetSelectionData() {
            this.selectionData = [];
        },
        /**
         * 计算全选按钮状态
         */
        computeIsAllCheck() {
            let length = 0;
            for (let i = 0; i < this.tableData.length; i++) {
                let row = this.tableData[i];
                let status = this.getStatus(row);
                if (status.check) {
                    length += 1;
                }
            }
            if (length === this.tableData.length && this.tableData.length!=0) {
                this.isIndeterminate = false;
                this.isAllCheck = true;
            } else if (length > 0) {
                this.isIndeterminate = true;
                this.isAllCheck = false;
            } else {
                this.isIndeterminate = false;
                this.isAllCheck = false;
            }
        },
        /**
         * 点击全选
         */
        clickAllCheck() {
            console.log("clickAllCheck");
            let vm = this;
            this.isIndeterminate = false;
            this.tableData.forEach(function (row) {
                let id = vm.getId(row);
                vm.delSelectionDataById(id);
                let status = vm.getStatus(row);
                status.check = vm.isAllCheck;
                if (vm.isAllCheck) {
                    vm.selectionData.push(row);
                }
            })
            this.$emit("selection-change", this.selectionData)
        }
    }
};
</script>

<style lang="less" scoped>
.move {
    cursor: all-scroll;
}

.all-scroll {
    /deep/ .el-table__row {
        cursor: all-scroll;
    }
}
</style>
