<template>
    <div
        ref="wrapEl"
        :class="[
            {
                'mc-table__scrollbar__horizontal': type === 'horizontal',
                'mc-table__scrollbar__vertical': type === 'vertical',
            }
        ]"
        @mousedown="mouseDown"
        @mouseup="mouseUp"
        @mousemove="mouseMove"
        :style="{
            width: scrollWidth? scrollWidth + 'px' : '100%',
            height: scrollHeight? scrollHeight + 'px' : '100%',
            transform: `translate(${x}px, ${y}px)`,
            ...horizontalStyle,
            ...verticalStyle,
        }">
        <div
            class="mc-table__scrollbar--thumb"
            :style="{
                width: thumbWidth? thumbWidth + 'px' : '100%',
                height: thumbHeight? thumbHeight + 'px' : '100%',
            }"></div>
    </div>
</template>

<script>
import { ref, onUnmounted, nextTick } from 'vue'

const Props = {
    type: String,
    scrollWidth: Number,
    scrollHeight: Number,
    thumbWidth: {
        type: Number,
        default: 0
    },
    thumbHeight: {
        type: Number,
        default: 0
    },
    x: {
        type: Number,
        default: 0
    },
    y: {
        type: Number,
        default: 0
    },

    // 自定义滚动条样式
    horizontalStyle: {
        type: Object,
        default: () => {}
    },
    verticalStyle: {
        type: Object,
        default: () => {}
    },
}

export default {
    props: Props,
    emits: ['move', 'mouseDragger'],
    setup(props, { emit }) {

        const wrapEl = ref()
        let isDraging = false,
            dragX = 0,
            dragY = 0
        const x = ref(0)
        const y = ref(0)

        const mouseDown = (e) => {
            isDraging = true
            dragX = e.clientX - props.x
            dragY = e.clientY - props.y
            emit('mouseDragger', true)
        }

        const mouseMove = (e) => {
            if(isDraging){
                if(props.type === 'horizontal'){
                    let m = e.clientX - dragX
                    m = Math.max(m, 0)
                    m = Math.min(m, (wrapEl.value?.offsetWidth || 0) - props.thumbWidth)
                    x.value = m
                    emit('move', {
                        type: props.type,
                        x: m,
                    })
                }
                if(props.type === 'vertical'){
                    let m = e.clientY - dragY
                    m = Math.max(m, 0)
                    m = Math.min(m, (wrapEl.value?.offsetHeight || 0) - props.thumbHeight)
                    y.value = m
                    emit('move', {
                        type: props.type,
                        y: m,
                    })
                }
            }
        }

        const blockMouseEvent = () => {
            if(isDraging){
                isDraging = false
                dragX = 0
                dragY = 0
                emit('mouseDragger', false)
            }
        }

        /* 监听鼠标点击抬起 取消移动监听 */
        const mouseUp = (e) => blockMouseEvent()

        nextTick(() => {
            window.addEventListener('mouseup', blockMouseEvent)
            window.addEventListener('mousemove', mouseMove)
        })

        onUnmounted(() => {
            window.removeEventListener('mouseup', blockMouseEvent)
            window.removeEventListener('mousemove', mouseMove)
        })

        return {
            wrapEl,
            mouseUp,
            mouseDown,
            mouseMove,
        }
    }
}
</script>

