<template>
    <su-table
        ref="multipleTable"
        :data="tableData"
        @row-click="rowClick"
        v-bind="$attrs"
        v-on="$listeners"
    >
        <el-table-column width="55" column-key="selection" :fixed="checkboxFixed">
            <template
                slot="header"
                slot-scope="scope"
                v-if="showAllCheck"
            >
                <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>
    </su-table>
</template>

<script>
import seTable from "../su-table"
import ListUtil from "../../../util/pattern/list";

export default {
    name: "veCheckPageTable",
    components: {seTable},
    data() {
        return {
            /* 全选按钮是否是选中状态 */
            isAllCheck: false,
            /* 全选按钮是否模糊状态 */
            isIndeterminate: false,
            tableData: [],
            statusMap: {},
            selectionData: []
        }
    },
    props: {
        // 复选框固定
        checkboxFixed: {
            type: [String, Boolean],
            default: false
        },
        data: {
            type: Array,
            default() {
                return [];
            },
        },
        /* 行点击是否能选中 */
        rowSelection: {
            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: {
            immediate: true,
            handler(newV, oldV) {
                if (!newV) return;
                if (!this.across) {
                    this.resetSelectionData();
                }
                this.initData();
            }
        },
    },
    computed: {
        rowKey() {
            return this.$attrs['row-key']
        },
        /* 是否显示全选 有禁用行则不显示*/
        showAllCheck() {
            if (this.tableData.length === 0) return false;
            let hasDisabledRow = false;
            let selectLength = 0;
            for (let i = 0; i < this.tableData.length; i++) {
                let item = this.tableData[i];
                hasDisabledRow = hasDisabledRow || item._status.disabled;
                if (this.hasIdInSelectionData(this.getId(item))) {
                    selectLength++;
                }
                if (hasDisabledRow) {
                    break;
                }
            }
            return !hasDisabledRow && (this.max - this.selectionData.length >= this.tableData.length - selectLength);
        }
    },
    methods: {
        rowClick(row, column, event) {
            if (column.columnKey === 'selection') {
            } else if (this.rowSelection) {
                if (!row._status.disabled && row._status.disableClickTip) {
                    row._status.check = !row._status.check;
                    this.checkChange(row);
                }
            }
            this.$emit("row-click", row, column, event);
        },
        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) {
            this.checkChangeRecompute(row);
            this.$emit("selection-change", this.selectionData, row)
        },
        checkChangeRecompute(row){
            let id = this.getId(row);
            this.delSelectionDataById(id);
            if (this.getStatus(row).check) {
                this.selectionData.push(row);
            }
            this.setSelectStatus();
            this.computeIsAllCheck();
        },
        /**
         * 设置所有行选中状态
         */
        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._toArray(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);
            });
        },
        _toArray(list, key) {
            let array = [];
            if (key) {
                list = ListUtil.toArray(list, key);
            }
            list.forEach(function (item) {
                array.push(item + "");
            })
            return array;
        },
        /**
         * 选择数据是否包含某个id
         */
        hasIdInSelectionData(id) {
            return this._toArray(this.selectionData, this.rowKey).indexOf(id) > -1;
        },
        delSelectionDataById(id) {
            let index = this._toArray(this.selectionData, this.rowKey).indexOf(id);
            if (index > -1) {
                this.selectionData.splice(index, 1);
            }
        },
        /**
         * 重置选择数据
         */
        resetSelectionData() {
            this.selectionData = [];
        },
        /**
         * 移除某个选中数据的选中状态
         */
        removeSelectionItem(item) {
            let vm = this;
            let id = vm.getId(item);
            this.delSelectionDataById(id);
            let row = null;
            this.tableData.forEach(function (row_) {
                if (id == vm.getId(row_)) {
                    row = row_;
                    console.log(">>>>>>",row_);
                }
            });
            if (row) {
                let status = vm.getStatus(row);
                status.check = false;
                vm.checkChangeRecompute(row);
            }
        },
        clearSelection(){
            this.resetSelectionData();
            this.initData();
        },
        /**
         * 计算全选按钮状态
         */
        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.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 scoped>
.disabled-click {
    pointer-events: none;
    cursor: default;
    opacity: 0.6;
}
</style>
