<template>
    <view class="contract-sign" :class="btnClass">
        <canvas
            class="canvas"
            canvas-id="canvas"
            @touchstart="touchStart"
            @touchmove="touchMove"
            @touchend="touchEnd"
            :style="{ width: canvasWidth + 'rpx', height: canvasHeight + 'rpx' }"
        />
        <view class="btns flex flex_align justify_b">
            <view class="repair-btn" @click="handleClearCanvas">重新签名</view>
            <view class="finish-btn" @click="handleConfirmSign">完成签名</view>
        </view>
    </view>
</template>

<script setup lang="ts">
import { onLoad } from '@dcloudio/uni-app'
import { computed, getCurrentInstance, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useAppStore } from '@/stores/app'

const props = defineProps({
    orientation: {
        type: String,
        default: 'portrait'
    },
    lineWidth: {
        type: Number,
        default: 3
    },
    strokeStyle: {
        type: String,
        default: 'black'
    },
    width: {
        type: Number,
        default: 0
    },
    height: {
        type: Number,
        default: 0
    }
})

interface IPoint {
    X: number
    Y: number
}
const instance = getCurrentInstance()

const appStore = useAppStore()
const { sysInfo } = storeToRefs(appStore)
const windowWidth = computed(() => sysInfo.value.windowWidth)
const windowHeight = computed(() => sysInfo.value.windowHeight)

const context = ref()
const points = ref<IPoint[]>([])
const canvasWidth = ref(0)
const canvasHeight = ref(0)

const btnClass = computed(() => {
    const classes = []
    const { orientation } = props
    classes.push(`contract-sign--${orientation}`)
    return classes.join(' ')
})
const touchStart = e => {
    const startX = e.touches[0].x
    const startY = e.touches[0].y
    points.value.push({ X: startX, Y: startY })
    context.value.beginPath()
}
const touchMove = e => {
    const moveX = e.touches[0].x
    const moveY = e.touches[0].y
    points.value.push({ X: moveX, Y: moveY })
    if (points.value.length >= 2) {
        draw()
    }
}
const touchEnd = () => {
    points.value = []
}

const createCanvas = () => {
    const { lineWidth, strokeStyle } = props
    const ctx = uni.createCanvasContext('canvas', this)
    ctx.lineCap = 'round'
    ctx.lineJoin = 'round'
    ctx.lineWidth = lineWidth
    ctx.strokeStyle = strokeStyle
    context.value = ctx
}
/* ***********************************************
	绘制笔迹
	1.为保证笔迹实时显示，必须在移动的同时绘制笔迹
	2.为保证笔迹连续，每次从路径集合中区两个点作为起点（moveTo）和终点(lineTo)
	3.将上一次的终点作为下一次绘制的起点（即清除第一个点）
************************************************ */
const draw = () => {
    const point1 = points.value[0]
    const point2 = points.value[1]
    points.value.shift()
    context.value.moveTo(point1.X, point1.Y)
    context.value.lineTo(point2.X, point2.Y)
    context.value.stroke()
    context.value.draw(true)
}
// 重新签名
const handleClearCanvas = () => {
    context.value.clearRect(0, 0, canvasWidth.value, canvasHeight.value)
    context.value.draw(true)
}
// 完成签名
const handleConfirmSign = () => {
    uni.canvasToTempFilePath({
        canvasId: 'canvas',
        success: res => {
            const path = res.tempFilePath
            console.log(path)
            uni.redirectTo({
                url: `/bundle/pages/contract/contract-preview/index?type=sign&path=${path}`
            })
        }
    })
}
// 设置画布大小
const setCanvasSize = async () => {
    const rect = await getRect()
    const { orientation, width, height } = props
    if (orientation === 'portrait') {
        // 纵向
        canvasWidth.value = width > windowWidth.value || width === 0 ? windowWidth.value * 2 : width
        canvasHeight.value =
            height > windowWidth.value || height === 0
                ? (windowHeight.value - rect.height) * 2
                : height
    } else if (orientation === 'abeam') {
        // 横向
        canvasWidth.value =
            width > windowWidth.value || width === 0 ? (windowWidth.value - rect.height) * 2 : width
        canvasHeight.value =
            height > windowWidth.value || height === 0 ? windowHeight.value * 2 : height
    }
}

// 获取底部按钮信息
const getRect = () => {
    return new Promise(resolve => {
        const query = uni.createSelectorQuery().in(instance)
        query
            .select('.btns')
            .boundingClientRect(data => {
                return resolve(data)
            })
            .exec()
    })
}
onLoad(() => {
    setCanvasSize()
    createCanvas()
})
</script>

<style lang="scss" scoped>
.contract-sign {
    width: 100vw;
    height: 100vh;
    display: flex;
    &--portrait {
        flex-direction: column;
    }
    &--abeam {
        flex-direction: row-reverse;
        overflow-y: hidden;

        .btns {
            width: 70px;
            height: 100%;
            .repair-btn {
                width: 42vh;
                transform: rotate(90deg);
                margin-left: -19.5vh;
                margin-top: 21vh;
                height: 80rpx;
                line-height: 80rpx;
                text-align: center;
                position: fixed;
                left: 25px;
            }
            .finish-btn {
                position: absolute;
                z-index: 999;
                display: inline-flex;
                margin-top: 67vh;
                margin-left: -19.5vh;
                transform: rotate(90deg);
                width: 42vh;
                left: 25px;
                height: 80rpx;
                line-height: 80rpx;
                text-align: center;
                justify-content: center;
            }
        }
    }

    .canvas {
        width: 100%;
        flex: 1;
        background-color: $white-1;
    }
    .btns {
        @include flex-align;
        padding: 0 32rpx;
        height: 120rpx;
        gap: 20rpx;
        background: $gray-5;
        > view {
            flex: 1;
            @include flex-center;
            height: 80rpx;
            border-radius: 8rpx;
            font-size: 30rpx;
            &.repair-btn {
                background-color: $white-1;
                color: $blue-1;
            }
            &.finish-btn {
                background-color: $blue-1;
                color: $white-1;
            }
        }
    }
}
</style>
