<script>
/**
 * vs-dialog 2022-05-26
 *
 * 宽度，高度，偏移量必须带单位，px/vh/vw等
 * 
 * left 左侧偏移量 ''
 * right 右侧偏移量 '' 如果设置left则该属性不生效
 * top 顶部偏移量 100px
 * isCenter 是否水平居中  如果设置left或right则该属性不生效
 * width 弹窗宽度 360px
 * height 弹窗高度 550px
 * header 弹窗头部高度 50px
 * title 弹窗标题内容 vs-dialog
 * showTitle 是否显示标题 true
 * bg 弹窗背景图片
 * closeMode 关闭弹窗的方式 if 销毁dom show 隐藏dom
 *
 * isMini 是否显示最小化按钮 true
 * isFullScreen 是否显示最大化按钮 true
 * isClose 是否显示关闭按钮 true
 * isDrag 是否允许拖动 true
 *
 * @mini 最小化点击回调
 * @fullScreen 最大化点击回调
 * @close 关闭点击回调
 * @back 点击还原回调
 * @dragstop 拖拽结束回调
 */
export default {
    name: "vs-dialog",
};
</script>
<script setup>
import {
    ref,
    toRef,
    reactive,
    getCurrentInstance,
    onBeforeMount,
    onMounted,
    onBeforeUnmount,
    nextTick,
    watch
} from "vue";
const props = defineProps({
    left: {
        type: String,
        default: '',
    },
    right: {
        type: String,
        default: '',
    },
    isCenter: {
        type: Boolean,
        default: false,
    },
    top: {
        type: String,
        default: '100px',
    },
    width: {
        type: String,
        default: "360px",
    },
    height: {
        type: String,
        default: "550px",
    },
    header: {
        type: String,
        default: "50px",
    },
    title: {
        type: String,
        default: "vs-dialog",
    },
    showTitle: {
        type: Boolean,
        default: true,
    },
    bg: {
        type: String,
        default: "",
    },
    isMini: {
        type: Boolean,
        default: true,
    },
    isFullScreen: {
        type: Boolean,
        default: true,
    },
    isClose: {
        type: Boolean,
        default: true,
    },
    isDrag: {
        type: Boolean,
        default: true,
    },
    closeMode: {
        type: String,
        default: 'if',
    },

    mountDom: {
        type: Object,
        default: () => { },
    }
});

//弹窗背景图
const dialogProps = reactive({
    isMini: props.isMini,
    isFullScreen: props.isFullScreen,
    isClose: props.isClose,
    showTitle: props.showTitle,
    width: props.width,
    height: props.height,
    left: props.left,
    right: props.right,
    top: props.top,
    isDrag: props.isDrag,
});

const styleToolbar = reactive({
    paddingTop: (parseInt(props.header) - 22) / 2 + "px",
});


const style = reactive({
    width: dialogProps.width,
    height: dialogProps.height,
    left: dialogProps.left,
    top: dialogProps.top
});
const styleheader = reactive({
    height: props.header,
    lineHeight: props.header,
    cursor: props.isDrag ? 'move' : 'default'
});

const stylecon = reactive({
    height: `calc(100% - ${props.header})`,
});

onBeforeMount(() => {
    if (props.left === '' && props.right !== '') {
        const _w = document.body.clientWidth;
        style.left = _w - parseInt(dialogProps.width) - parseInt(props.right) + 'px';
        window.addEventListener("resize", () => {
            const _w = document.body.clientWidth;
            style.left = _w - parseInt(dialogProps.width) - parseInt(props.right) + 'px';
        });
    }

    if (props.left === '' && props.right === '' && props.isCenter) {
        const _w = document.body.clientWidth;
        style.left = (_w - parseInt(dialogProps.width)) / 2 + 'px';


        posi.left = style.left;

        window.addEventListener("resize", () => {
            const _w = document.body.clientWidth;
            style.left = (_w - parseInt(dialogProps.width)) / 2 + 'px';
            posi.left = style.left;
        });
    }


    if (props.bg) {
        style.background = `url(${props.bg}) no-repeat`;
        style.backgroundSize = "100% 100%";
        styleheader.background = "unset";
    }
    if (props.header === "0px") {
        props.isMini = false;
        props.isFullScreen = false;
        props.isClose = false;
        props.showTitle = false;
    }
});

const emit = defineEmits(["mini", "fullScreen", "close", "back", "dragstop"]);

const posi = reactive({
    left: props.left,
    top: props.top,
});

//最小化方法
const ismini = ref("mini");
const miniClickHandle = () => {
    if (ismini.value === "mini") {
        const { left, top } = posi;
        ismini.value = "miniback";

        if (style.width === '100vw' && style.height === '100vh') {
            style.left = '0px';
            style.top = '0px';
        } else {
            style.left = left;
            style.top = top;
        }
        style.height = props.header;
        emit("mini");
    } else if (ismini.value === "miniback") {
        backClickHandle();
    }
};

//最大化方法
const isfull = ref("full");
const fullScreenClickHandle = () => {
    if (isfull.value === "full") {
        ismini.value = "mini";
        isfull.value = "fullback";
        style.width = "100vw";
        style.height = "100vh";
        style.left = '0px';
        style.top = '0px';
        emit("fullScreen");
    } else if (isfull.value === "fullback") {
        backClickHandle();
    }
};

//还原弹窗方法
const backClickHandle = () => {
    const { left, top } = posi
    ismini.value = "mini";
    isfull.value = "full";
    style.width = props.width;
    style.height = props.height;
    style.left = left;
    style.top = top;
    emit("back");
};

//关闭弹窗方法
const dialogshow = ref(true);
const closeClickHandle = () => {

    //如果是通过方法打开弹窗
    // if (props.mountDom) {
    //   document.body.removeChild(props.mountDom);
    //   return
    // }

    dialogshow.value = false;
    emit("close");
};

const dialogRef = ref(null);

const drapStop = function (e) {

    if (isfull.value === "fullback") return;

    const { offsetLeft, offsetTop } = dialogRef.value;
    style.left = posi.left = offsetLeft + 'px';
    style.top = posi.top = offsetTop + 'px';
    emit('dragstop', offsetLeft, offsetTop, e)
}

</script>

<template>
    <div v-drag="{ dom: '.vs-dialog--header', drapStop, enable: props.isDrag }" ref="dialogRef" :style="style"
        class="vs-dialog" v-on:[props.closeMode]="dialogshow">
        <div v-if="dialogProps.showTitle" :style="styleheader" class="vs-dialog--header">
            <div class="title">
                <span>{{ props.title }}</span>
            </div>
            <div class="toolbar" :style="styleToolbar">
                <i v-if="dialogProps.isMini" @click="miniClickHandle" :class="ismini"></i>
                <i v-if="dialogProps.isFullScreen" @click="fullScreenClickHandle" :class="isfull"></i>
                <i v-if="dialogProps.isClose" @click="closeClickHandle" class="close"></i>
            </div>
        </div>
        <div :style="stylecon" class="vs-dialog--content">
            <div class="vs-dialog--content--scorll">
                <slot />
            </div>
        </div>
    </div>
</template>

<style  lang="scss" scope>
$main: var(--main);
$auxiliary: var(--auxiliary);

.vdr-container {
    border: none !important;
}

.vs-dialog {
    background: $auxiliary;
    border-radius: 5px;
    color: #fff;
    position: absolute;
    z-index: 999;

    .vs-dialog--header {
        width: 100%;
        background: $main;
        border-top-left-radius: 5px;
        border-top-right-radius: 5px;
        display: flex;
        justify-content: space-around;

        .title {
            width: 100%;
            text-indent: 20px;
            overflow: hidden;
            /*超出部分隐藏*/
            white-space: nowrap;
            /*不换行*/
            text-overflow: ellipsis;
            /*超出部分文字以...显示*/
        }

        .toolbar {
            display: flex;
            justify-content: space-around;
            margin-right: 10px;

            .mini {
                background-image: url("../icon/mini.png");
            }

            .miniback {
                background-image: url("../icon/miniback.png");
            }

            .full {
                background-image: url("../icon/fullscreen.png");
            }

            .fullback {
                background-image: url("../icon/fullback.png");
            }

            .close {
                background-image: url("../icon/close.png");
            }

            i {
                width: 21px;
                height: 21px;
                background-size: 100% 100%;
                background-repeat: no-repeat;
                cursor: pointer;
                margin: 0px 3px;
            }
        }
    }

    .vs-dialog--content {
        width: 99%;
        padding: 10px 5px 10px 10px;
        box-sizing: border-box;

        .vs-dialog--content--scorll {
            height: 100%;
            padding-right: 5px;
            overflow-y: auto;
            overflow-x: hidden;
        }

        .vs-dialog--content--scorll::-webkit-scrollbar {
            width: 5px;
            height: 1px;
        }

        .vs-dialog--content--scorll::-webkit-scrollbar-thumb {
            border-radius: 10px;
            background: $main;
        }
    }
}

.vs-dialog-unDrag {
    position: absolute;
}
</style>
