<template>
	<view class="signature">
		<cover-view class="operate-btns">
			<!-- <cover-view class="t-icon t-icon-palette" @click="onVisiblePalette" />	 -->
			<!-- <view class="t-icon t-icon-brush" @click="onVisibleBrush" /> -->
			<cover-view @click="onReset" class="resetBtn btnItem">重绘</cover-view>
			<cover-view @click="onRollback" class="backBtn btnItem">撤消</cover-view>
			<cover-view @click="onCancel" class="cancelBtn btnItem">取消</cover-view>
			<cover-view @click="onSave" class="saveBtn btnItem">确定</cover-view>
		</cover-view>
		
		<!-- #ifndef MP -->
		<cover-view class="signature-content">
			<cover-view class="customMask flex_center">
				<cover-view class="tip-content font_bolder">
					<cover-view class="tip-title">签名区</cover-view>
					<cover-view class="tip-desc">示例: 张XX</cover-view>
				</cover-view>
			</cover-view>
			<canvas style="width: 100%;height:100%" :id="canvasName" :canvas-id="canvasName" :disable-scroll="true"
				@touchstart="onTouchStart" @touchmove="onTouchmove" @touchend="onTouchEnd">
			</canvas>
		</cover-view>
		<!-- #endif -->

		<!-- #ifdef MP -->
		<canvas class="signature-content" :id="canvasName" :canvas-id="canvasName" :disable-scroll="true"
			@touchstart="onTouchStart" @touchmove="onTouchmove" @touchend="onTouchEnd">
		</canvas>
		<!-- #endif -->
		
		<!-- 调色板 -->
		<cover-view class="palette-container" :style="{display: showPalette ? 'block' : 'none'}">
			<cover-view class="palette-block-list flex_sb">
				<cover-view class="palette-block-item" :style="{'background-color': item}"
					v-for="(item,index) in colorBlocks" :key="index" @click="onChangeColor" :data-color="item" />
			</cover-view>
		</cover-view>
		<!-- 画笔选择 -->
		<cover-view class="atom-container-brush flex_cen" :style="{display: showBrush ? 'flex' : 'none'}">
			<cover-view class="slender brush-item flex_cen" @click="onChangeBrush" data-width="3">细</cover-view>
			<cover-view class="medium brush-item flex_cen" @click="onChangeBrush" data-width="5">适中</cover-view>
			<cover-view class="bolder brush-item flex_cen" @click="onChangeBrush" data-width="6">粗</cover-view>
		</cover-view>
		<!-- 签名预览 -->
		<cover-view class="preview-mask" v-if="visible">
			<cover-view class="preview-sign">
				<cover-view class="previewTitle">签名预览</cover-view>
				<cover-image mode="aspectFill" :src="imgUrl" style="width: 100%; height: 100%" />
				<cover-view @click.stop.prevent="onRedraw" class="preview-redraw">重签</cover-view>
				<cover-view @click.stop.prevent="onSubmit" class="preview-submit">提交</cover-view>
			</cover-view>
		</cover-view>
	</view>
</template>

<script>
	import { signFor, uploadImg } from '../../api/apiList'
	import { pathToBase64, base64ToPath } from 'image-tools'
	import { formatTime, formatGMT } from '../../utils/util.js'

	let tempPath = []; //存储临时笔迹 ,避免频繁setData导致卡顿
	let previewImgPath = [] //保存当前画布步骤，用于撤消、还原画布
	let ctx = null //Canvas 的绘图上下文

	export default {
		options: { styleIsolation: 'shared' },
		data() {
			return {
				shipmentMode: 'OM', //运输模式
				orderList: [], //订单列表
				selectedId: '', //shipmentLocationId
				shipmentId: '', //运单id
				locationInfo: '', //当前位置信息
				imgUrl: "", //图片地址
				imgBase64: "", //base64图
				visible: false, //预览图显隐

				watermark: formatGMT(formatTime(new Date()), 'D'), //水印文本,默认为当前日期
				canvasName: 'myCanvas', // 画布Name&&ID,当指定画布Type=2d时,小程序将异常
				canvasBg: '#F7FBFF', // 画布背景
				canvasWidth: "", //画布宽
				canvasHeight: "", //画布高
				lineColor: '#000000', // 默认画笔颜色
				lineSize: 3, // 画笔粗细

				// startX: null,
				// startY: null,
				paths: [], // 路径二维数组		
				colorBlocks: ['#FF0000', '#FFA000', '#FFEB3B', '#00BCD4', '#2196F3', '#9E9E9E', '#000000'], //颜色列表
				showPalette: false, //是否显示调色板
				showBrush: false, //是否显示线条选择				
			};
		},
		onLoad(options) {
			this.initCanvas()
			const { orderList, selectedId, shipmentMode, locationInfo, shipmentId } = JSON.parse(options.data)
			this.shipmentMode = shipmentMode
			this.orderList = orderList
			this.selectedId = selectedId
			this.locationInfo = locationInfo
			this.shipmentId = shipmentId
		},
		methods: {
			initCanvas() {
				ctx = uni.createCanvasContext(this.canvasName, this); //创建画布绘图上下文
				this.$nextTick(() => {
					uni.createSelectorQuery().select('.signature-content').boundingClientRect(node => {
						this.canvasWidth = node.width;
						this.canvasHeight = node.height;
						this.setCanvasBg();
					}).exec();
				});
			},
			//设置canvas背景色  不设置则导出的canvas的背景为透明
			setCanvasBg() {
				const { canvasBg, canvasWidth, canvasHeight } = this
				ctx.setFillStyle(canvasBg);
				ctx.fillRect(0, 0, canvasWidth, canvasHeight);
				ctx.draw();
			},

			// 调色板显隐
			onVisiblePalette() {
				this.showBrush = false
				this.showPalette = !this.showPalette
			},
			//画笔粗细显隐
			onVisibleBrush() {
				this.showPalette = false
				this.showBrush = !this.showBrush
			},
			//颜色选择
			onChangeColor(e) {
				let color = e.currentTarget.dataset.color;
				ctx.setStrokeStyle(color)
				this.lineColor = color
				this.showPalette = false
			},
			//画笔选择
			onChangeBrush(e) {
				let strokeWidth = e.currentTarget.dataset.width;
				ctx.setLineWidth(strokeWidth)
				this.lineSize = strokeWidth
				this.showBrush = false
			},
			// 是否暂停
			isPaused() {
				const flag = this.showBrush || this.showPalette;
				if (flag) {
					console.log('绘画处于暂停状态')
				}
				return flag
			},

			//签名开始
			onTouchStart(e) {
				if (this.isPaused()) return
				let point = {
					x: e.touches[0].x,
					y: e.touches[0].y
				};
				tempPath = [point];

				// this.startX = e.changedTouches[0].x
				// this.startY = e.changedTouches[0].y
				//设置画笔参数
				ctx.setStrokeStyle(this.lineColor) //画笔颜色
				ctx.setLineWidth(this.lineSize) //设置线条粗细
				ctx.setLineCap("round") //设置线条的结束端点样式: 'butt'、'round'、'square'
				ctx.setLineJoin('round')
				ctx.beginPath() //开始画笔
			},
			//签名绘制中
			onTouchmove(e) {
				if (this.isPaused()) return
				let point = {
					x: e.touches[0].x,
					y: e.touches[0].y
				};
				tempPath.push(point)
				ctx.moveTo(tempPath[tempPath.length - 2].x, tempPath[tempPath.length - 2].y)
				ctx.lineTo(point.x, point.y)
				ctx.stroke()
				ctx.draw(true)

				// //取点
				// let temX = e.changedTouches[0].x
				// let temY = e.changedTouches[0].y
				// //画线条
				// ctx.moveTo(this.startX, this.startY)
				// ctx.lineTo(temX, temY)
				// ctx.stroke()
				// ctx.draw(true)
				// this.startX = temX
				// this.startY = temY
			},
			//签名绘制结束
			async onTouchEnd() {
				if (this.isPaused()) return
				this.paths = [...tempPath]
				tempPath = [];
				const imgUrl = await this.canvasToImg()
				previewImgPath.push(imgUrl)
			},

			// 撤消
			onRollback() {
				let { paths, canvasWidth, canvasHeight } = this
				if (!previewImgPath.length) return
				previewImgPath.pop()
				paths.pop()
				this.paths = paths
				const path = previewImgPath[previewImgPath.length - 1]
				if (path) {
					ctx.drawImage(path, 0, 0, canvasWidth, canvasHeight) //todo 新旧版本参数不同
					ctx.draw()
				} else {
					this.resetCanvas()
				}
			},
			//清除画布
			onReset() {
				this.imgUrl = ""
				this.paths = []
				previewImgPath = []
				this.resetCanvas()
			},
			// 重置画布
			resetCanvas() {
				ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
				this.setCanvasBg();
			},

			// 返回上一页
			onCancel() {
				uni.navigateBack()
			},

			//预览图显隐
			onVisible() {
				this.visible = !this.visible
			},
			//重签
			onRedraw() {
				this.onReset()
				this.onVisible()
			},
			//提交签名
			onSubmit() {
				this.convertReqData()
			},

			//生成水印
			onMakeWatermark() {
				const rotateAngle = 90 * Math.PI / 180; //设置画布旋转角度，并将角度转为弧度
				ctx.font = `${24}px normal` //文本大小
				ctx.fillStyle = "#000000" //文本颜色
				ctx.save(); //保存当前画布状态
				ctx.translate(this.canvasHeight / 2, this.canvasWidth / 2); //旋转前调整画布中心点
				ctx.rotate(rotateAngle); //旋转
				ctx.fillText(this.watermark, this.canvasHeight / 2 - 50, -26); //设置文本位置并绘制
				ctx.restore(); //恢复之前画布状态
				ctx.draw(true)
			},

            //旋转签名, 传入需要旋转的base64图片
            rotateImg (data){
               return new Promise((resolve, reject) => {
                 const imgView = new Image();
                 imgView.src = data;
                 const canvas = document.createElement('canvas');
                 const context = canvas.getContext('2d');
                 const cutCoor = {sx: 0, sy: 0, ex: 0, ey: 0}; // 裁剪坐标
                 imgView.onload = () => {
                   const imgW = imgView.width;
                   const imgH = imgView.height;
                   const size = imgH;
                   canvas.width = size * 2;
                   canvas.height = size * 2;
                   cutCoor.sx = size;
                   cutCoor.sy = size - imgW;
                   cutCoor.ex = size + imgH;
                   cutCoor.ey = size + imgW;
                   context.translate(size, size);
                   context.rotate(Math.PI/2*3);
                   context.drawImage(imgView, 0, 0);
                   const imgData = context.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
                   canvas.width = imgH;
                   canvas.height = imgW;
                   context.putImageData(imgData, 0, 0);
                   resolve(canvas.toDataURL('image/png'));
                 };				 			 				
               });
            },
			
			//保存签名
			async onSave() {
				this.onMakeWatermark() //生成预览图时添加时间水印
				const imgUrl = await this.canvasToImg()
				// #ifdef MP
				this.imgUrl = imgUrl
				this.onVisible()
				// #endif
				
				// #ifdef H5	
				const rotImg = await this.rotateImg(imgUrl)
				// const tempath = await base64ToPath(rotImg) //base64 转本地路径(本地流)								
				this.imgBase64 = rotImg //上传图片：旋转后
				this.imgUrl = imgUrl //预览图片：旋转前
				this.onVisible()			
				// #endif
			},
			//画布转存为图片
			canvasToImg() {
				return new Promise((reslove, reject) => {
					uni.canvasToTempFilePath({
						canvasId: this.canvasName,
						fileType: 'png', //目标文件类型，默认为png
						quality: 1.0, //图片的质量
						success(res) {
							reslove(res.tempFilePath) //TODO H5平台下，tempFilePath 为 base64
						},
						fail(err) {
							uni.showModal({
								title: '保存失败！',
								content: err.errMsg,
								showCancel: false
							});
						}
					}, this)
				})
			},
			convertReqData() {
				// #ifdef H5
				const imgUrl = this.imgBase64 //todo H5非base64上传后web端无法查看图片
				// #endif
				// #ifdef MP
				const imgUrl = this.imgUrl 
				// #endif
				uploadImg(imgUrl).then(res => {
					let newImgUrl = JSON.parse(res).data.path
					let list = []
					this.orderList.map(order => {
						list.push({
							'id': order.id,
							'images': newImgUrl,
							'abnormal': order.abnormal,
							'content': order.content
						})
					})
					this.onSignFor(list)
				}).catch(err => {
					console.log(err);
				})
			},
			//订单签收
			onSignFor(list) {
				const { selectedId, locationInfo, shipmentMode, shipmentId } = this
				const { longitude, latitude, address } = locationInfo
				const reqData = {
					'aux': {
						stopId: selectedId,
						shipmentId,
						list: [...list],
						eventSource: 'DriverApp',
						longitude,
						latitude,
						address,
						time: formatTime(new Date())
					}
				}				
				const signMode = {
					'OM': 'MovementShipment',
					'OR': 'SimpleShipment',
					'MS': 'MassShipment'
				}
				signFor(signMode[shipmentMode], reqData).then(res => {
					if (res.data.messageType === 'success') {
						uni.showToast({
							title: '操作成功',
							duration: 3000
						})
						setTimeout(() => {
							uni.navigateBack({ delta: 2 })
						}, 1500)
					}
				})
			},
		}
	};
</script>

<style lang="scss">
	.signature {
		font-size: 28rpx;
		height: 100vh;
		position: relative;

		.operate-btns {
			height: 100%;
			display: inline-flex;
			flex-direction: column;
			justify-content: space-evenly;
			align-items: center;
			line-height: 70rpx;
			position: absolute;
			z-index: 1;

			&/deep/.t-icon {
				width: 60rpx;
				height: 60rpx;
			}

			.btnItem {
				font-size: 28rpx;
				width: 120rpx;
				height: 70rpx;
				padding: 0;
				margin: 0 10rpx;
				border-radius: 10rpx;
				line-height: 70rpx !important;
				display: flex;
				text-align: center;
				justify-content: center;
				align-items: center;
				background: #008ef6;
				transform: rotate(90deg);
			}

			.resetBtn,
			.backBtn {
				color: #436BF8;
				background-color: #fff;
				border: 2rpx solid #436BF8;
			}

			.saveBtn,
			.cancelBtn {
				color: #fff;
			}
			.cancelBtn{
				background-color: #FF4D4F;
			}
		}

		.signature-content,
		.customMask {
			width: 100%;
			height: 100%;
			overflow: hidden;
		}

		.customMask {
			position: absolute;
			z-index: 2;
			pointer-events: none;
			justify-content: center;

			.tip-content {
				color: #000;
				letter-spacing: 10rpx;
				font-size: 32rpx;
				transform: rotate(90deg);
				opacity: 0.2;
			}

			.tip-title {
				font-size: 48rpx;
				padding-left: 30rpx;
			}
		}

		//签名预览
		.preview-mask {
			width: 100%;
			height: 100%;
			background-color: rgba(0, 0, 0, 0.5);
			position: absolute;
			top: 0;
			left: 0;
			z-index: 111;

			.preview-sign {
				width: 70vw;
				height: 80vh;
				background-color: #fff;
				position: absolute;
				z-index: 666;
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%);

				.previewTitle {
					width: 100%;
					text-align: center;
					font-size: 32rpx;
					letter-spacing: 10rpx;
					transform: rotate(90deg);
					translate: (0, -50%);
					position: absolute;
					left: 40%;
					top: 50%;
					z-index: 3;
				}

				.preview-redraw,
				.preview-submit {
					transform: rotate(90deg);
					padding: 20rpx;
					color: #fff;
					background-color: #008EF6;
					letter-spacing: 10rpx;
					text-align: center;
					position: absolute;
					left: 2%;
					top: 30%;
					z-index: 1;
				}

				.preview-submit {
					top: 70%;
				}
			}
		}

		.palette-container {
			width: 100%;
			padding: 20rpx;
			background-color: #333333;
			transform: translateY(-50%) rotate(90deg);
			position: absolute;
			top: 50%;
			right: 25%;
			z-index: 2;

			.palette-block-item {
				width: 40rpx;
				height: 40rpx;
			}
		}

		.atom-container-brush {
			width: 100%;
			padding: 20rpx 20rpx 0;
			background-color: #F6D6B5;
			transform: translateY(-50%) rotate(90deg);
			position: absolute;
			top: 50%;
			right: 25%;
			z-index: 2;

			.brush-item {
				padding: 15rpx;
				width: 180rpx;
				margin-left: 40rpx;
			}

			.slender {
				border-top: 6rpx solid #333333;
			}

			.medium {
				border-top: 8rpx solid #333333;
			}

			.bolder {
				border-top: 10rpx solid #333333;
			}
		}
	}
</style>
