<script setup lang="ts">
    /**
     * 滑动验证组件
     * 用法：<SlideVerify v-model:show="showSlide" @success="onVerifySuccess" />
     */
    const props = defineProps<{
        show: boolean
    }>()
    const emit = defineEmits<{
        (e: 'update:show', val: boolean): void
        (e: 'success'): void
        (e: 'close'): void
    }>()

    const TRACK_WIDTH = 560  // rpx，滑道宽度（与样式保持一致）
    const BTN_WIDTH = 96    // rpx，滑块宽度

    const maxRpx = TRACK_WIDTH - BTN_WIDTH  // 最大可拖动距离(rpx)

    const state = reactive({
        translateX: 0,   // 当前滑块位移(px，运行时换算)
        isDragging: false,
        startX: 0,
        maxPx: 0,        // 运行时根据屏幕宽度换算
        verified: false,
        text: '按住滑块，拖动到最右侧',
    })

    // 将 rpx 换算为 px
    function rpxToPx(rpx: number): number {
        const screenWidth = uni.getSystemInfoSync().windowWidth
        return (rpx / 750) * screenWidth
    }

    watch(() => props.show, (val) => {
        if (val) {
            reset()
            state.maxPx = rpxToPx(maxRpx)
        }
    })

    function reset() {
        state.translateX = 0
        state.isDragging = false
        state.verified = false
        state.text = '按住滑块，拖动到最右侧'
    }

    function onTouchStart(e: any) {
        if (state.verified) return
        state.isDragging = true
        state.startX = e.touches[0].clientX
    }

    function onTouchMove(e: any) {
        if (!state.isDragging || state.verified) return
        const dx = e.touches[0].clientX - state.startX
        state.translateX = Math.max(0, Math.min(dx, state.maxPx))
    }

    function onTouchEnd() {
        if (!state.isDragging) return
        state.isDragging = false
        // 距终点 10px 以内视为验证通过
        if (state.translateX >= state.maxPx - rpxToPx(10)) {
            state.translateX = state.maxPx
            state.verified = true
            state.text = '验证通过'
            setTimeout(() => {
                emit('success')
                close()
            }, 600)
        } else {
            // 未拖到底，回弹
            state.translateX = 0
        }
    }

    function close() {
        emit('update:show', false)
        emit('close')
        reset()
    }
</script>

<template>
    <view class="sv-mask" v-if="show" @click.self="close">
        <view class="sv-panel">
            <view class="sv-title">安全验证</view>
            <view class="sv-desc">{{ state.text }}</view>

            <!-- 滑道 -->
            <view class="sv-track">
                <!-- 已划过的高亮区 -->
                <view class="sv-fill" :style="{ width: state.translateX + 'px' }" />
                <!-- 滑块 -->
                <view
                    class="sv-btn"
                    :class="{ success: state.verified }"
                    :style="{ transform: `translateX(${state.translateX}px)` }"
                    @touchstart.prevent="onTouchStart"
                    @touchmove.prevent="onTouchMove"
                    @touchend.prevent="onTouchEnd"
                >
                    <text class="sv-arrow" v-if="!state.verified">&#8594;</text>
                    <text class="sv-check" v-else">&#10003;</text>
                </view>
            </view>

            <view class="sv-close" @click="close">
                <text>取消</text>
            </view>
        </view>
    </view>
</template>

<style lang="scss" scoped>
    .sv-mask {
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.45);
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 9999;
    }

    .sv-panel {
        width: 640rpx;
        background: #fff;
        border-radius: 24rpx;
        padding: 48rpx 40rpx 40rpx;
        display: flex;
        flex-direction: column;
        align-items: center;
        box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.16);
    }

    .sv-title {
        font-size: 34rpx;
        font-weight: 700;
        color: #222;
        margin-bottom: 12rpx;
    }

    .sv-desc {
        font-size: 26rpx;
        color: #888;
        margin-bottom: 40rpx;
    }

    .sv-track {
        position: relative;
        width: 560rpx;
        height: 96rpx;
        background: #f0f0f0;
        border-radius: 48rpx;
        overflow: hidden;
    }

    .sv-fill {
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        background: linear-gradient(90deg, #b8e8c0, #5db66f);
        border-radius: 48rpx 0 0 48rpx;
        transition: width 0.05s;
    }

    .sv-btn {
        position: absolute;
        left: 0;
        top: 0;
        width: 96rpx;
        height: 96rpx;
        background: #fff;
        border-radius: 48rpx;
        box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.18);
        display: flex;
        align-items: center;
        justify-content: center;
        transition: background 0.3s;
        z-index: 2;

        &.success {
            background: #5db66f;
        }
    }

    .sv-arrow {
        font-size: 40rpx;
        color: #5db66f;
        font-weight: 700;
    }

    .sv-check {
        font-size: 40rpx;
        color: #fff;
        font-weight: 700;
    }

    .sv-close {
        margin-top: 32rpx;

        text {
            font-size: 28rpx;
            color: #aaa;
        }
    }
</style>
