<template>
    <a-modal
        class="my-modal"
        ref="modalRef"
        :wrap-style="{ overflow: 'hidden' }"
        @ok="handleOk"
        :mask="mask"
        :width="width"
    >
        <slot />
        <template #title>
            <div ref="modalTitleRef" class="title">
                {{ title }}
            </div>
        </template>
        <template #modalRender="{ originVNode }">
            <div :style="transformStyle">
                <component :is="originVNode" />
            </div>
        </template>
        <template #footer>
            <slot name="footer" />
        </template>
    </a-modal>
</template>
<script lang="ts" setup>
import { ref, computed, CSSProperties, watch, watchEffect } from 'vue';
import { useDraggable } from '@vueuse/core';

const props = defineProps({
    allowDrag: {
        type: Boolean,
        default: true,
    },
    title: {
        type: String,
        default: '弹窗',
    },
    mask: {
        type: Boolean,
        default: true,
    },
    width: {
        type: String || Number,
        default: '520px',
    },
});

const emits = defineEmits(['confirm', 'cancel']);

const modalTitleRef = ref<HTMLElement>();

const { x, y, isDragging } = useDraggable(modalTitleRef);

const handleOk = (e: MouseEvent) => {
    emits('confirm', e);
};

// 拖拽操作
const startX = ref<number>(0);
const startY = ref<number>(0);
const startedDrag = ref(false);
const transformX = ref(0);
const transformY = ref(0);
const preTransformX = ref(0);
const preTransformY = ref(0);
const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 });
watch([x, y], () => {
    if (!startedDrag.value) {
        startX.value = x.value;
        startY.value = y.value;
        const bodyRect = document.body.getBoundingClientRect();
        const titleRect = modalTitleRef.value!.getBoundingClientRect();
        dragRect.value.right = bodyRect.width - titleRect.width;
        dragRect.value.bottom = bodyRect.height - titleRect.height;
        preTransformX.value = transformX.value;
        preTransformY.value = transformY.value;
    }
    startedDrag.value = true;
});
watch(isDragging, () => {
    if (!isDragging) {
        startedDrag.value = false;
    }
});

watchEffect(() => {
    if (startedDrag.value && props.allowDrag) {
        transformX.value =
            preTransformX.value +
            Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) -
            startX.value;
        transformY.value =
            preTransformY.value +
            Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) -
            startY.value;
    }
});
const transformStyle = computed<CSSProperties>(() => {
    return {
        transform: `translate(${transformX.value}px, ${transformY.value}px)`,
    };
});
</script>

<style lang="less">
.my-modal {
    &.ant-modal {
        .ant-modal-content {
          width: 1000px;
            background: url('@/assets/modal/model-bg.png') no-repeat 0 0/100% 100%;
            .ant-modal-close {
                top: 26px;
            }
            .ant-modal-header {
                min-height: 50px;
                background: url('@/assets/modal/header-bg.png') no-repeat 0 0/100% 100%;

                .ant-modal-title {
                    padding-left: 2vmin;
                    .title {
                      color: white;
                        line-height: 34px;
                        width: 100%;
                        cursor: move;
                        font-size: 30px;
                    }
                }
            }
        }
    }
}
</style>
