<template>
	<view class="app-container">
		<view class="fixed-container">
			<view class="top-container">
				<scroll-view
					:scroll-x="true"
					:scroll-left="scrollLeft"
					scroll-with-animation
					:show-scrollbar="false"
					class="tabs-view"
					ref="tabs-view">
					<view class="tab">
						<block v-for="(item, index) in tabList" :key='index'>
							<view class="item" :ref="`tabs-item-${index}`" :class="[`tabs-item-${index}`, item.categoryId == tabCurrent ? 'current':'']" @tap="changeTab(item.categoryId)">{{item.name}}</view>
						</block>
					</view>
				</scroll-view>
			</view>
			<view class="search-container">
				<view class="search">
					<image src="/static/icon/search.png" class=""></image>
					<input type="text" confirm-type="search" placeholder="搜索商品名称" v-model="keyword" @confirm="searchSubmit">
				</view>
			</view>
		</view>
		
		<view class="banner-container" v-if="bannerUrl">
			<image :src="bannerUrl" mode="widthFix"></image>
		</view>
		
		<view class="list-container">
			<block v-for="(item, index) in dataList" :key='index'>
				<div class="item" @tap="toGoodsDetail(item.goodsId)">
					<image :src="item.goodsImgSrc" mode="aspectFill"></image>
					<view class="right">
						<view class="title ellipsis-2">{{item.goodsName}}</view>
						<view class="des ellipsis-2">{{item.describeText ? item.describeText : ''}}</view>
						<view class="stock-sales">
							<view class="stock">
								<text>剩余{{item.stock}}件</text>
								<view class="progress-box">
									<!-- 库存 / 总数 * 100 = 剩余百分比 -->
									<progress :percent="item.stock / (item.stock+100) * 100" activeColor="#FF3F42" active stroke-width="6" />
								</view>
							</view>
							<view class="sales">销量：{{item.saleNum || '0'}}</view>
						</view>
						<view class="bottom">
							<view class="price">
								<view class="price-1">¥{{item.groupPrice | numToFixed}}</view>
								<view class="price-2">¥{{item.orgGoodsPrice | numToFixed}}</view>
							</view>
							<view class="btn">去拼团</view>
						</view>
					</view>
				</div>
			</block>
		</view>
		<no-data v-if="!dataList.length" :showText="'暂无数据'"></no-data>
		<loading-text v-if="dataList.length"  :loading="loading" :noMore="noMore" ></loading-text>
		
		<view class="share-container" :style="{top: top+'px'}" v-if="dataList.length">
			<button @tap="clickShare">
				<image src="@/static/icon/share.png"></image>
				<text>分享</text>
			</button>
		</view>
		
		<view class="global-mask" v-show="isShareDialog" @tap="isShareDialog = false"></view>
		<view class="sharelist-container" v-show="isShareDialog">
			<button class="item" open-type="share" @tap="isShareDialog = false">
				<image src="@/static/icon/wechat.png"></image>
				<text>分享给微信好友</text>
			</button>
			
			<view class="item" @tap="markImage">
				<image src="@/static/icon/image.png"></image>
				<text>生成图片分享</text>
			</view>
		</view>
		
		<view class="global-mask" v-show="isShowCanvas" @tap="closeCanvas"></view>
		<view class="canvas-container" v-show="isShowCanvas">
			<view class="content">
				<canvas style="width: 340px; height: 340px;" canvas-id="myCanvas" id="myCanvas"></canvas>
			</view>
			<view class="button"><text @tap="saveImage">保存图片</text></view>
		</view>
		
		<drag-button :isDock="true" :customBar="true" ref="dragButton"></drag-button>
	</view>
</template>

<script>
	import {mapState} from 'vuex';
	import dragButton from '@/components/drag-button.vue';
	
	export default {
		components:{
			dragButton
		},
		data() {
			return {
				configInfo: uni.getStorageSync('configInfo'),
				dataList: [], // 优惠券列表
				pageNum: 1,
				pageSize: 8,
				noMore: false,
				loading: false,
				isShareDialog: false, // 是否显示分享弹窗
				isShowCanvas: false, // 是否显示海报弹窗
				isFinishCanvas: false, // 是否已完成海报
				codeUrl: '',
				bgUrl: '',
				headUrl: '',
				top: 300,
				tabList: [], // 分类列表
				tabCurrent: '', // 分类当前值
				keyword: '',
				
				scrollLeft: 50,
				scrollViewWidth: 0,
				tabsRect: {
					left: 0
				},
				
				bannerUrl: '',
			}
		},
		
		watch: {
			tabList() {
				this.$nextTick(() => {
					this.resize()
				})
			},
		},
		
		computed:{
			...mapState(['userInfo', 'isLogin', 'userId'])
		},
		
		onShow() {
			this.$refs.dragButton.init();
			
			this.top = uni.getStorageSync('top') < 200 ? uni.getStorageSync('top') : uni.getStorageSync('top') - 124;
		},
		
		onLoad() {
			this.getTabList();
			this.getBanner();
		},
		
		// 下拉刷新
		onPullDownRefresh() {
			this.pageNum = 1;
			this.getList();
		},
		
		// 上拉加载
		onReachBottom() {
			this.getList(1);
		},
		
		onShareAppMessage(options) {
			if (options && options.from == 'button') {
				// 来自页面内的转发按钮
			} else {
				// 点击微信右上角的分享按钮
			}
			return {
				title: `${this.userInfo.nickName}向你推荐了${this.configInfo.minAppName}的团购活动`,
				// imageUrl: this.detail.imgUrl,
				path: '/pages/index/index?serviceId=' + this.userId + '&otherType=groupbuyList',
				query: {
					// id: this.goodsId,
				},
				success: function(res) {
					if(res.errMsg == 'shareAppMessage:ok'){
						this.$successToast('分享完成');
					}
				}
			}
		},
		
		methods: {
			getList(loadMore) {
				if(this.noMore && loadMore)return;
				this.noMore = false
				if(!loadMore){
					this.pageNum = 1;
				}else{
					this.loading = true;
				}
				this.$axios({
					url: '/goods/promotion/group/list',
					method: 'get',
					params: {
						pageNo: this.pageNum,
						pageSize: this.pageSize,
						userId: this.userId,
						goodsCategoryId: this.tabCurrent,
						keyword: this.keyword,
					},
					isLoading: !loadMore
				}).then(res => {
					let _list = res.data.records;
					let pageTotal = res.data.pages;
					if(this.pageNum >= pageTotal){
						this.noMore = true;
					}
					if (_list.length) {
						this.pageNum += 1
					}
					if (loadMore) {
						this.dataList = this.dataList.concat(_list);
						this.loading = false;
					} else {
						this.dataList = _list;
					}
					
					uni.stopPullDownRefresh();
				})
			},
			
			// 获取一级菜单
			getTabList() {
				this.$axios({
					url: '/goods/category/list',
					method: 'get',
					params: {}
				}).then(res => {
					res.data.unshift({name: "全部", categoryId: ""})
					this.tabList = res.data;
					this.tabCurrent = res.data.length > 0 ? res.data[0].categoryId : 0;
					this.getList();
				})
			},
			
			// 切换一级菜单
			changeTab(current) {
				this.pageNum = 1;
				this.tabCurrent = current;
				this.resize();
				this.getList();
			},
			
			searchSubmit() {
				this.pageNum = 1;
				this.getList();
			},
			
			setScrollLeft() {
				// 当前活动tab的布局信息，有tab菜单的width和left(为元素左边界到父元素左边界的距离)等信息
				const index = this.findElem(this.tabList, 'categoryId', this.tabCurrent);
				const tabRect = this.tabList[index]
				// 累加得到当前item到左边的距离
				const offsetLeft = this.tabList
					.slice(0, index)
					.reduce((total, curr) => {
						return total + curr.rect.width
					}, 0)
				// 此处为屏幕宽度
				const res = uni.getSystemInfoSync();
				const windowWidth = res.windowWidth;
				// 将活动的tabs-item移动到屏幕正中间，实际上是对scroll-view的移动
				let scrollLeft = offsetLeft - (this.tabsRect.width - tabRect.rect.width) / 2 - (windowWidth - this.tabsRect.right) / 2 + this.tabsRect.left / 2
				
				// 这里做一个限制，限制scrollLeft的最大值为整个scroll-view宽度减去tabs组件的宽度
				scrollLeft = Math.min(scrollLeft, this.scrollViewWidth - this.tabsRect.width)
				this.scrollLeft = Math.max(0, scrollLeft)
			},
			// 获取所有标签的尺寸
			resize() {
				// 如果不存在list，则不处理
				if(this.tabList.length === 0) {
					return
				}
				Promise.all([this.getTabsRect(), this.getAllItemRect()]).then(([tabsRect, itemRect = []]) => {
					this.tabsRect = tabsRect
					this.scrollViewWidth = 0
					itemRect.map((item, index) => {
						// 计算scroll-view的宽度，这里
						this.scrollViewWidth += item.width
						// 另外计算每一个item的中心点X轴坐标
						this.tabList[index].rect = item
					})
					// 获取了tabs的尺寸之后，设置滑块的位置
					this.setScrollLeft()
				})
			},
			// 获取导航菜单的尺寸
			getTabsRect() {
				return new Promise(resolve => {
					this.queryRect('tabs-view').then(size => resolve(size))
				})
			},
			// 获取所有标签的尺寸
			getAllItemRect() {
				return new Promise(resolve => {
					const promiseAllArr = this.tabList.map((item, index) => this.queryRect(
						`tabs-item-${index}`, true))
					Promise.all(promiseAllArr).then(sizes => resolve(sizes))
				})
			},
			// 获取各个标签的尺寸
			queryRect(el, item) {
				const query = uni.createSelectorQuery().in(this);
				return new Promise(resolve => {
					query.select(`.${el}`).boundingClientRect(data => {
						resolve(data)
					}).exec();
				})
			},
			
			findElem(array, attr, val) {
			    for (var i = 0; i < array.length; i++) {
			        if (array[i][attr] == val) {
			            return i; //返回当前索引值
			        }
			    }
			    return -1;
			},
			
			// 进入商品详情
			toGoodsDetail(id) {
				if(!id) {
					return false;
				}
				uni.navigateTo({
					url: '/packageGoods/pages/detail?id=' + id
				})
			},
			
			// 获取海报图
			getBanner() {
				this.$axios({
					url: '/goods/promotion/share/qrcode',
					method: 'get',
					params: {
						userId: this.userId,
					}
				}).then(res => {
					this.bannerUrl = res.data.posterImgUrl;
				})
			},
			
			// 点击分享
			clickShare() {
				if(!this.isLogin) {
					return uni.navigateTo({
						url: '/pages/login/index'
					})
				}
				this.getCode();
				this.isShareDialog = true;
			},
			
			// 获取二维码
			getCode() {
				let that = this;
				this.$axios({
					url: '/goods/promotion/share/qrcode',
					method: 'get',
					params: {
						userId: this.userId,
					}
				}).then(res => {
					if(res.data) {
						// this.codeUrl = res.data.qrcode;
						// this.bgUrl = res.data.promotionImgUrl;
						if(!this.isFinishCanvas) {
							uni.downloadFile({
							    url: res.data.promotionImgUrl,
							    success: function (fileRes) {
									that.bgUrl = fileRes.tempFilePath;
								}
							})
							uni.downloadFile({
							    url: res.data.qrcode,
							    success: function (fileRes) {
									that.codeUrl = fileRes.tempFilePath;
								}
							})
							uni.downloadFile({
							    url: that.userInfo.avatar.indexOf('http') >= 0 ? that.userInfo.avatar : (that.$imageUrl + that.userInfo.avatar),
							    success: function (fileRes) {
									that.headUrl = fileRes.tempFilePath;
								}
							})
						}
					}
				})
			},
			
			// 生成图片
			markImage() {
				if(!this.bgUrl || !this.codeUrl || !this.headUrl) {
					this.getCode();
					return this.$toast('生成失败，请重新操作');
				}
				
				let that = this;
				this.isShareDialog = false;
				this.isShowCanvas = true;
				
				if(this.isFinishCanvas) {
					return false;
				}
				
				uni.showLoading({
				    title: '海报生成中'
				});
				
				let codeUrl = this.codeUrl;
				let bgUrl = this.bgUrl;
				let headUrl = this.headUrl;
				
				// this.userInfo.nickName = '阿里巴巴的的';
				let name = this.userInfo.nickName.length > 4 ? this.userInfo.nickName.slice(0, 4) + '...' : this.userInfo.nickName;
				
				var ctx = uni.createCanvasContext('myCanvas');
				
				// 背景图片
				ctx.drawImage(bgUrl, 0, 0, 340, 340)
				
				// 二维码
				this.circleImgOne(ctx, codeUrl, 260, 260, uni.upx2px(70));
				// ctx.drawImage(codeUrl, 260, 260, 70, 70)
				
				// 矩形
				// ctx.setFillStyle('rgba(0,0,0,0.4)')
				// ctx.fillRect(185, 10, 145, 30)
				
				// 圆角矩形
				this.fillRoundRect(ctx, 175, 10, 155, 30, 15, 'rgba(0,0,0,0.4)');
				
				// 头像
				// this.circleImgOne(ctx, headUrl, 200, 10, 15);
				ctx.drawImage(headUrl, 187, 12, 26, 26)
				
				// 文字
				ctx.setFontSize(12)
				ctx.setFillStyle('#FFFFFF')
				ctx.fillText(name+'向你推荐', 217, 30)
				
				ctx.draw()
				uni.hideLoading();
				this.isFinishCanvas = true;
			},
			
			// ctx=Canvas实例, img=图片地址, x=x轴坐标, y=y轴坐标, r=圆形半径
			circleImgOne(ctx, img, x, y, r) {
				// 如果在绘制图片之后还有需要绘制别的元素，需启动 save() 、restore() 方法，否则 clip() 方法会导致之后元素都不可见
				// save()：保存当前 Canvas 画布状态
				// restore()：恢复到保存时的状态
				ctx.save();
				let d = r * 2;
				let cx = x + r;
				let cy = y + r;
				ctx.arc(cx, cy, r, 0, 2 * Math.PI);
				ctx.strokeStyle = '#FFFFFF'; // 设置绘制圆形边框的颜色
				ctx.stroke(); // 绘制出圆形，默认为黑色，可通过 ctx.strokeStyle = '#FFFFFF'， 设置想要的颜色
				ctx.clip();
				ctx.drawImage(img, x, y, d, d);
				ctx.restore();
			},
			
			/**该方法用来绘制一个有填充色的圆角矩形 
				*@param cxt:canvas的上下文环境 
				*@param x:左上角x轴坐标 
				*@param y:左上角y轴坐标 
				*@param width:矩形的宽度 
				*@param height:矩形的高度 
				*@param radius:圆的半径 
				*@param fillColor:填充颜色 
			 **/
			fillRoundRect(cxt, x, y, width, height, radius, fillColor) {
				//圆的直径必然要小于矩形的宽高          
				if (2 * radius > width || 2 * radius > height) { return false; }
		
				cxt.save();
				cxt.translate(x, y);
				//绘制圆角矩形的各个边
				this.drawRoundRectPath(cxt, width, height, radius);
				cxt.fillStyle = fillColor;
				cxt.fill();
				cxt.restore();
			},
			
			drawRoundRectPath(cxt, width, height, radius) {
				cxt.beginPath(0);
				//从右下角顺时针绘制，弧度从0到1/2PI  
				cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
				//矩形下边线
				cxt.lineTo(radius, height);
				//左下角圆弧，弧度从1/2PI到PI
				cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
				//矩形左边线
				cxt.lineTo(0, radius);
				//左上角圆弧，弧度从PI到3/2PI  
				cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
				//上边线  
				cxt.lineTo(width - radius, 0);
				//右上角圆弧  
				cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
				//右边线  
				cxt.lineTo(width, height - radius);
				cxt.closePath();
			},
			
			// 保存图片
			saveImage() {
				let that = this;
				uni.canvasToTempFilePath({
					x: 0,
					y: 0,
					width: 340,
					height: 340,
					canvasId: 'myCanvas',
					success: function(res) {
						uni.saveImageToPhotosAlbum({
							filePath: res.tempFilePath,
							success: function () {
								that.$successToast('保存成功');
							}
						});
					} 
				})
			},
			
			// 关闭canvas
			closeCanvas() {
				this.isShowCanvas = false;
				uni.hideLoading();
			},
			
		}
	}
</script>

<style lang="scss">
	.app-container {
		background: #F4F2F2;
		box-sizing: border-box;
		padding-top: 184rpx;
	}
	
	.fixed-container {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
	}
	
	.share-container {
		position: fixed;
		right: 20rpx;
		// bottom: 30vh;
		button {
			width: 108rpx;
			height: 108rpx;
			padding: 0;
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
			border-radius: 50%;
			// box-shadow: 0 1px 4px rgba(0, 21, 41, .8);
			background: #ffffff;
			border: 4rpx solid #eaeaea;
			image {
				width: 28rpx;
				height: 28rpx;
				display: block;
				flex-shrink: 0;
				margin-bottom: 6rpx;
			}
			text {
				font-size: 22rpx;
				line-height: 24rpx;
				color: #666666;
				margin-top: 8rpx;
			}
		}
	}
	
	.top-container {
		background: #FFFFFF;
		.tab {
			display: flex;
			margin-left: -10rpx;
			.item {
				display: flex;
				flex-direction: column;
				align-items: center;
				flex-shrink: 0;
				font-size: 28rpx;
				color: #666666;
				height: 80rpx;
				line-height: 80rpx;
				position: relative;
				padding: 0 30rpx;
				&.current {
					color: #FF3F42;
					font-weight: 600;
					&::after {
						content: '';
						display: block;
						width: 50rpx;
						height: 6rpx;
						background: #FF3F42;
						position: absolute;
						bottom: 0;
						left: 50%;
						margin-left: -25rpx;
					}
				}
			}
		}
	}
	
	.search-container {
		background: #FFFFFF;
		padding: 20rpx;
		.search {
			height: 64rpx;
			display: flex;
			align-items: center;
			border-radius: 64rpx;
			padding: 0 20rpx;
			border: 1px solid #eaeaea;
			image {
				width: 28rpx;
				height: 28rpx;
			}
			input {
				width: 100%;
				padding-left: 15rpx;
			}
		}
	}
	
	.banner-container {
		padding: 20rpx 20rpx 0;
		image {
			display: block;
			width: 100%;
			border-radius: 10rpx;
		}
	}
	
	.list-container {
		padding: 20rpx;
		.item {
			background: #FFFFFF;
			border-radius: 10rpx;
			display: flex;
			padding: 20rpx;
			margin-bottom: 20rpx;
			image {
				display: block;
				width: 180rpx;
				height: 180rpx;
				flex-shrink: 0;
			}
			.right {
				width: 490rpx;
				box-sizing: border-box;
				padding-left: 20rpx;
				.title {
					font-size: 30rpx;
					color: #333333;
					line-height: 36rpx;
					font-weight: 600;
				}
				.des {
					font-size: 24rpx;
					line-height: 30rpx;
					color: #999999;
					margin-top: 6rpx;
				}
				.stock-sales {
					display: flex;
					justify-content: space-between;
					align-items: center;
					margin-top: 10rpx;
					font-size: 24rpx;
					color: #666666;
					.stock {
						display: flex;
						align-items: center;
						text {
							font-size: 24rpx;
							color: #666666;
						}
						.progress-box {
							width: 140rpx;
							border-radius: 6px;
							overflow: hidden;
							margin-left: 10rpx;
						}
					}
				}
				.bottom {
					display: flex;
					justify-content: space-between;
					align-items: center;
					margin-top: 10rpx;
					.price {
						display: flex;
						flex-direction: column;
					}
					.price-1 {
						font-size: 32rpx;
						color: #FF3F42;
						line-height: 36rpx;
					}
					.price-2 {
						font-size: 26rpx;
						color: #666666;
						line-height: 30rpx;
						text-decoration: line-through;
					}
					.btn {
						width: 110rpx;
						height: 44rpx;
						background: #FF3F42;
						border-radius: 5rpx;
						font-size: 28rpx;
						color: #FFFFFF;
						text-align: center;
						line-height: 44rpx;
					}
					.btn2 {
						width: 110rpx;
						height: 44rpx;
						background: #AAAAAA;
						border-radius: 5rpx;
						font-size: 28rpx;
						color: #FFFFFF;
						text-align: center;
						line-height: 44rpx;
					}
				}
			}
		}
	}
	
	.sharelist-container {
		position: fixed;
		bottom: 0;
		left: 0;
		z-index: 999;
		width: 100%;
		box-sizing: border-box;
		background: #FFFFFF;
		padding: 30rpx 0;
		display: flex;
		button {
			background: none;
			border-radius:0;
			&::after {
				border: none;
			}
		}
		.item {
			display: flex;
			width: 50%;
			flex-direction: column;
			align-items: center;
			image {
				width: 100rpx;
				height: 100rpx;
				display: block;
				margin-bottom: 20rpx;
			}
			text {
				font-size: 28rpx;
				line-height: 32rpx;
				color: #333333;
			}
		}
	}
	.canvas-container {
		position: fixed;
		left: 50%;
		top: 50%;
		z-index: 999;
		margin-left: -170px;
		margin-top: -170px;
		.button {
			display: flex;
			justify-content: center;
			text {
				display: block;
				width: 280rpx;
				height: 70rpx;
				border-radius: 70rpx;
				background: linear-gradient(-90deg,#ff3f42 0%, #fe781f 100%);
				font-size: 28rpx;
				color: #FFFFFF;
				text-align: center;
				line-height: 70rpx;
				margin-top: 20rpx;
			}
		}
	}
</style>
