<template>
    <transition
        :name="transitionName"
        @after-leave="afterLeave"
        v-on="transitionOn"
        :duration="transitionDuration">
        <div
            ref="wrapper"
            :class="bem('wrapper', {centered})"
            v-if="mounted && visible"
            :style="{zIndex: zIndex, position: appendBody ? 'fixed' : 'absolute'}"
            @click="close">
            <div :class="bem([theme])" :style="{width, top: centered ? '0' : top, bottom}">
                <div :class="bem('header')">
                    <!-- 头部 会覆盖 title -->
                    <slot name="header" >
                        <span :class="bem('title')" v-if="title">{{title}}</span>
                    </slot>
                    <icon
                        name="close"
                        v-if="showClose && !closeText && !showNewClose"
                        color="#AAA"
                        :class="bem('close')"
                        @click.native="onClickOverlay(false)"
                    />
                    <span
                        :class="bem('close')"
                        v-if="showClose && closeText && !showNewClose"
                        @click="onClickOverlay(false)"
                    >{{ closeText }}</span>
                    <i
                        v-if="showClose && !closeText && showNewClose"
                        :class="bem('close', 'new')"
                        @click="onClickOverlay(false)"/>
                </div>
                <div :class="bem('body')">
                    <!-- modal内容 -->
                    <slot/>
                </div>
                <div :class="bem('footer')" v-if="hasFooter">
                    <!-- 底部 -->
                    <slot name="footer">
                        <div :class="bem('buttons')">
                            <gd-button rect type="primary" v-if="okText" @click="confirm">
                                {{okText}}
                            </gd-button>
                            <gd-button rect @click="cancel" v-if="cancelText">
                                {{cancelText}}
                            </gd-button>
                        </div>
                    </slot>
                </div>
            </div>
        </div>
    </transition>
</template>
<script>
import { createComponentName, componentMixin } from '../_utils/component';
import Icon from '../Icon';
import popupManager from '../_utils/popup-manager';

export default {
    name: createComponentName('modal'),
    components: {
        Icon,
    },
    mixins: [componentMixin],
    props: {
        // 是否可见
        visible: {
            type: Boolean,
            default: false,
        },
        // 显示遮罩层
        mask: {
            type: Boolean,
            default: true,
        },
        transitionName: {
            type: String,
            default: 'gd-modal-fade',
        },
        transitionOn: {
            type: Object,
        },
        transitionDuration: {
            type: Object,
        },
        // 是否支持键盘esc关闭
        keyborad: {
            type: Boolean,
            default: true,
        },
        // 标题
        title: {
            type: String,
        },
        appendBody: {
            type: Boolean,
            default: true,
        },
        // modal 宽度
        width: {
            type: String,
            default: '350px',
        },
        top: {
            type: String,
            default: '15%',
        },
        theme: {
            type: String,
            default: 'light', // light or dark
        },
        bottom: {
            type: String,
            default: 'auto',
        },
        // 显示关闭按钮
        showClose: {
            type: Boolean,
            default: true,
        },
        // 显示新的关闭按钮
        showNewClose: {
            type: Boolean,
            default: false,
        },
        // 自定义关闭按钮文笔
        closeText: {
            type: String,
        },
        // 确认按钮文字
        okText: {
            type: String,
        },
        // 取消按钮文字
        cancelText: {
            type: String,
        },
        // 点击遮罩层是否允许关闭
        maskClosable: {
            type: Boolean,
            default: true,
        },
        onCancel: {
            type: Function,
        },
        afterClose: {
            type: Function,
        },
        // 居中
        centered: {
            type: Boolean,
            default: false,
        },
        onOk: {
            type: Function,
        }
    },
    data() {
        return {
            zIndex: popupManager.getZindex(),
            mounted: false,
        };
    },
    computed: {
        dialogStyle() {
            return {
                marginTop: this.top,
                width: this.width,
            };
        },
        hasFooter() {
            return this.okText || this.noText || this.$slots.footer;
        },
    },
    watch: {
        visible(value) {
            if (value) {
                popupManager.pushStack(this);
            }
            else if (!value) {
                popupManager.popStack(this);
            }
        },
    },
    mounted() {
        this.mounted = true;

        if (this.isSSR()) return;
        if (this.visible) popupManager.pushStack(this);
    },
    beforeDestroy() {
        if (this.appendBody && this.$el.parentElement) {
            this.$el.parentElement.removeChild(this.$el);
        }
        popupManager.popStack(this);
    },
    methods: {
        close(e) {
            if (this.maskClosable && e.target === this.$refs.wrapper) {
                this.cancel();
            }
        },
        async confirm() {
            this.$emit('update:visible', false);
            if (this.onOk) await this.onOk();
        },
        async cancel() {
            // visible.sync
            this.$emit('update:visible', false);
            if (this.onCancel) await this.onCancel();
        },
        onClickOverlay() {
            if (this.showClose) {
                this.cancel();
            }
        },
        afterLeave() {
            if (this.afterClose) this.afterClose();
        }
    },
};
</script>

<style lang="less">
@import '../_styles/base.less';

@b: ~'@{prefix}-modal';

.@{b}__wrapper {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    color: #606266;
    .scrollbar();

    &--overlay {
        background: hsla(0,0%,100%,.8);
    }

    &--centered {
        text-align: center;
        &::before {
            content: '';
            display: inline-block;
            height: 100%;
            vertical-align: middle;
            width: 0;
        }

        .@{b} {
            text-align: left;
            vertical-align: middle;
            display: inline-block;
        }
    }
}

.@{b} {
    margin: 0 auto;
    position: relative;
    outline: 0;

    background: #fff;
    box-shadow: 0 2px 8px rgba(160, 160, 180, 0.4);
    box-sizing: border-box;
    padding: 40px 40px 0px 40px;

    &--dark {
        background: #000;
        color: #fff;
    }

    &__header {
        display: flex;
        align-items: center;
        justify-content: space-between;
    }

    &__title {
        font-size: 22px;
        color: #333;
        font-weight: bold;
    }

    &__close {
        cursor: pointer;
        position: absolute;
        right: 20px;
        top: 20px;
        opacity: 0.6;
        font-size: 16px;
        color: #AAA;

        &:hover {
            opacity: 1;
        }
    }

    &__close--new {
        width: 1.2em;
        height: 1.2em;
        background: svg-load('../../assets/icons/close-new.svg', fill=#999);
        background-size: contain;
    }

    &__footer {
        padding: 0 0 40px 0;
    }
    &__body {
        margin: 16px 0;
        /*
        font: 14px/1.5 -apple-system,BlinkMacSystemFont,Segoe UI,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
        */
    }

    &__buttons {
        display: flex;
        flex-flow: row-reverse;
    }
}

.gd-modal-fade-enter-active {
    animation: gd-modal-fade-in 0.3s;
}

.gd-modal-fade-leave-active {
    animation: gd-modal-fade-out 0.3s;
}

@keyframes gd-modal-fade-in {
    0% {
        transform: translate3d(0, -40px, 0);
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

@keyframes gd-modal-fade-out {
    0% {
        opacity: 1;
    }
    100% {
        transform: translate3d(0, -20px, 0);
        opacity: 0;
    }
}
</style>
