<!-- 
场控
http://localhost:5173/actMgt/#/pages/actManage/track?compId=80 
https://oss-mbh5.colormaprun.com/actMgt/#/pages/actManage/track?compId=80
 -->
<template>
	<view class="body">
		<view class="content uni-column">
			<view class="uni-column top" :style="getBannerStyle()">
				<my-topbar :title="actRs.config.matchInfo.compName" @btnBackClick="btnBack"></my-topbar>
				<view class="top-content uni-row">
				</view>
			</view>

			<view class="main uni-column">
				<view class="selectBox uni-row uni-jcse">
					<view class="select">
						<e-select v-model="mapId" maxHeight="300px" :props="selectMapProps" :options="mapList"
							:search="false" :inputClick="false" :clearable="false" @getText="getESelectText"
							@change="selectMapChange"></e-select>
					</view>
					<!-- <view class="select">
						<e-select v-model="actionId" maxHeight="300px" :props="selectActionProps" :options="actionList"
							:search="false" :inputClick="false" :clearable="false" @getText="getESelectText"
							@change="selectActionChange"></e-select>
					</view> -->
				</view>

				<view id="map" class="map"></view>

				<view v-show="popupShow" class="popup"
					:style="{ height: popupHeight + 'px', width: popupWidth + 'px' }">
					<uni-section class="section" title="活动路线列表" type="line">
						<template v-slot:right>
							<uni-icons @click="leafletHelper.elListClick(leafletHelper)" type="closeempty"
								size="16"></uni-icons>
						</template>
						<uni-data-picker ref="actionsTree" class="actionsTree" :style="{ width: popupWidth + 'px' }" placeholder="请选择活动路线"
							popup-title="请选择活动路线" :localdata="actionsTree" v-model="sltActRoute" :clear-icon="false"
							@change="onActionChange" @popupopened="onActionsTreePopupOpened"
							@popupclosed="onActionsTreePopupClosed"></uni-data-picker>
					</uni-section>

					<uni-section class="section" :title="'玩家列表 (' + playersNum + '人)'" type="line">
						<view class="norecord" v-if="playersNum == 0">暂无记录</view>
						<scroll-view v-else :scroll-top="0" scroll-y="true" :style="{ height: popupHeight - 122 + '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">
												<!-- <span class="slot-sn" :style="'background-color:' + getPlayerColor(item.id)">{{index+1}}</span> -->
												[{{index+1}}]<span class="slot-phone" @click="onPhoneClick(item.phone)">
													{{item.name}}
													<uni-icons v-if="admin" type="phone" size="14"></uni-icons>
												</span>
												打点 {{item.EffectiveNum}}/{{item.TotalControlNum}} &nbsp; 目标点
												{{item.nextControlPoint.orderNO}} &nbsp; <!-- 百味豆 {{item.sysPoint}} -->
											</view>
											<view class="slot-note">
												距离 {{tools.fmtDistanctKm(item.distance)}}km &nbsp; 配速
												{{tools.convertSecondsToHMS(item.pace, 2)}}
												&nbsp; Cal {{Math.round(item.Calorie/1000)}} &nbsp; 
												 百味豆 {{item.sysPoint}}
												<!-- | &nbsp; 心率 {{item.lastHr}} &nbsp; 平均 {{item.avgHr}} &nbsp; 最大 {{item.maxHr}}-->
												<!-- &nbsp; | &nbsp;  Ck {{item.Ck}} 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>
		</view>
	</view>
</template>

<script>
	import {
		mapState,
		mapGetters
	} from 'vuex';
	import tools from '/utils/tools.js';
	import card from '/utils/card.js';
	import 'leaflet/dist/leaflet.css';
	import '/utils/map/leafletHelper.css'
	import leafletHelper from '/utils/map/leafletHelper';
	import mapHelper from '/utils/map/mapHelper';
	import {
		apiCompInfoDetail,
		apiMapList,
		apiMapDetail,
		apiActionList,
		apiActionDetail,
		apiUsersInGameDetail,
		apiUsersInGameGpsQuery,
		checkResCode
	} from '/utils/api.js';

	export default {
		data() {
			return {
				leafletHelper: leafletHelper,
				tools: tools,
				queryObj: {},
				queryString: "",
				interval_loadActionsTree: null,
				interval_loadData: null,
				actionsTreePopup: false,
				refreshTime_loadData: 3000, // 刷新时间 ms
				refreshTime_loadActionsTree: 10000, // 刷新时间 ms
				admin: true, // 是否场控管理员

				compId: 0, // 赛事ID
				actRs: card.actRs, // 赛事详情

				mapList: [], // 地图列表
				mapId: 0, // (当前选中的)地图ID
				mapDetail: {}, // (当前选中的)地图详情
				mapInfo: {}, // (当前选中的)地图信息 mapDetail.mapInfo
				mapUrl: null, // (当前选中的)地图图片URL
				mapConfig: "", // (当前选中的)地图图片的地理参考信息

				actionList: [], // 活动列表
				actionId: 0, // (当前选中的)活动ID
				actionDetail: {}, // (当前选中的)活动详情
				courseId: 0, // (当前选中的)路线ID

				selectMapProps: {
					value: 'id',
					text: 'name',
					// disabled: 'noallowed'
				},
				selectActionProps: {
					value: 'id',
					text: 'name',
					// disabled: 'noallowed'
				},

				map: null,
				checkPoints: [],
				players: [],
				players_position: [],
				focusPlayerId: 0,
				trailTime: 0,

				sltActRoute: '',
				actionsTree: [],

				popupHeight: 360,
				popupWidth: 0,
				popupType: 'bottom',
				popupShow: false,
			}
		},
		computed: {
			...mapState([
				'username', // 映射 this.username 为 store.state.username
				'userlevel',
				'token'
			]),
			...mapGetters([
				'metadata'
			]),
			playersNum() {
				if (this.players && this.players.length > 0) {
					return this.players.length;
				} else {
					return 0;
				}
			},
			players_position_num() {
				if (this.players_position && this.players_position.length > 0) {
					return this.players_position.length;
				} else {
					return 0;
				}
			},
			players_position_num_text() {
				if (this.players_position_num > 0) {
					return this.players_position_num;
				} else {
					return "";
				}
			}
		},
		async onLoad(query) {
			// console.log(query);
			this.queryObj = query;
			this.queryString = tools.objectToQueryString(this.queryObj);
			// console.log(queryString);
			this.compId = query["compId"] ?? 0;

			this.actRs = await this.compInfoDetail(this.compId);

			this.mapList = await this.getMapList(this.compId);
			this.mapId = this.mapList[0].id;
			
			await this.loadMap();

			// this.actionList = await this.getActionList(this.compId, this.mapId);
			// this.actionId = this.actionList[0].id;

			// this.actionDetail = await this.getActionDetail(this.actionId);

			// console.log("====> mapSltMapId:", this.$store.state.mapSltMapId);
			if (this.mapId == this.$store.state.mapSltMapId) { // 页面重载
				console.log("[onLoad] 页面重载 mapId:", this.mapId);
				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()
				}
			}, that.refreshTime_loadActionsTree);

			// 自动弹出活动路线列表窗口 供用户选择
			leafletHelper.elListClick(leafletHelper);
			this.$refs.actionsTree.show();
		},
		mounted() {
			// console.log("mounted");
			this.$global.getWindowInfo();
			uni.$on('windowResize', this.reLoad);
			this.popupShow = this.$store.state.mapPopupShow;
			this.layoutInit()
		},
		beforeDestroy() {
			console.log("beforeDestroy")
			this.clear();
		},
		methods: {
			clear() {
				if (this.interval_loadActionsTree != null) {
					clearInterval(this.interval_loadActionsTree);
				}
				if (this.interval_loadData != null) {
					clearInterval(this.interval_loadData);
				}
				
				leafletHelper.free();
				uni.$off('windowResize', this.reLoad);
			},
			getBannerStyle() {
				return card.getBannerStyle(this.actRs);
			},
			reLoad() {
				this.clear();
				this.$store.commit('setMapSltMapId', this.mapId)
				this.savePlayersData()

				var fullPath = this.$route.fullPath
				console.log("[windowResize] reLaunch: " + fullPath)
				uni.redirectTo({
					url: fullPath
				});
			},
			// 布局初始化 设置地图高度
			layoutInit() {
				this.popupWidth = this.$global.windowWidth
			},
			popupToggle() {
				this.popupShow = !this.popupShow
				this.$store.commit('setMapPopupShow', this.popupShow)
				// this.layoutInit()
			},
			async loadMap() {
				await this.loadActionsTree();
				/* uni.setNavigationBarTitle({
					title: this.mapDetail.mapInfo.mapName
				}); */
				await mapHelper.handleMapInfo(this, this.mapInfo);
				this.mapUrl = mapHelper.mapUrl;
				this.mapConfig = mapHelper.mapConfig;

				await this.initMap();
				this.handleMapToggle();
			},
			async loadActionsTree() {
				this.mapDetail = await this.getMapDetail(this.compId, this.mapId);
				this.mapInfo = this.mapDetail.mapInfo;
				this.makeActionsTree(this.mapDetail.actSelectRs);
			},
			async initMap() {
				const zoomNum = this.mapInfo.DefScale;
				const mapOptions = {
					zoom: zoomNum
				};
				if (this.mapUrl != undefined && this.mapUrl.length > 0) {
					// console.log("[initMap] mapUrl", this.mapUrl);
					await leafletHelper.init(this, 'map', this.mapUrl, this.mapConfig, mapOptions);
				}
			},
			async loadData(sltActRoute) {
				// console.log("[loadData] sltActRoute: ", sltActRoute);
				if (sltActRoute == null || sltActRoute.length == 0) {
					console.log("[loadData] return: sltActRoute is null ");
					return;
				}
				
				var actRouteArr = sltActRoute[1].value.split('-');
				this.actionId = actRouteArr[0];
				this.courseId = actRouteArr[1];
				
				this.actionDetail = await this.getActionDetail(this.actionId, this.courseId);
				/* uni.setNavigationBarTitle({
					title: this.mapDetail.mapinfo.mapname + ' - ' + this.actionDetail.name
				}); */
				
				if (this.interval_loadData != null) {
					clearInterval(this.interval_loadData);
				}

				this.players = await this.getUsersInGameDetail();
				// console.log('players', this.players)
				// leafletHelper.global.setPlayers(this.players)

				this.players_position = await this.usersInGameGpsQuery();
				// leafletHelper.global.setPlayersPosition(this.players_position)
				
				this.handleMapDrawRoute();
				this.handleMapDrawPlayer();
				this.handleMapDrawTrail();
				
				let that = this;
				this.interval_loadData = setInterval(async function() {
					that.players = await that.getUsersInGameDetail();
					that.players_position = await that.usersInGameGpsQuery();
					//// leaflet.leafletHelper.global.setPlayers(that.players);
					// leafletHelper.global.setPlayersPosition(that.players_position);
					that.handleMapDrawPlayer();
					that.handleMapDrawTrail();
				}, that.refreshTime_loadData);

				// await mapHelper.handleMapInfo(this, this.mapInfo)
				// this.handleMapToggle(); // to del
			},
			handleWindowResize() {
				leafletHelper.onWindowResize()
			},
			handleMapDrawRoute() {
				// console.log("this.actionDetail.routes", this.actionDetail.routes);
				// leafletHelper.global.setCheckPoints(this.checkPoints)
				leafletHelper.global.setRoutes(this.actionDetail.routes)

				// 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.global.dealStaleData()
			},
			handleMapDrawTrail() {
				this.trailTime = leafletHelper.config.trailTime
				// leafletHelper.player.drawOneTrail(2, 10000)
				// leafletHelper.player.drawOneTrail(2, 0, false)
				leafletHelper.player.drawAllTrails(this.trailTime)
			},
			handleMapToggle() {
				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()
			},
			// 自助赛事详情查询
			async compInfoDetail(compId) {
				try {
					return new Promise((resolve, reject) => {
						uni.request({
							url: apiCompInfoDetail,
							header: this.metadata,
							method: "POST",
							data: {
								compId: compId
							},
							success: (res) => {
								// console.log("[compInfoDetail] res", res);
								if (checkResCode(res)) {
									const data = res.data.data;
									resolve(data);									
								}
							},
							fail: (err) => {
								console.log("[compInfoDetail] err", err);
								reject(err);
							},
						});
					});
				} catch (e) {
					console.log('[compInfoDetail] err', e)
					reject(e)
				}
			},
			// 自助赛事详情查询
			async getMapList(compId) {
				try {
					return new Promise((resolve, reject) => {
						uni.request({
							url: apiMapList,
							header: this.metadata,
							method: "POST",
							data: {
								compId: compId
							},
							success: (res) => {
								// console.log("[getMapList] res", res);
								if (checkResCode(res)) {
									const data = res.data.data;
									resolve(data.list);
								} else {
									reject(res);
								}
							},
							fail: (err) => {
								console.log("[getMapList] err", err);
								reject(err);
							},
						});
					});
				} catch (e) {
					console.log('[getMapList] err', e)
					reject(e)
				}
			},
			// 赛事监控地图详情
			async getMapDetail(compId, mapId) {
				try {
					return new Promise((resolve, reject) => {
						uni.request({
							url: apiMapDetail,
							header: this.metadata,
							method: "POST",
							data: {
								compId: compId,
								mapId: mapId
							},
							success: (res) => {
								// console.log("[getMapDetail] res", res);
								if (checkResCode(res)) {
									const data = res.data.data;
									resolve(data);
								} else {
									reject(res);
								}
							},
							fail: (err) => {
								console.log("[getMapDetail] err", err);
								reject(err);
							},
						});
					});
				} catch (e) {
					console.log('[getMapDetail] err', e)
					reject(e)
				}
			},
			// 赛事监控地图下的活动列表
			async getActionList(compId, mapId) {
				try {
					return new Promise((resolve, reject) => {
						uni.request({
							url: apiActionList,
							header: this.metadata,
							method: "POST",
							data: {
								compId: compId,
								mapId: mapId
							},
							success: (res) => {
								// console.log("[getActionList] res", res);
								if (checkResCode(res)) {
									const data = res.data.data;
									resolve(data.list);
								}
							},
							fail: (err) => {
								console.log("[getActionList] err", err);
								reject(err);
							},
						});
					});
				} catch (e) {
					console.log('[getActionList] err', e)
					reject(e)
				}
			},
			// 赛事监控地图下的活动详情
			async getActionDetail(actionId, courseId) {
				try {
					return new Promise((resolve, reject) => {
						uni.request({
							url: apiActionDetail,
							header: this.metadata,
							method: "POST",
							data: {
								actId: actionId,
								courseId: courseId
							},
							success: (res) => {
								// console.log("[getActionDetail] res", res);
								if (checkResCode(res)) {
									const data = res.data.data;
									resolve(data);
								}
							},
							fail: (err) => {
								console.log("[getActionDetail] err", err);
								reject(err);
							},
						});
					});
				} catch (e) {
					console.log('[getActionDetail] err', e)
					reject(e)
				}
			},
			//场控端_正在进行中所有用户实时信息
			async getUsersInGameDetail() {
				try {
					return new Promise((resolve, reject) => {
						uni.request({
							url: apiUsersInGameDetail,
							header: this.metadata,
							method: "POST",
							data: {
								actId: this.actionId,
								courseId: this.courseId
							},
							success: (res) => {
								// console.log("[getUsersInGameDetail] res", res);
								if (checkResCode(res)) {
									resolve(res.data.data.users);
								} else {
									reject(res);
								}
							},
							fail: (err) => {
								console.log("[getUsersInGameDetail] err", err);
								reject(err);
							},
						});
					});
				} catch (e) {
					console.log('[getUsersInGameDetail] err', e)
					reject(e)
				}
			},
			//场控端_正在进行中所有用户实时gps查询
			async usersInGameGpsQuery() {
				try {
					return new Promise((resolve, reject) => {
						uni.request({
							url: apiUsersInGameGpsQuery,
							header: this.metadata,
							method: "POST",
							data: {
								actId: this.actionId,
								courseId: this.courseId
							},
							success: (res) => {
								// console.log("[usersInGameGpsQuery] res", res);
								if (checkResCode(res)) {
									resolve(res.data.data.gpsInfo);
								} else {
									reject(res);
								}
							},
							fail: (err) => {
								console.log("[usersInGameGpsQuery] err", err);
								reject(err);
							},
						});
					});
				} catch (e) {
					console.log('[usersInGameGpsQuery] err', e)
					reject(e)
				}
			},
			makeActionsTree(actSelectRs) {
				this.actionsTree.length = 0 // 先清空数组
				for (let i = 0; i < actSelectRs.length; i++) {
					var act = actSelectRs[i]
					var pushData = {
						text: act.actName,
						value: act.actId,
						children: []
					}

					var actUserNum = 0
					for (let j = 0; j < act.courseSelectRs.length; j++) {
						var course = act.courseSelectRs[j]
						const courseUserNum = course.courseUserNum > 0 ? course.courseUserNum : 0
						actUserNum += courseUserNum
						pushData.children.push({
							text: course.courseName + ' (' + 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))
			},
			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 (!this.admin) {
					return;
				}
				if (phoneNumber.length == 11) {
					uni.makePhoneCall({
						phoneNumber: phoneNumber
					})
				} else {
					uni.showToast({
						title: '手机号码不正确',
						icon: 'none'
					})
				}
			},
			fullScreenToggle() {
				this.$global.fullscreen();
				// this.layoutInit();
			},
			// 获取输入框中值
			getESelectText(data) {
				// console.log("getESelectText:", data);
			},
			async selectMapChange(data) {
				// console.log("selectMapChange:", data);
				this.mapId = data.id;
				await loadActionsTree();
				
				this.actionList = await this.getActionList(this.compId, this.mapId);
				this.actionId = this.actionList[0].id;
			},
			/* async selectActionChange(data) {
				// console.log("selectActionChange:", data);
				this.actionId = data.id;
				this.actionDetail = await this.getActionDetail(this.actionId);
			}, */
			btnBack() {
				this.clear();
				const url = "/pages/actManage/actDetail?" + this.queryString;
				tools.appAction(url, "uni.navigateTo");
			},
		}
	}
</script>

<style scoped>
	.content {
		height: 100vh;
	}

	.top {
		height: 36px;
		padding-top: 16px;
		flex-shrink: 0;
		background-repeat: no-repeat;
		background-size: cover;
	}

	.selectBox {
		width: 100%;
		margin-top: 5px;
		margin-bottom: 5px;
	}

	.select {
		/* width: 48%; */
		width: 96%;
	}

	.map {
		width: 100%;
		flex: 1 1 auto;
		background-color: white;
		z-index: 0;
	}

	.popup {
		display: flex;
		height: 30vh;
		overflow: scroll;
		flex-direction: column;
		align-items: center;
		background-color: #ffffff;
		border-top: #dedede solid 1px;
	}

	.section {
		width: 100%;
	}

	.actionsTree {
	}
	
	/deep/ .input-value-border {
	    border-top: 1px solid #e5e5e5;
	    border-bottom: 1px solid #e5e5e5;
		border-left: 0;
		border-right: 0;
	    border-radius: 0px;
	}
	
	/deep/ .uni-scroll-view {
	    overflow: unset !important;
	}
	
	/deep/ .uni-section-header {
		padding-right: 7px !important;
	}

	.section-title {
		font-size: 14px;
		color: #424242;
		line-height: 20px;
		padding: 10px 0 10px 10px;
	}

	.section-content {
		width: 100%;
		height: 100%;
	}

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

	.list-item {
		display: flex;
		flex-direction: row;
		align-items: center;
		height: 46px;
	}

	.slot-box {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		width: 330px;
		max-width: 350px;
	}

	.slot-image {
		display: block;
		margin-right: 6px;
		width: 3px;
		height: 33px;
		align-self: center;
	}

	.slot-title {
		flex: 1;
		font-size: 13px;
		color: #424242;
		line-height: 18px;
		/* white-space: nowrap; */
	}

	.slot-sn {
		display: inline-flex;
		width: 15px;
		height: 15px;
		border-radius: 50%;
	}

	.slot-note {
		flex: 1;
		margin-left: 25px;
		font-size: 12px;
		color: #7d8da7;
		line-height: 18px;
		white-space: nowrap;
	}

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

	.norecord {
		font-weight: 500;
		color: #818181;
		font-size: 14px;
		text-align: center;
		line-height: 50px;
	}

</style>