<template>
    <div id="VirtualList">
        <div class="v-top v-content">
            <p class="v-header">
                <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">所有公众号</el-checkbox>
                <span>{{checkedLeftAcc.length}}/{{list.length}}</span>
            </p>
            <div class="v-search">
                <el-input
                    placeholder="请输入公众号"
                    prefix-icon="el-icon-search"
                    clearable
                    v-model="leftSearch">
                </el-input>
            </div>
            <div class="list-wrap" ref="listWrap" @scroll="scrollListener">
                <div class="scroll-bar" ref="scrollBar"></div>
                <el-checkbox-group v-model="checkedLeftAcc" @change="handleCheckedLeftAccChange" v-if="list.length > 0">
                    <ul class="list" ref="list">
                        <li v-for="val in showList" :key="val.key" :style="{height: itemHeight + 'px'}"><el-checkbox :label="val.key">{{val.label}}</el-checkbox></li>
                    </ul>
                </el-checkbox-group>
                <div v-else style="text-align: center; padding: 20px 0;">无{{leftSearch ? '匹配': ''}}数据</div>
            </div>
        </div>
        <div class="v-center">
            <el-button type="primary" icon="el-icon-arrow-left" circle :disabled='checkedRightAcc.length === 0' @click="handleRight"></el-button>
            <el-button type="primary" icon="el-icon-arrow-right" circle :disabled='checkedLeftAcc.length === 0' @click="handleLeft"></el-button>
        </div>
        <div class="v-bottom v-content">
            <p class="v-header">
                <el-checkbox :indeterminate="isIndeterminateRight" v-model="checkRightAll" @change="handleCheckAllRightChange">已选公众号</el-checkbox>
                <span>{{checkedRightAcc.length}}/{{listRight.length}}</span>
            </p>
            <div class="v-search">
                <el-input
                    placeholder="请输入公众号"
                    prefix-icon="el-icon-search"
                    clearable
                    v-model="rightSearch">
                </el-input>
            </div>
            <div class="list-wrap" ref="listWrapRight" @scroll="scrollListenerRight">
                <div class="scroll-bar" ref="scrollBarRight"></div>
                <el-checkbox-group v-model="checkedRightAcc" @change="handleCheckedRightAccChange" v-if="listRight.length > 0">
                    <ul class="list" ref="listRight">
                        <li v-for="val in showListRight" :key="val.key" :style="{height: itemHeight + 'px'}"><el-checkbox :label="val.key">{{val.label}}</el-checkbox></li>
                    </ul>
                </el-checkbox-group>
                <div v-else style="text-align: center; padding: 20px 0;">无{{rightSearch ? '匹配': ''}}数据</div>
            </div>
        </div>
    </div>
</template>

<script>
import { debounce } from '@/utils'
let _this = null
export default {
    props: {
        data: {
            type: Array,
            default: ()=>[],
        },
        selectData: {
            type: Array,
            default: ()=>[]
        }
    },
    data() {
        return {
            LeftData: [], // 搜索 取消搜索 使用
            rightData: [], 
            list: [],// 左边的显示数据
            itemHeight: 30,//每一列的高度
            showNum: 10,//显示几条数据
            start: 0,//滚动过程显示的开始索引
            end: 10,//滚动过程显示的结束索引
            checkAll: false, // 左边全选显示
            isIndeterminate: false, // 左边控制全选按钮显示
            leftSearch: '', // 左边搜索输入内容
            checkedLeftAcc: [], // 左边选择勾选的内容
            
            startRight: 0,//滚动过程显示的开始索引
            endRight: 10,//滚动过程显示的结束索引
            listRight: [], // 右边显示数据
            checkedRightAcc: [], // 右边选择的勾选的内容
            rightSearch: '', // 右边搜索输入内容
            checkRightAll: false, // 左边全选显示
            isIndeterminateRight: false, // 左边控制全选按钮显示
        }
    },
    computed: {
        //显示的数组，用计算属性计算
        showList(){
            return this.list.slice(this.start, this.end);
        },
        showListRight() {
            return this.listRight.slice(this.startRight, this.endRight);
        }
    },
    created() { 
        _this = this
        this.handleData()
    },
    watch: {
        selectData: {
            handler(val) {
                this.handleData()
            },
            deep: true
        },
        list: {
            handler(val, oldVal) {
                if(val) {
                    //计算滚动容器高度
                    // this.$refs.listWrap.style.height = this.itemHeight * this.showNum + 'px';
                    //计算总的数据需要的高度，构造滚动条高度
                    this.$refs.scrollBar.style.height = this.itemHeight * val.length + 'px';
                    if(this.checkedLeftAcc.length > 0) {
                        if(val.length === this.checkedLeftAcc.length) {
                            this.isIndeterminate = false
                            this.checkAll = true
                        }else{
                            this.isIndeterminate = true
                        }
                    }
                }
            }
        },
        listRight: {
            handler(val, oldVal) {
                this.$nextTick(()=>{
                    let ids = val.map(item => item.key)
                    this.$emit('input', ids);
                })
                if(val) {
                    //计算滚动容器高度
                    // this.$refs.listWrap.style.height = this.itemHeight * this.showNum + 'px';
                    //计算总的数据需要的高度，构造滚动条高度
                    this.$refs.scrollBarRight.style.height = this.itemHeight * val.length + 'px';
                    if(this.checkedRightAcc.length > 0) {
                        if(val.length === this.checkedRightAcc.length) {
                            this.isIndeterminateRight = false
                            this.checkRightAll = true
                        }else{
                            this.isIndeterminateRight = true
                        }
                    }
                }
            },
        },
        leftSearch: {
            handler(val) {
                this.searchLeftAcc({ vm: this, val });
            }
        },
        rightSearch: {
            handler(val) {
                console.log(val);
                this.searchRightAcc({ vm: this, val });
            }
        },
        checkedLeftAcc: {
            handler(val, oldVal) {
                /** 根据checkedLeftAcc 全选按钮的显示 */
                if(val.length > 0){
                    if(this.list.length <= val.length) {
                        this.isIndeterminate = false
                        this.checkAll = true
                    }else{
                        this.isIndeterminate = true
                    }
                }else{
                    this.isIndeterminate = false
                }
            }
        },
        checkedRightAcc: {
            handler(val, oldVal) {
                /** 根据checkedLeftAcc 全选按钮的显示 */
                if(val.length > 0){
                    if(this.listRight.length <= val.length) {
                        this.isIndeterminateRight = false
                        this.checkRightAll = true
                    }else{
                        this.isIndeterminateRight = true
                    }
                }else{
                    this.isIndeterminateRight = false
                }
            }
        }
    },
    methods: {
        scrollListener(){
            //获取滚动高度
            let scrollTop = this.$refs.listWrap.scrollTop;
            //开始的数组索引
            this.start = Math.floor(scrollTop / this.itemHeight);
            //结束索引
            this.end = this.start + this.showNum;
            //绝对定位对相对定位的偏移量
            this.$refs.list.style.top = this.start * this.itemHeight + 'px';
        },
        scrollListenerRight(){
            let scrollTop = this.$refs.listWrapRight.scrollTop;
            this.startRight = Math.floor(scrollTop / this.itemHeight);
            this.endRight = this.startRight + this.showNum;
            this.$refs.listRight.style.top = this.startRight * this.itemHeight + 'px';
        },
        /** 选择公众号 */
        handleLeft() {
            this.list = this.LeftData.filter(item => !this.checkedLeftAcc.includes(item.key))
            let newRightData = this.LeftData.filter(item => this.checkedLeftAcc.includes(item.key))
            this.listRight = [...this.listRight, ...newRightData]
            this.LeftData = this.list
            this.rightData = this.listRight
            this.checkedLeftAcc = []
            this.leftSearch = ""
        },
        /** 删除公众号 */
        handleRight() {
            this.listRight = this.rightData.filter(item => !this.checkedRightAcc.includes(item.key))
            let listRightIds = this.listRight.map(item => item.key)
            this.list = this.data.filter(item => !listRightIds.includes(item.key))
            this.LeftData = this.list
            this.rightData = this.listRight
            this.checkedRightAcc = []
            this.rightSearch = ""
        },
        /** 首次进来 改变数据处理数据 */
        handleData() {
            if(this.selectData.length > 0) {
                this.list = this.data.filter(item => !this.selectData.includes(item.key))
                this.listRight = this.data.filter(item => this.selectData.includes(item.key))
                this.$nextTick(()=>{
                    this.$emit('input', this.selectData);
                })
            }else{
                this.list = this.data
                this.listRight = []
            }
            this.LeftData = this.list
            this.rightData = this.listRight
        },
        /** 左边查询查询公众号 */
        searchLeftAcc: debounce(() => {
            if(_this.leftSearch) {
                _this.list = _this.LeftData.filter(item => {
                    if(item && item.label) {
                        let Vals = _this.leftSearch.split(',')
                        for(let key = 0; key <= Vals.length; key++) {
                            if(Vals[key] && item.label.indexOf(Vals[key]) !== -1) {
                                return true
                            }
                            if(key >= Vals.length) {
                                return false
                            }
                        }
                    }
                })
                // _this.list = _this.LeftData.filter(item => {
                //     if(item && item.label) {
                //         return item.label.indexOf(_this.leftSearch) !== -1
                //     }
                // })
            }else{
                _this.list = _this.LeftData
            }
            
	    }, 300),
        /** 右边查询查询公众号 */
        searchRightAcc: debounce(() => {
            if(_this.rightSearch) {
                _this.listRight = _this.rightData.filter(item => {
                    if(item && item.label) {
                        let Vals = _this.rightSearch.split(',')
                        for(let key = 0; key <= Vals.length; key++) {
                            if(Vals[key] && item.label.indexOf(Vals[key]) !== -1) {
                                return true
                            }
                            if(key >= Vals.length) {
                                return false
                            }
                        }
                    }
                })
                // _this.listRight = _this.rightData.filter(item => {
                //     if(item && item.label) {
                //         return item.label.indexOf(_this.rightSearch) !== -1
                //     }
                // })
            }else{
                _this.listRight = _this.rightData
            }
            
	    }, 300),
        /** 左边全选按钮触发 */
        handleCheckAllChange(val) {
            if(val){
                this.checkedLeftAcc = this.list.map(item => item.key)
            }else{
                this.checkedLeftAcc = []
            }
        },
        /** 左边勾选多选触发事件 */
        handleCheckedLeftAccChange(value) {
            this.checkedLeftAcc = value
        },
        /** 右边全选按钮触发 */
        handleCheckAllRightChange(val) {
            if(val){
                this.checkedRightAcc = this.listRight.map(item => item.key)
            }else{
                this.checkedRightAcc = []
            }
        },
        /**  */
        handleCheckedRightAccChange(value) {
            this.checkedRightAcc = value
        }
    }
}
</script>

<style lang="scss">
#VirtualList {
    display: flex;
    justify-content: flex-start;
    .v-content {
        border: 1px solid #ebeef5;
        border-radius: 4px;
        overflow: hidden;
        background: #fff;
        width: 200px;
        .v-header{
            height: 40px;
            line-height: 40px;
            background: #f5f7fa;
            margin: 0;
            padding: 0 15px;
            border-bottom: 1px solid #ebeef5;
            box-sizing: border-box;
            color: #000;
            display: flex;
            justify-content: space-between;
            &>span {
                color: #909399;
                font-size: 12px;
                font-weight: 400;
            }
        }
        .v-search{
            margin: 12px;
            .el-input__inner{
                border-radius: 18px;
            }
        }
        .list-wrap{
            position: relative;
            overflow-y: scroll;
            width: 100%;
            height: 200px;
            box-sizing: border-box;
        }
        .list{
            width: 100%;
            position: absolute;
            top: 0;
            left: 0;
            padding: 0 20px;
            margin: 0;
        }
        .list li{
            list-style: none;
            line-height: normal;
            display: flex;
            align-items: center;
        }
    }

    .v-center{
        display: flex;
        flex-direction: column;
        padding: 0 18px;
        justify-content: center;
        
        .el-button + .el-button{
            margin: 0;
            margin-top: 20px;
        }
    }
}

</style>