/*
 * @Author: zhangzc
 * @Email: zhangzc2@guahao.com
 * @Date: 2019-04-25 14:44:40
 * @Last Modified by: qiuwt
 * @Last Modified time: 2020-12-26 15:00:19
 * @Description: 业务弹窗元组件
 */
<template>
    <div class="dialog-wrapper">
        <!--其中的一个dialog-->
        <template v-if="dialogConfig && Array.isArray(dialogConfig.data) && dialogConfig.data.length"
                  v-for="cell in dialogConfig.data">
            <el-dialog :ref="cell.name"
                       :visible.sync="dialogVisible[cell.name]"
                       v-if="visibleObj[cell.name]"
                       @close="() => { handleDialogClose(cell) }"
                       @closed="()=>{ handleDialogClosed(cell) }"
                       v-bind="getMergedObject(cell.extend && cell.extend || cell,dialogExtend)"
                       :class="{'dialog-item': true, 'title-flag': !cell.extend || !cell.extend.title}">
                <!-- dialog顶部自定义插槽 -->
                <bk-slot :config="cell"
                         slot-name="above-dialog" />

                <template v-if="cell && Array.isArray(cell.data) && cell.data.length"
                          v-for="item in cell.data">
                    <!-- 内容是form类型的dialog -->
                    <template v-if="item.type === 'form'">
                        <bk-form :ref="item.name"
                                 :formConfig="item.formConfig"
                                 :dialogConfig="item.dialogConfig || dialogConfig" />
                    </template>
                    <!-- 内容是list类型的dialog -->
                    <template v-if="item.type === 'list'">
                        <bk-list :ref="item.name"
                                 :searchConfig="item.searchConfig"
                                 :tableConfig="item.tableConfig"
                                 :buttonConfig="item.buttonConfig" />
                    </template>
                    <!-- 内容是html类型的dialog -->
                    <template v-if="item.type === 'html'">
                        <div :ref="item.name"
                             v-html="item.html" />
                    </template>
                </template>

                <!-- dialog底部自定义插槽 -->
                <bk-slot :config="cell"
                         slot-name="under-dialog" />

                <!-- 底部按钮(可加入自定义按钮，默认按钮可隐藏) -->
                <div slot="footer"
                     v-if="!(cell.noDefaultButtons && ((Array.isArray(cell.extraButtons) && !cell.extraButtons.length) || !cell.extraButtons))"
                     class="dialog-footer">
                    <template v-if="Array.isArray(cell.extraButtons)"
                              v-for="extraButton in cell.extraButtons">
                        <el-button :key="extraButton.name"
                                   @click="() => handleExtraBtnClick(extraButton, cell)"
                                   :loading="extraButton.loadingStatus"
                                   v-bind="getMergedObject(extraButton.extend, {type:'primary'})">
                            {{ extraButton.label }}
                        </el-button>
                    </template>
                    <template v-if="!cell.noDefaultButtons">
                        <el-button @click="dialogVisible[cell.name] = false">
                            取消
                        </el-button>
                        <el-button :loading="cell.confirmButtonConfig && cell.confirmButtonConfig.loadingSwitch
                            ? submittingObj[cell.name] : false"
                                   @click="() => handleDialogConfirm(cell)"
                                   v-bind="getMergedObject(
                                       cell.confirmButtonConfig && cell.confirmButtonConfig.extend
                                       , {type:'primary'})">
                            {{ cell.confirmButtonConfig && cell.confirmButtonConfig.label ?
                                cell.confirmButtonConfig.label
                                : '确定' }}
                        </el-button>
                    </template>
                </div>
            </el-dialog>
        </template>
    </div>
</template>

<script>
import { getMergedObject } from 'utils/util';

export default {
    name: 'BkDialog',
    props: {
        dialogVisible: {
            required: true,
            type: Object,
            default: () => ({})
        },
        dialogConfig: {
            required: true,
            type: Object,
            default: () => ({})
        },
        initParams: {
            type: Object,
            default: () => ({})
        }
    },
    data() {
        return {
            getMergedObject,
            submittingObj: {}, // 各弹窗的提交按钮状态集合
            visibleObj: {} // 控制弹窗是否销毁
        };
    },
    computed: {
        // 接收一个全局配置
        dialogExtend() {
            const bkConfig = this.$root.bkConfig || this.$bkConfig;
            const config = Object.assign({ appendToBody: true, width: '80%' }, bkConfig.dialogExtend);
            return config;
        },
        // 拷贝dialogVisible参数，解决监听dialogVisible参数，获取改变前后值相同问题
        dialogVisibleNew() {
            return JSON.parse(JSON.stringify(this.dialogVisible));
        }
    },
    watch: {
        dialogVisibleNew: {
            handler(val, oldVal) {
                Object.keys(val).forEach(key => {
                    // 弹窗隐藏或者之前已打开，返回
                    if (val[key]) {
                        this.$set(this.visibleObj, key, true);
                    }
                    if (!val[key] || (oldVal && oldVal[key] === val[key])) return;
                    // 弹窗显示状态切换时，重置确认按钮loading状态
                    this.$set(this.submittingObj, key, false);
                });
            },
            deep: true
        }
    },
    created() {
        const { data } = this.dialogConfig;
        if (Array.isArray(data)) {
            data.forEach(dialog => {
                this.$set(this.submittingObj, dialog.name, false);
                this.$set(this.visibleObj, dialog.name, this.dialogVisible[dialog.name] || false);
            });
        }
    },
    methods: {
        /**
         * 弹窗确认事件
         * @param {Object} dialogConfig 当前弹窗配置
         */
        handleDialogConfirm(dialogConfig) {
            const { confirmButtonConfig, data } = dialogConfig;
            const { callback } = confirmButtonConfig || {};
            if (typeof callback === 'function') {
                callback(this, dialogConfig);
                return;
            }
            // 弹窗内只有一个表单块，提供默认的提交事件
            if (data.length === 1 && data[0].type === 'form') {
                this.$refs[data[0].name][0].handleSubmit(dialogConfig, this);
            }
        },

        /**
         * 弹窗关闭事件
         * @param {Object} dialogConfig 当前弹窗配置
         */
        handleDialogClose(dialogConfig) {
            const {
                onBeforeClose, onAfterClose, confirmButtonConfig, name 
            } = dialogConfig;
            const { loadingSwitch } = confirmButtonConfig || {};
            if (loadingSwitch) this.submittingObj[name] = false;
            // 弹窗关闭前事件
            if (typeof onBeforeClose === 'function') {
                const toContinue = onBeforeClose(this, dialogConfig);
                if (toContinue === false) return;
            }
            
            // 弹窗关闭后事件
            if (typeof onAfterClose === 'function') {
                onAfterClose(this, dialogConfig);
            }
        },
        /**
         * 弹窗关闭动画结束事件
         * @param {Object} dialogConfig 当前弹窗配置
         */
        handleDialogClosed(dialogConfig) {
            const { name } = dialogConfig;
            this.visibleObj[name] = false;
        },

        /**
         * 底部额外的自定义按钮点击事件
         * @param {Object} btn 点击的按钮实例
         * @param {Object} dialogConfig 当前弹窗配置
         */
        handleExtraBtnClick(btn, dialogConfig) {
            if (typeof btn.callback === 'function') {
                btn.callback(this, dialogConfig);
            }
        }
    }
};
</script>
