<template>
    <div class="transferWrap" ref="transferWrap">
        <el-transfer
            :value="selectedKeys"
            v-model="selectedKeys"
            filterable
            :render-content="renderContent"
            :titles="titles"
            :format="format"
            @change="change"
            :data="data"
            :props="props"
            @left-check-change="leftCheckChange"
            @right-check-change="rightCheckChange"
            :filter-method="filterSearch"
            :left-default-checked="leftDefaultCheckedData"
            :right-default-checked="rightDefaultCheckedData"
        >
            <el-pagination layout="prev, pager, next" small slot="left-footer" 
                :total="leftShowDataCount" @current-change="handleLeftPageChange" :current-page.sync="leftCurrentPageData"
            />
            <el-pagination layout="prev, pager, next" small slot="right-footer" 
                :total="rightShowDataCount" @current-change="handleRightPageChange" :current-page.sync="rightCurrentPageData"
            
            />
        </el-transfer>
    </div>
</template>

<script>
// 默认渲染label的方法，如果不是自己想要的，自己传入renderContent参数即可
const renderTransferContent = (h, option) => {
    return <span>{ option.label }</span>;
}

export default {
    name: "Transfer",
    props: {
        // componentRef: {
        //     type: String,
        //     default: 'transferWrap',
        // },
        titles: {
            type: Array,
            default: [],
        },
        // 上方展示样式
        format: {
            type: Object,
            default: () => {
                // 默认为官网给定格式
                return {
                    noChecked: '${total}',
                    hasChecked: '${checked}/${total}'
                }
            }
        },
        // 所有可选数据
        data: {
            type: Array,
            default: [],
        },
        // 已选中的数据
        vModel: {
            type: Array,
            default: [],
        },
        renderContent: {
            type: Function,
            default: renderTransferContent,
        },
        // 数据源的字段别名
        props: {
            type: Object,
        },
        leftCurrentPage: {
            type: Number,
            default: 1,
        },
        rightCurrentPage: {
            type: Number,
            default: 1,
        },
        leftDefaultChecked: {
            type: Array,
            default: () => [],
        },
        rightDefaultChecked: {
            type: Array,
            default: () => [],
        },
    },
    data() {
        const notSelectedData = this.data && this.data.length > 0 ? this.data.filter(item => !this.vModel.includes(item.key)) : [];
        return {
            notSelectedData,
            selectedKeys: this.vModel,
            leftCurrentPageData: this.leftCurrentPage,
            rightCurrentPageData: this.rightCurrentPage,
            leftFirstKey: notSelectedData.length > 0 ? notSelectedData[0].key : 0,
            rightFirstKey: this.vModel && this.vModel.length > 0 ? this.vModel[0] : 0,
            leftShowDataCount: notSelectedData.length,
            rightShowDataCount: this.vModel && this.vModel.length > 0 ? this.vModel.length : 0,
            leftDefaultCheckedData: this.leftDefaultChecked,
            rightDefaultCheckedData: this.rightDefaultChecked,
        };
    },
    methods: {
        // 过滤掉已选择的数据
        filterSelectedData(keys) {
            if(this.data && this.data.length > 0) {
                this.notSelectedData = this.data.filter(item => !keys.includes(item.key));
                this.leftFirstKey = this.notSelectedData.length > 0 ? this.notSelectedData[0].key : 0;
                this.rightFirstKey = this.selectedKeys > 0 ? this.selectedKeys[0] : 0;
                this.rendPageList(this.leftCurrentPageData === 0 ? 1 : this.leftCurrentPageData, "left");
                this.rendPageList(this.rightCurrentPageData === 0 ? 1 : this.rightCurrentPageData, "right");
            }
        },

        /**
         * 
         * @param {*} value 已选中的值[数组]
         * @param {*} direction 移动方向 left，right
         * @param {*} movedKeys 移动的key数组
         */
        change(value, direction, movedKeys) {
            // 判断移动后，左边或者右边的数据数量是否无法支持当前的分页数
            const limit = 10;
            const leftMaxPage = Math.ceil((this.data.length - value.length) / limit);
            const rightMaxPage = Math.ceil(value.length / limit);
            if(this.leftCurrentPageData > leftMaxPage) {
                this.leftCurrentPageData = leftMaxPage;
            }
            if(this.rightCurrentPageData > rightMaxPage) {
                this.rightCurrentPageData = rightMaxPage;
            }

            // 这边修改已选数据并同步到vModel
            // 因为change方法是在修改dom之前触发的，而rendPageList方法是根据dom来决定分页数据是否显示隐藏，故这里延迟触发
            setTimeout(() => {
                this.filterSelectedData(this.selectedKeys);
            }, 10);

            if(this.$listeners['change']) {
                this.$emit('change', value, direction, movedKeys);
            }

            setTimeout(() => {
              this.leftCurrentPageData = this.leftCurrentPageData<=0?1:this.leftCurrentPageData;
              this.rightCurrentPageData = this.rightCurrentPageData<=0?1:this.rightCurrentPageData;
              this.rendPageList(this.leftCurrentPageData, 'left');
              this.rendPageList(this.rightCurrentPageData, 'right');
            }, 50);
        },

        leftCheckChange(keys) {
            if(this.$listeners['left-check-change']) {
                this.$emit('left-check-change', keys);
            }
        },

        rightCheckChange(keys) {
            if(this.$listeners['right-check-change']) {
                this.$emit('right-check-change', keys);
            }
        },

        // 左侧分页参数变化时
        handleLeftPageChange(value) {
            this.rendPageList(value, 'left');
            if(this.$listeners['handlePageChange']) {
                this.$emit('handlePageChange', value, "left");
            }
        },

        // 右侧分页参数变化时
        handleRightPageChange(value) {
            this.rendPageList(value, 'right');
            if(this.$listeners['handlePageChange']) {
                this.$emit('handlePageChange', value, "right");
            }
        },

        /** 搜索框过滤方法 */
        filterSearch(searchValue, data) {
            // 判断data是否是左边或者右边的第一个数据
            if(this.leftFirstKey === data.key) {
                this.leftCurrentPageData = 1; // 默认切换到第一页
                this.$nextTick(()=>{
                    this.rendPageList(1, 'left');
                });
            }
            if(this.rightFirstKey === data.key) {
                this.rightCurrentPageData = 1; // 默认切换到第一页
                this.$nextTick(()=>{
                    this.rendPageList(1, 'right');
                });
            }

            if(searchValue === '') {
                return true;
            }
            return data.label.indexOf(searchValue) >= 0;
        },

        // 重置所有搜索框
        resetAllSearchInput() {
            this.$refs.transferWrap.children[0].__vue__.clearQuery('left');
            this.$refs.transferWrap.children[0].__vue__.clearQuery('right');
        },

        /**
         * 获取列表的数据
         * this.$refs.transferWrap.children[0] 获得.el-transfer的dom元素
         * 结构目录为:
         * .el-transfer // 下标0
         *  .el-transfer-panel  // 下标0 左侧穿梭栏
         *    .el-transfer-panel__body .is-with-footer // 下标为1
         *      .el-checkbox-group .el-transfer-panel__list .is-filterable  // 下标为1
         *        .el-checkbox .el-transfer-panel__item // 每行数据
         *  .el-transfer__buttons  // 下标1 中间的按钮
         *  .el-transfer-panel  // 下标2 右侧穿梭栏
         */
        rendPageList(currentPage, type) {
            const limit = 10;// 分页 写死为10
            let transferPanelItems = this.$refs.transferWrap.children[0].childNodes[0].childNodes[1].childNodes[1].childNodes;
            if(type === 'right') {
                transferPanelItems = this.$refs.transferWrap.children[0].childNodes[2].childNodes[1].childNodes[1].childNodes;
                this.rightShowDataCount = transferPanelItems && transferPanelItems.length > 0 ? transferPanelItems.length : 0;
            } else {
                this.leftShowDataCount = transferPanelItems && transferPanelItems.length > 0 ? transferPanelItems.length : 0;
            }
            if(transferPanelItems && transferPanelItems.length > 0) {
                // 根据当前显示页和类型，决定元素是否显示和隐藏
                for(let i=0; i<transferPanelItems.length; i++) {
                    if(i < currentPage * limit && i >= (currentPage - 1) * limit) {
                        // 说明该元素正好在当前页
                        // if(transferPanelItems[i].className.indexOf('is-checked') > 0) {
                        //     transferPanelItems[i].className = 'el-checkbox el-transfer-panel__item is-checked';
                        // } else {
                        //     transferPanelItems[i].className = 'el-checkbox el-transfer-panel__item';
                        // }
                        // 这里强行提高优先级  一般不建议这么写， 但是为了覆盖公用样式中.el-transfer-panel__item的!important写法，因此这边提高该样式的优先级
                        transferPanelItems[i].style = 'display: block !important';
                    } else {
                        // if(transferPanelItems[i].className.indexOf('is-checked') > 0) {
                        //     transferPanelItems[i].className = 'hidden el-checkbox el-transfer-panel__item is-checked';
                        // } else {
                        //     transferPanelItems[i].className = 'hidden el-checkbox el-transfer-panel__item';
                        // }
                        // 这里强行提高优先级  一般不建议这么写， 但是为了覆盖公用样式中.el-transfer-panel__item的!important写法，因此这边提高该样式的优先级
                        transferPanelItems[i].style = 'display: none !important';
                    }
                }
            }
        }
    },
    watch: {
        // 监听父控件参数的变化
        data: {
            handler() {
                this.filterSelectedData(this.selectedKeys);
            }
        },
        vModel: {
            handler(newVal) {
                this.selectedKeys = newVal;
                this.filterSelectedData(newVal);
            }
        },
        leftCurrentPage(newVal) {
            this.leftCurrentPageData = newVal;
            // this.filterSelectedData(this.selectedKeys);
            this.rendPageList(newVal, "left");
        },
        rightCurrentPage(newVal) {
            this.rightCurrentPageData = newVal;
            // this.filterSelectedData(this.selectedKeys);
            this.rendPageList(newVal, "right");
        },
        leftDefaultChecked(newVal) {
            this.leftDefaultCheckedData = newVal;
        },
        rightDefaultChecked(newVal) {
            this.rightDefaultCheckedData = newVal;
        },
    },
    mounted() {
        this.$nextTick(()=>{
            this.rendPageList(1, "left");
            this.rendPageList(1, "right");
            this.$on('resetAllSearchInput', this.resetAllSearchInput);
        });
    },
}
</script>

<style scoped lang="scss">
.transferWrap {

    ::v-deep .el-transfer {
        text-align: left;
        display: flex;
        align-items: center;
        max-height: 500px;
        height: 100%;

        .el-transfer-panel {
            height: 500px;

            .el-transfer-panel__body {
                overflow: hidden;
                height: 452px;
                .el-transfer-panel__list {
                    height: 350px;
                    overflow: hidden;
                    .el-transfer-panel__item {
                        height: 35px;
                        line-height: 35px;
                        display: block;
                        // border-bottom: 1px solid #e6ebf5;
                    }
                    .el-transfer-panel__item::after {
                        content: '';
                        background-color: #e6ebf5;
                        height: 1px;
                        width: 90%;
                        position: absolute;
                        top: 35px;
                        left: 5%;
                    }
                }
            }
            .el-pagination {
                text-align: right;
                margin: 5px;
            }
        }
    }

    ::v-deep .el-transfer-panel {
        flex: 1;
    }

    ::v-deep .el-transfer__buttons{
      padding: 0;
    }

    ::v-deep .el-transfer__buttons > button {
        display: flex;
        flex: 1;
        margin: 8px;
    }
    ::v-deep .el-transfer__button{
      width: 24px;
      height: 24px;
      padding: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    ::v-deep .el-transfer-panel__filter .el-input__inner{
      border-radius: 2px;
      font-size: 14px;
    }
    ::v-deep .el-pager{
      .active {
        border: 1px solid #1890ff;
        margin-right: 4px;
      }
      .number{
        font-size: 14px;
      }
    }
    ::v-deep .el-checkbox:last-of-type{
      margin-right: 30px;
    }
}

</style>