<template>
	<view class="page" :style="{ height: windowHeight + 'px', flexDirection: flexDirection }">
		<view id="map" :style="{ height: mapHeight + 'px', width: mapWidth + 'px' }" class='map' />

		<view v-show="popupShow" class="popup" :style="{ height: popupHeight + 'px', width: popupWidth + 'px' }">
			<!-- <uni-section title="活动路线列表" type="line"> -->
				<uni-data-picker class="actionsTree" placeholder="请选择活动" popup-title="请选择活动路线" :localdata="actionsTree"
					v-model="sltActRoute" @change="onActionChange" @popupopened="onActionsTreePopupOpened" @popupclosed="onActionsTreePopupClosed"></uni-data-picker>
			<!-- </uni-section> -->

			<!-- <uni-section title="玩家列表" type="line"> -->
				<scroll-view :scroll-top="0" scroll-y="true" class="scroll-Y" :style="{ height: popupHeight - 35 + 'px'}">
					<uni-list v-for="(item, index) in players" :key="index" :border="true" class="list">
						<uni-list-item :clickable="true" @click="onPlayerListItemClick(item)" class="list-item" :class="{ 
							'list-item-focus': focusPlayerId == item.id 
							}">
							<template v-slot:header>
								<!-- <image class="slot-image" src="/static/logo.png" mode="widthFix"></image> -->
								<div class="slot-image" :style="'background-color:' + getPlayerColor(item.id)"></div>
							</template>
							<template v-slot:body>
								<view class="slot-box">
									<view class="slot-title">
										[{{index+1}}] <span class="slot-phone" @click="onPhoneClick(item.phone)">
											{{item.name}} </span>
										打点 {{item.effectivenum}}/{{item.totalcontrolnum}} 距离
										{{item.distance}}米 配速 {{formatTime(item.pace, false)}}
									</view>
									<view class="slot-note">
										心率 {{item.lasthr}} 平均 {{item.avghr}} 最大 {{item.maxhr}} | CAL
										{{Math.round(item.calorie/1000)}} Ck {{Math.round(item.ck/1000)}} Ei
										{{Math.round(item.ei*100)/100}}
									</view>
								</view>
							</template>
							<!-- <template v-slot:footer>
							<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
						</template> -->
						</uni-list-item>
					</uni-list>
				</scroll-view>
			<!-- </uni-section> -->
		</view>

	</view>
</template>

<script>
	import {
		mapState,
		mapGetters
	} from 'vuex'

	import {
		DefaultRequest,
		IdRequest,
	} from "@/grpc/base_pb.js"

	import {
		ToActionIdAndCourseIdRequest
	} from "@/grpc/track_offical_pb.js"
	
	import {
		formatTime
	} from "@/utils/util.js"

	export default {
		components: {},
		data() {
			return {
				interval_loadActionsTree: null,
				interval_loadData: null,
				actionsTreePopup: false,

				systemInfo: null,
				flexDirection: 'column',
				windowHeight: 0,
				windowWidth: 0,
				mapHeight: 0,
				mapWidth: 0,
				popupHeight: 0,
				popupWidth: 0,
				popupHeightPortrait: 360, // 竖屏状态下的底部弹框高度
				popupWidthlandscape: 330, // 横屏状态下的右侧弹框宽度
				popupType: 'bottom',
				popupShow: false,
				extraIcon: {
					// color: '#4cd964',
					// size: '22',
					// type: 'gear-filled'
				},

				mapId: 0,
				mapDetail: {},
				mapUrl: null,
				mapInfo: {},

				actionId: 0,
				actionDetail: {},

				routeId: 0,
				routeDetail: {},

				// checkPoints: [],
				nextCP: [], // 用户即将到达控制点列表
				players: [],
				players_position: [],
				focusPlayerId: 0,
				trailTime: 0,

				sltActRoute: '',
				actionsTree: []
			}
		},
		computed: {
			...mapState([
				'username', // 映射 this.username 为 store.state.username
			]),
			...mapGetters([
				'metadata'
			]),
		},
		mounted() {
			this.$global.getWindowInfo()
			uni.$on('windowResize', this.reLoad)
			this.popupShow = this.$store.state.mapPopupShow
			this.layoutInit()
		},
		onLoad(option) {
			console.log('[onLoad] mapId:' + option.mapId)
			if (option.mapId > 0) {
				this.mapId = option.mapId
				this.loadMap(this.mapId)

				if (this.mapId == this.$store.state.mapSltMapId) { // 页面重载
					this.sltActRoute = this.$store.state.mapSltActRoute
					this.loadData(this.sltActRoute)
				}
				
				if (this.interval_loadActionsTree != null) {
					clearInterval(this.interval_loadActionsTree)
				}
				
				let that = this
				this.interval_loadActionsTree = setInterval(async function() {
					if (!that.actionsTreePopup) {
						await that.loadActionsTree()
					}
				}, 3000);
			}
		},
		beforeDestroy() {
			console.log("[beforeDestroy]")
			clearInterval(this.interval_loadActionsTree)
			clearInterval(this.interval_loadData)
			// leafletHelper.free()
			uni.$off('windowResize', this.reLoad)
		},
		methods: {
			formatTime,
			reLoad() {
				this.$store.commit('setMapSltMapId', this.mapId)
				this.savePlayersData()

				var fullPath = this.$route.fullPath
				console.log("[windowResize] reLaunch: " + fullPath)
				uni.redirectTo({
					url: fullPath
				});
			},
			// 布局初始化 设置地图高度
			layoutInit() {
				this.windowHeight = this.$global.windowHeight
				this.windowWidth = this.$global.windowWidth
				if (this.$global.deviceOrientation == 'portrait') { // 竖屏
					this.flexDirection = 'column'
					this.mapWidth = this.$global.windowWidth
					this.mapHeight = this.$global.windowHeight
					// if (this.popupShow) {
					// 	this.mapHeight = this.$global.windowHeight - this.popupHeightPortrait
					// } else {
					// 	this.mapHeight = this.$global.windowHeight
					// }
					// console.log("竖屏", this.mapHeight)
					this.popupHeight = this.popupHeightPortrait
					this.popupWidth = this.$global.windowWidth
				} else { // 横屏
					this.flexDirection = 'row'
					this.mapHeight = this.$global.windowHeight
					this.mapWidth = this.$global.windowWidth
					// if (this.popupShow) {
					// 	this.mapWidth = this.$global.windowWidth - this.popupWidthlandscape
					// } else {
					// 	this.mapWidth = this.$global.windowWidth
					// }
					// console.log("横屏", this.mapWidth)
					this.popupHeight = this.$global.windowHeight
					this.popupWidth = this.popupWidthlandscape
					// console.log("横屏 popupHeight", this.popupHeight)
				}
			},
			popupToggle() {
				this.popupShow = !this.popupShow
				this.$store.commit('setMapPopupShow', this.popupShow)
				// this.layoutInit()
			},
			fullScreenToggle() {
				this.$global.fullscreen()
				this.$global.getWindowInfo()
				this.layoutInit()
			},
			makeActionsTree(actselectrsList) {
				this.actionsTree.length = 0 // 先清空数组
				for (let i = 0; i < actselectrsList.length; i++) {
					var act = actselectrsList[i]
					var pushData = {
						text: act.actname,
						value: act.actid,
						children: []
					}

					var actUserNum = 0
					for (let j = 0; j < act.courseselectrsList.length; j++) {
						var course = act.courseselectrsList[j]
						actUserNum += course.courseusernum
						pushData.children.push({
							text: course.coursename + ' (' + course.courseusernum + '人)',
							value: act.actid + '-' + course.courseid
						})
					}
					if (actUserNum > 0) {
						pushData.children.unshift({
							text: '全部 (' + actUserNum + '人)',
							value: act.actid + '-' + 0
						})
					}

					pushData.text += ' (' + actUserNum + '人)'
					this.actionsTree.push(pushData)
				}
				// console.log("[makeActionsTree]" + JSON.stringify(this.actionsTree))
			},
			async loadMap() {
				await this.loadActionsTree()
				uni.setNavigationBarTitle({
					title: this.mapDetail.mapinfo.mapname
				});
				// console.log(this.actionDetail)

				this.initMap()
				this.handleMapToggle()
			},
			async loadActionsTree() {
				this.mapDetail = await this.getToMapDetail(this.mapId)
				this.makeActionsTree(this.mapDetail.actselectrsList)
			},
			async loadData(sltActRoute) {
				console.log("[loadData] sltActRoute: ", sltActRoute)
				if (sltActRoute == null || sltActRoute.length == 0) {
					return
				}

				var actRouteArr = sltActRoute[1].value.split('-')
				this.actionId = actRouteArr[0]
				this.routeId = actRouteArr[1]

				this.actionDetail = await this.getToActionDetail(this.actionId, this.routeId)
				uni.setNavigationBarTitle({
					title: this.mapDetail.mapinfo.mapname + ' - ' + this.actionDetail.name
				});
				// console.log(this.actionDetail)

				if (this.interval_loadData != null) {
					clearInterval(this.interval_loadData)
				}

				this.players = await this.getToUsersInGameDetail(this.actionId, this.routeId)
				// console.log('players', that.players)
				// leafletHelper.global.setPlayers(this.players)

				this.players_position = await this.getToUsersInGameGpsQuery(this.actionId, this.routeId)
				// leafletHelper.global.setPlayersPosition(this.players_position)
				
				this.nextCP = await this.getToNextControlPointInGame(this.actionId, this.routeId)
				
				this.handleMapDrawRoute()
				this.handleMapDrawPlayer()
				this.handleMapDrawTrail()

				let that = this
				this.interval_loadData = setInterval(async function() {
					that.players = await that.getToUsersInGameDetail(that.actionId, that.routeId)
					that.players_position = await that.getToUsersInGameGpsQuery(that.actionId, that
						.routeId)
					that.nextCP = await that.getToNextControlPointInGame(that.actionId, that.routeId)
					//// leaflet.leafletHelper.global.setPlayers(that.players)
					// leafletHelper.global.setPlayersPosition(that.players_position)
					that.handleMapDrawPlayer()
					that.handleMapDrawTrail()
				}, 1000);
			},
			//场控端_地图详情
			async getToMapDetail(mapId) {
				try {
					return new Promise((resolve, reject) => {
						// 创建请求参数并赋值
						var request = new IdRequest()
						request.setId(mapId)
						// 调用客户端相应的grpc方法，发送grpc请求，并接受后台发送回来的返回值
						this.$client.toMapDetail(request, this.metadata, (err, response) => {
							if (err) {
								console.warn(`[toMapDetail] err: code = ${err.code}` +
									`, message = "${err.message}"`)
								reject(err)
							} else {
								let res = response.toObject()
								// console.log('[toMapDetail]', res)
								resolve(res)
							}
						})
					});
				} catch (e) {
					console.log('[getToMapDetail] err', e)
					reject(e)
				}
			},
			//场控端_活动详情
			async getToActionDetail(actId, routeId = 0) {
				try {
					return new Promise((resolve, reject) => {
						// 创建请求参数并赋值
						var request = new ToActionIdAndCourseIdRequest()
						request.setActid(actId)
						request.setCourseid(routeId)
						// 调用客户端相应的grpc方法，发送grpc请求，并接受后台发送回来的返回值
						this.$client.toActionDetail(request, this.metadata, (err, response) => {
							if (err) {
								console.warn(`[toActionDetail] err: code = ${err.code}` +
									`, message = "${err.message}"`)
								reject(err)
							} else {
								let res = response.toObject()
								console.log('[toActionDetail]', res)
								resolve(res)
							}
						})
					});
				} catch (e) {
					console.log('[getToActionDetail] err', e)
					reject(e)
				}
			},
			//场控端_正在进行中所有用户实时信息
			async getToUsersInGameDetail(actId, routeId = 0) {
				try {
					return new Promise((resolve, reject) => {
						// 创建请求参数并赋值
						var request = new ToActionIdAndCourseIdRequest()
						request.setActid(actId)
						request.setCourseid(routeId)
						// 调用客户端相应的grpc方法，发送grpc请求，并接受后台发送回来的返回值
						this.$client.toUsersInGameDetail(request, this.metadata, (err,
							response) => {
							if (err) {
								console.warn(`[toUsersInGameDetail] err: code = ${err.code}` +
									`, message = "${err.message}"`)
								reject(err)
							} else {
								let res = response.toObject()
								// console.log('[toUsersInGameDetail]', res)
								resolve(res.usersList)
							}
						})
					});
				} catch (e) {
					console.log('[getToUsersInGameDetail] err', e)
					reject(e)
				}
			},
			//场控端_正在进行中所有用户实时gps查询
			async getToUsersInGameGpsQuery(actId, routeId = 0) {
				try {
					return new Promise((resolve, reject) => {
						// 创建请求参数并赋值
						var request = new ToActionIdAndCourseIdRequest()
						request.setActid(actId)
						request.setCourseid(routeId)
						// 调用客户端相应的grpc方法，发送grpc请求，并接受后台发送回来的返回值
						this.$client.toUsersInGameGpsQuery(request, this.metadata, (err,
							response) => {
							if (err) {
								console.warn(`[toUsersInGameGpsQuery] err: code = ${err.code}` +
									`, message = "${err.message}"`)
								reject(err)
							} else {
								let res = response.toObject()
								// console.log('[toUsersInGameGpsQuery]', res)
								resolve(res.gpsinfoList)
							}
						})
					});
				} catch (e) {
					console.log('[getToUsersInGameGpsQuery] err', e)
					reject(e)
				}
			},
			//场控端_正在进行中所有用户即将到达控制点列表，结果去重
			async getToNextControlPointInGame(actId, routeId = 0) {
				try {
					return new Promise((resolve, reject) => {
						// 创建请求参数并赋值
						var request = new ToActionIdAndCourseIdRequest()
						request.setActid(actId)
						request.setCourseid(routeId)
						// 调用客户端相应的grpc方法，发送grpc请求，并接受后台发送回来的返回值
						this.$client.toNextControlPointInGame(request, this.metadata, (err,
							response) => {
							if (err) {
								console.warn(`[toNextControlPointInGame] err: code = ${err.code}` +
									`, message = "${err.message}"`)
								reject(err)
							} else {
								let res = response.toObject()
								// console.log('[toNextControlPointInGame]', res)
								resolve(res.nextcontrolpointrsList)
							}
						})
					});
				} catch (e) {
					console.log('[getToUsersInGameGpsQuery] err', e)
					reject(e)
				}
			},
			onActionChange(e) {
				const sltActRoute = e.detail.value
				console.log("onActionChange", sltActRoute)
				this.$store.commit('setMapSltActRoute', sltActRoute)

				if (sltActRoute == null || sltActRoute.length == 0) {
					this.reLoad()
					return
				}
				this.loadData(sltActRoute)
			},
			onActionsTreePopupOpened() {
				// console.log("onActionsTreePopupOpened")
				this.actionsTreePopup = true
			},
			onActionsTreePopupClosed() {
				// console.log("onActionsTreePopupClosed")
				this.actionsTreePopup = false
			},
			onPlayerListItemClick(item) {
				// console.log("onListItemClick", item)
				this.handlePlayerListItemClick(item)
			},
			onPhoneClick(phoneNumber) {
				if (phoneNumber.length == 11) {
					uni.makePhoneCall({
						phoneNumber: phoneNumber
					})
				} else {
					uni.showToast({
						title: '手机号码不正确',
						icon: 'none'
					})
				}
			},
		}
	}
</script>

<script module="leaflet" lang="renderjs">
	import 'leaflet/dist/leaflet.css'
	import '@/utils/map/leafletHelper.css'

	// import mapHelper from '@/utils/mapHelper'
	import leafletHelper from '@/utils/map/leafletHelper'

	export default {
		components: {},
		// data() {
		// 	return {},
		// },
		// mounted() {
		// 	uni.$on('myEvent', this.myEventHandler);
		// },
		// destroyed() {
		// 	uni.$off('myEvent', this.myEventHandler);
		// },
		beforeDestroy() {
			// console.log("beforeDestroy")
			// clearInterval(this.interval_loadData)
			leafletHelper.free()
		},
		methods: {
			// myEventHandler(data) {
			// 	console.log('视图层接收到数据：', data);
			// },
			initMap() {
				if (this.mapDetail != null && this.mapDetail.mapinfo != null) {
					// const mapid = this.mapDetail.mapinfo.lid
					const mapUrl = this.mapDetail.mapinfo.mapurl
					const centPoint = [this.mapDetail.mapinfo.centerlatitude, this.mapDetail.mapinfo.centerlongitude]
					const zoomNum = this.mapDetail.mapinfo.defscale
					const mapOptions = {
						center: centPoint,
						zoom: zoomNum,
						maxBounds: [
							[36.659365, 117.105246],
							[36.653753, 117.122841]
						],
					}
					leafletHelper.init(this, 'map', mapUrl, mapOptions)
				}
			},
			handleWindowResize() {
				leafletHelper.onWindowResize()
			},
			handleMapDrawRoute() {
				// leafletHelper.global.setCheckPoints(this.checkPoints)
				// leafletHelper.global.setRoutes(this.mapDetail.routesList)
				leafletHelper.global.setRoutes(this.actionDetail.routesList)

				// leafletHelper.checkPoint.drawAllCheckPoints()
				// leafletHelper.checkPoint.drawPath()
				leafletHelper.route.drawAllRoutes()
				// leafletHelper.route.drawAllPath()
			},
			handleMapDrawPlayer() {
				leafletHelper.global.setPlayers(this.players)
				leafletHelper.global.setPlayersPosition(this.players_position)
				leafletHelper.player.drawAllPlayers()
				// leafletHelper.player.drawOnePlayer(2)
				// leafletHelper.player.drawOnePlayer(3)

				leafletHelper.global.dealStaleData()
			},
			handleMapDrawTrail() {
				this.trailTime = leafletHelper.config.trailTime
				// leafletHelper.player.drawOneTrail(2, 10000)
				// leafletHelper.player.drawOneTrail(3, 10000)
				// leafletHelper.player.drawOneTrail(2, 0, false)
				leafletHelper.player.drawAllTrails(this.trailTime)
			},
			handleMapToggle() {
				// leafletHelper.checkPoint.toggle(true)
				// leafletHelper.route.toggle(true)
				// leafletHelper.player.togglePlayer(true)
				// leafletHelper.player.toggleTooltip(true)
				// leafletHelper.player.toggleTrail(true)

				leafletHelper.route.toggle(this.$store.state.mapControlRoute)
				leafletHelper.player.togglePlayer(this.$store.state.mapControlPlayer)
				leafletHelper.player.toggleTooltip(this.$store.state.mapControlTooltip)
				leafletHelper.player.toggleTrail(this.$store.state.mapControlTrail)
			},
			handlePlayerListItemClick(item) {
				this.focusPlayerId = item.id
				leafletHelper.player.handleFocusPlayer(this.focusPlayerId)
			},
			getPlayerColor(playerId) {
				if (playerId != this.focusPlayerId)
					return leafletHelper.player.getPlayerColor(playerId)
				else
					return leafletHelper.config.gStyle.marker.focus.fillColor
			},
			// 页面reLoad前调用本方法，将用户数据先保存，页面重载后再进行数据恢复
			savePlayersData() {
				leafletHelper.global.savePlayersData()
			},
		},
	}
</script>

<style lang="scss" scoped>
	.page {
		display: flex;
		// margin: 0px;
		// padding: 0px;
	}

	// 勿删，解决map控件获得焦点后出现边框颜色的问题
	:focus-visible {
		outline: none;
	}

	.map {
		flex: 1 1 auto;
		background-color: white;
		z-index: 0;
		// display: flex;
		// justify-content: center;
		// align-items: center;
	}

	.popup {
		display: flex;
		flex-direction: column;
		align-items: center;
		background-color: #f5f5f5;
		border-left: #dedede solid 1px;
		// border-top: #dedede solid 1px;
		// overflow: scroll;
	}
	
	.actionsTree {
		width: 100%;
		// background-color: #ffffff;
		
		/deep/ .input-value-border {
		    border-top: 1px solid #e5e5e5;
		    border-bottom: 1px solid #e5e5e5;
		    border-radius: 0px;
		}
		
		/deep/ .uni-scroll-view {
		    overflow: unset !important;
		}
	}

	.scroll-Y {
		// height: 100vh;
	}

	.list {
		margin-left: -6px;
	}

	.list-item {
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		flex-direction: row;
		align-items: center;
		height: 46px;
	}

	.list-item-focus {
		background-color: #fffaef !important;
	}

	.slot-box {
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		flex-direction: column;
		align-items: flex-start;
		max-width: 280px;
	}

	.slot-image {
		/* #ifndef APP-NVUE */
		display: block;
		/* #endif */
		margin-right: 6px;
		width: 6px;
		height: 33px;
		align-self: center;
	}

	.slot-title {
		flex: 1;
		font-size: 13px;
		color: #424242;
		line-height: 18px;
		// margin-right: 10px;
		// overflow:hidden; //超出的文本隐藏
		// text-overflow:ellipsis; //溢出用省略号显示
		white-space: nowrap; //溢出不换行
	}

	.slot-note {
		flex: 1;
		font-size: 12px;		
		color: #7d8da7;
		line-height: 18px;
		// margin-right: 10px;
		// overflow:hidden; //超出的文本隐藏
		// text-overflow:ellipsis; //溢出用省略号显示
		white-space: nowrap; //溢出不换行
	}

	.slot-phone {
		padding: 0 5px;
		color: #000;
		font-weight: bold;
	}

	/deep/ .uni-data-tree-dialog {
		top: 39px;
	}
</style>