<template>
	<view class="container" @click="showSearch(false)">
		<view id="map" class="map" :prop="mapData" :change:prop="mapModule.updateMapData"></view>
		<!-- <image-button @click="location" className="location" imgSrc="/static/dw.png"></image-button> -->

		<view class="south" :style="'transform:rotate('+compassNum.toString()+'deg)'">
			<image src="/static/south.png" class="south-img" />
			<text class="south-text" style="transform:rotate(180deg)">南</text>
		</view>
		<view class="right-actions">
			<view class="btn-tcdj right-btn" @click="showLayerModal">
				<image src="/static/tcdj.png" class="btn-img"></image>
			</view>
			<view class="btn-mjcl right-btn" @click="toggleMeasure">
				<image :src="measureStatus==='mjcl'?'/static/mjcl-sel.png':'/static/mjcl.png'" class="btn-img"></image>
			</view>
			<view class="btn-xzgj right-btn" @click="toggleXzgj">
				<image :src="measureStatus==='xzgj'?'/static/xzgj-sel.png':'/static/xzgj.png'" class="btn-img"></image>
			</view>
			<view class="btn-location right-btn" @click="location">
				<image src="/static/dw.png" class="img-location" />
			</view>
			<view class="btn-clear right-btn" @click="mapModule.clear">
				<image src="/static/clear.png" class="img-clear" />
			</view>
			<!-- <view class="btn-logout right-btn" @click="logout">
				<image src="/static/logout.png" class="img-logout" />
			</view> -->
		</view>
		<button class="btn-workbench" @click="toWorkBench">
			<image src="/static/gzt.png" class="workbench-img" />
			<div>工作台</div>
		</button>
		<view>
			<!-- 普通弹窗 -->
			<uni-popup ref="popup" background-color="#fff" @change="popupChange">
				<view class="popup-title">图层叠加</view>
				<view class="popup-content uni-flex uni-row" style="align-items: center;justify-content: center;">
					<view class="uni-flex uni-row" style="justify-content: space-around;flex:1;">
						<layer-checkbox v-for="item in layerItems" :icon="item.icon" :label="item.text"
							:value="item.value" @change="checkLayer"
							:checked="currentLayers.indexOf(item.value)>-1"></layer-checkbox>
					</view>
				</view>
			</uni-popup>
			<!-- 普通弹窗 -->
			<uni-popup ref="popupDetail" background-color="#fff">
				<view class="popup-detail-title">
					<text
						style="flex:1;font-size: 18px; font-weight: bold;">{{currentClickLayerItem?currentClickLayerItem.text:''}}详情</text>
					<text @click="closeDetail()" style="font-size: 16px;color: #555; padding-bottom: 4px;">关闭</text>
				</view>
				<view class="popup-content" style="padding: 12px;">
					<view class="detail-tab">
						<view v-if="detailGroups.length>1" v-for="groupItem in detailGroups"
							style="margin-bottom: 8px;margin-right: 8px;">
							<uni-tag :circle="true" @click="changeDetailTab(groupItem.tab)" :text="groupItem.tab"
								:type="currentGroupTab===groupItem.tab?'success':''"></uni-tag>
						</view>
					</view>

					<view v-if="!!currentGroupTab" style="border: 0.5px solid rgba(5, 5, 5, 0.1);">
						<view v-for="item in detailGroups.find(g=>g.tab===currentGroupTab).children">
							<view class="uni-flex uni-row">
								<view
									style="display: flex;align-items: center; width:30%;padding: 2px 4px;background-color: rgba(0, 0, 0, 0.02);border: 0.5px solid rgba(5, 5, 5, 0.1);">
									<text style="color: #666;">{{item.title}}</text>
								</view>
								<view
									style="display: flex;align-items: center;width:70%;padding: 2px 8px;border: 0.5px solid rgba(5, 5, 5, 0.1);">
									<text
										v-if="!item.value.toString().endsWith('.png')&&!item.value.toString().endsWith('.jpg')"
										style="color: #222;">{{item.value}}{{item.unit}}</text>
									<view
										v-if="item.value.toString().endsWith('.png')||item.value.toString().endsWith('.jpg')">
										<image v-for="(img,index) in item.value.split(',')"
											style="height: 36px; width: 36px;margin-right: 8px;" :src="img"
											@click="preview(index,item.value.split(','))">
										</image>
									</view>
								</view>
							</view>
						</view>
					</view>
				</view>
			</uni-popup>
		</view>
		<view class="top-right">
			<view @click.stop="showSearch(true)" v-if="searchVisible" style="flex: 1;">
				<uni-search-bar :focus="true" v-model="searchValue" @confirm="search"
					cancelButton="none"></uni-search-bar>
			</view>
			<!-- <view class="search" @click.stop="showSearch(true)" v-if="!searchVisible">
				<image src="/static/search.png" class="img-search" />
			</view> -->
			<view class="message" @click="toWdxx">
				<image src="/static/message.png" class="img-message" />
			</view>
		</view>
	</view>
</template>

<script>
	import helper from '../../common/helper';
	import {
		GeoJSON
	} from 'ol/format'
	import _ from 'lodash'
	export default {
		data() {
			return {
				searchVisible: false,
				searchValue: '',
				mapData: {
					center: [102.45438, 32.53223]
				},
				currentLayers: [],
				currentLayer: null,
				layerItems: [{
					text: '生态修复工程',
					value: 'stxfgc',
					icon: 'stxfgc',
					zIndex: 99,
					detailUrl: '/stxh/appDetails'
				}, {
					text: '征占用',
					value: 'cdzzy_view',
					icon: 'zzy',
					zIndex: 88,
					detailUrl: '/cdzhy/appDetails'
				}, {
					text: '非法占用',
					value: 'ffzy_layer',
					icon: 'ffzy',
					zIndex: 77,
					detailUrl: '/cdzhy/appFfzyDetails'
				}, {
					text: '草地',
					value: 't_grassland_result',
					icon: 'cd',
					zIndex: 66,
					detailUrl: '/cdzy/appDetails'
				}],
				detailItems: [],
				detailGroups: [],
				currentGroupTab: null,
				token: '',
				measureStatus: '',
				currentClickLayerItem: null,
				xzgjPoints: [],
				compassNum: 0
			}
		},
		watch: {
			currentLayers(newVal, oldVal) {
				const map = this.$map;
				console.log(newVal, oldVal, map);
				if (newVal) {
					this.mapData = {
						layerOpts: newVal?.map(val => {
							const item = this.layerItems.find(l => l.value === val);
							return {
								layerName: val,
								...item
							}
						})
					}

				}
			}
		},
		onLoad() {
			this.token = helper.tempToken;
			let testIndex = 0;
			const settings = uni.getAppAuthorizeSetting()
			console.log(settings)
			uni.onLocationChange(res => {
				let {
					longitude,
					latitude,
					isFullAccuracy
				} = res;
				console.log(res)
				// longitude = longitude + 0.01 * testIndex * (testIndex % 2 ? 1 : -1);
				// latitude = latitude + 0.01 * testIndex * (testIndex % 2 ? 1 : -1);
				// ++testIndex;
				if (!this.xzgjPoints.find(point => {
						return point[0] === longitude && point[1] === latitude;
					})) {
					this.xzgjPoints.push([longitude, latitude]);
				}
				console.log(this.xzgjPoints)
				this.mapData = {
					xzgjPoints: this.xzgjPoints
				}
			})

			this.compassHandler = res => {
				console.log(res)
				this.compassNum = res.direction;
			}
			uni.onCompassChange(this.compassHandler);
		},
		onShow() {
			uni.startCompass()
		},
		onHide() {
			uni.stopCompass();
		},
		methods: {
			checkLayer(value) {
				const index = this.currentLayers.findIndex(l => l === value);
				if (index > -1) {
					this.currentLayers.splice(index, 1);
				} else {
					this.currentLayers.push(value)
				}
			},
			closeMeasureStatus() {
				this.measureStatus = ''
				this.mapData = {}
			},
			toggleXzgj() {
				if (this.measureStatus === 'xzgj') {
					this.measureStatus = ''
					this.mapData = {}
					uni.stopLocationUpdate();
				} else {
					this.measureStatus = 'xzgj';
					this.xzgjPoints = []
					uni.startLocationUpdate({
						// type: 'gcj02',
						needFullAccuracy: true
					})
					this.mapData = {
						xzgj: true
					}
				}
			},
			toggleMeasure() {
				if (this.measureStatus === 'mjcl') {
					this.measureStatus = ''
					this.mapData = {}
				} else {
					this.measureStatus = 'mjcl'
					this.mapData = {
						mjcl: true
					}
					uni.stopLocationUpdate();
				}
			},
			showFfzy(id) {
				console.log(id)
				if (!this.currentLayers.find(l => l === 'ffzy_layer')) {
					this.currentLayers.push('ffzy_layer')
				}
				uni.request({
					url: `${helper.serverUrl}/ffzy/ffzy/${id}`,
					header: {
						Authorization: `Bearer ${this.token}`
					},
					success: (resp) => {
						console.log(resp)
						if (resp.data.data) {
							const item = resp.data.data;
							if (item.geom) {
								this.mapData = {
									ffzyWkt: item.geom
								}
							}
						}
					},
				})
			},
			toWdxx() {
				uni.navigateTo({
					url: "/pages/wdxx/wdxx"
				})
			},
			preview(index, imgs) {
				uni.previewImage({
					urls: imgs,
					current: index
				})
			},
			changeDetailTab(tabName) {
				this.currentGroupTab = tabName;
			},
			closeDetail() {
				this.$refs.popupDetail.close()
			},
			showSearch(visible) {
				this.searchVisible = visible;
			},
			clear(res) {
				this.searchValue = '';
			},
			search(res) {
				console.log('查询值：' + res.value);
			},
			location() {
				uni.getLocation({
					type: 'gcj02',
					success: (res) => {
						console.log('当前位置的经度：' + res.longitude);
						console.log('当前位置的纬度：' + res.latitude);
						this.mapData = {
							center: [res.longitude, res.latitude, Math.random()]
						}
					}
				});
			},
			toWorkBench() {
				uni.navigateTo({
					url: '/pages/workbench/workbench',
					success(a) {
						debugger
					},
					fail(a) {
						debugger
					}
				})
			},
			popupChange(e) {
				console.log('当前模式：' + e.type + ',状态：' + e.show);
			},
			showLayerModal() {
				this.$refs.popup.open('bottom')
			},
			_request(index, wkt, apis, callback) {
				if (apis[index]) {
					uni.request({
						url: `${helper.mgServerUrl}${apis[index]}?wkt=${wkt}`,
						success: (resp2) => {
							console.log(resp2)
							if (resp2?.data?.data?.dyColumn?.length > 0) {
								const layerItem = this.layerItems.find(item => item.detailUrl === apis[index]);
								this.currentClickLayerItem = layerItem;
								callback(resp2?.data?.data, layerItem)
							} else {
								this._request(++index, wkt, apis, callback)
							}
						}
					})
				} else {
					callback();
				}
			},
			requestDetail({
				wkt
			}) {
				// if (resp?.data?.features?.[0]) {
				// 	this.mapData = {
				// 		highLightData: resp?.data?.features?.[0]
				// 	}

				// }
				const apis = [];
				this.layerItems.forEach(item => {
					const layerStr = this.currentLayers.find(l => l === item.value);
					if (layerStr) {
						apis.push(item.detailUrl);
					}
				});
				this._request(0, wkt, apis, (resp) => {
					if (resp) {
						if (resp.geom) {
							this.mapData = {
								highLightWkt: resp.geom
							}

						}
						const groups = _.groupBy(resp.dyColumn, 'tab');
						this.detailGroups = _.keys(groups).map(key => {
							return {
								tab: key,
								children: groups[key]?.map(item => {
									return {
										...item,
										value: item.value || ''
									}
								})
							}
						});
						this.currentGroupTab = this.detailGroups?.[0]?.tab;
						this.$refs.popupDetail.open('bottom');

					}
				});
			}
		}
	}
</script>

<script module="mapModule" lang="renderjs">
	import 'ol/ol.css'
	import {
		Map,
		View
	} from 'ol'
	import {
		get as getProjection
	} from 'ol/proj';
	import {
		Tile as TileLayer,
		Vector as VectorLayer
	} from 'ol/layer'
	import {
		XYZ,
		Vector as VectorSource
	} from 'ol/source'
	import {
		Point,
		Polygon,
		Circle,
		LineString
	} from 'ol/geom'
	import {
		fromExtent,
		fromCircle
	} from 'ol/geom/Polygon';
	import Feature from 'ol/Feature';
	import {
		Style,
		Icon as IconStyle,
		Circle as CircleStyle,
		Fill,
		Stroke,
		Text as TextStyle
	} from 'ol/style'
	import helper from '../../common/helper';
	import {
		Image
	} from 'ol/layer';
	import {
		ImageWMS
	} from 'ol/source';
	import {
		GeoJSON,
		WKT
	} from 'ol/format'
	import {
		getForViewAndSize
	} from 'ol/extent';
	let map, vectorLayer;
	export default {
		name: 'c-ol-map',
		data() {
			return {
				ownerInstance: null
			}
		},
		mounted(args) {
			console.log(args)
			this.initMap()
		},
		methods: {
			updateMapData(newValue, oldValue, ownerInstance, instance) {
				this.ownerInstance = ownerInstance;
				// 监听 service 层数据变更
				if (map) {
					if (newValue.center) {
						const point = new Point([newValue.center[0], newValue.center[1]]);
						const pFeature = new Feature({
							geometry: point
						});
						pFeature.setStyle(new Style({
							image: new IconStyle({
								src: './static/wz.png',
								scale: 0.5,
								anchor: [0.5, 0]
							})
						}))
						vectorLayer.getSource().clear();
						vectorLayer.getSource().addFeature(pFeature);
						map.getView().fit(point, {
							maxZoom: 16
						});
					}
					if (newValue.layerOpts) {
						const businessLayers = map.getAllLayers().filter(l => {
							return l.get('businessId') === 'business-layer';
						}) || []
						const layers = newValue.layerOpts.map(opt => {
							let layer = businessLayers.find(l => {
								return l.get('businessName') === opt.layerName;
							})
							if (!layer) {
								layer = new Image({
									businessId: 'business-layer',
									businessName: opt.layerName,
									source: new ImageWMS({
										ratio: 1,
										url: `${helper.geoserverUrl}/geoserver/yzt/wms`,
										params: {
											'FORMAT': 'image/png',
											'VERSION': '1.1.1',
											"STYLES": '',
											"LAYERS": `yzt:${opt.layerName}`,
											"exceptions": 'application/vnd.ogc.se_inimage',
										}
									}),
									zIndex: opt.zIndex
								});
								businessLayers.push(layer);
								map.addLayer(layer);
							} else {
								layer.setVisible(true)
							}
							return layer;
						})
						vectorLayer.getSource().clear();
						businessLayers.forEach(layer => {
							const index = newValue.layerOpts.findIndex(opt => opt.layerName === layer.get(
								'businessName'));
							if (index === -1) {
								layer.setVisible(false);
							}
						})
					}
					if (newValue.highLightWkt) {
						const feature = new WKT().readFeature(newValue.highLightWkt)
						feature.setStyle(new Style({
							fill: new Fill({
								color: 'rgba(0,0,0,0)',
							}),
							stroke: new Stroke({
								width: 3,
								color: '#ff0000'
							}),
							image: new CircleStyle({
								radius: 8,
								fill: new Fill({
									color: 'rgba(0,0,0,0)',
								}),
								stroke: new Stroke({
									width: 3,
									color: '#00ffff'
								}),
							})
						}));
						vectorLayer.getSource().clear();
						vectorLayer.getSource().addFeature(feature)
					}
					if (newValue.ffzyWkt) {
						const point = new WKT().readGeometry(newValue.ffzyWkt);
						const coordinate = point.getCoordinates();
						map.getView().setCenter(coordinate)
						this.showByWkt(coordinate)
					}
					if (newValue.mjcl) {
						helper.startMeasure(map, () => {
							this.ownerInstance?.callMethod('closeMeasureStatus', false)
						})
					}
					if (newValue.xzgjPoints) {
						this.clear();
						if (newValue.xzgjPoints.length === 1) {
							const point = new Point(newValue.xzgjPoints[0]);
							const feature = new Feature({
								geometry: point
							})
							const style = new Style({
								image: new CircleStyle({
									fill: new Fill({
										color: '#0ff'
									}),
									radius: 8
								})
							})
							feature.setStyle(style);
							vectorLayer.getSource().addFeature(feature)
							map.getView().setCenter(newValue.xzgjPoints[0])
						} else if (newValue.xzgjPoints.length === 2) {
							const line = new LineString(newValue.xzgjPoints);
							const feature = new Feature({
								geometry: line
							})
							const style = helper.generateStyle(feature, {
								fillOpt: {
									color: 'rgba(255, 255, 255, 0.4)',
								},
								strokeOpt: {
									color: '#ffcc33',
									width: 2,
								}
							})
							feature.setStyle(style);
							vectorLayer.getSource().addFeature(feature)
							const geom = line.clone();
							geom.scale(2, 2)
							map.getView().fit(geom)
						} else if (newValue.xzgjPoints.length >= 3) {
							const polygon = new Polygon([
								[...newValue.xzgjPoints, newValue.xzgjPoints[0]]
							]);
							const feature = new Feature({
								geometry: polygon
							})
							const style = helper.generateStyle(feature, {
								fillOpt: {
									color: 'rgba(255, 255, 255, 0.4)',
								},
								strokeOpt: {
									color: '#ffcc33',
									width: 2,
								},
								withNode: true
							})
							feature.setStyle(style);
							vectorLayer.getSource().addFeature(feature)
							const geom = polygon.clone();
							geom.scale(2, 2)
							map.getView().fit(geom)
						}
					}
				}
			},
			clear() {
				if (map) {
					map.removeLayer(map.getAllLayers().find(l => l.get('id') === 'draw-layer'));
					vectorLayer.getSource().clear();
				}
			},
			// 初始化天地图
			initMap() {
				let that = this
				//天地图影像
				var tdt = new TileLayer({
					source: new XYZ({
						maxZoom: 16,
						url: "https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
						// url: 'http://t{0-5}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=cef191b507ff5cb698811cd8a9b11ca0',
						projection: 'EPSG:3857',
						crossOrigin: '*',
					}),
				})
				//天地图标注
				// var tdtLabel = new TileLayer({
				// 	source: new XYZ({
				// 		maxZoom: 18,
				// 		url: 'http://t{0-5}.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=cef191b507ff5cb698811cd8a9b11ca0',
				// 		projection: 'EPSG:3857',
				// 	}),
				// })
				map = new Map({
					controls: [],
					target: 'map',
					layers: [tdt],
					view: new View({
						projection: 'EPSG:4326',
						center: [102.45438, 32.53223],
						// center: [102.712251, 25.040609],
						zoom: 12,

						enableRotation: false
					}),
				})
				vectorLayer = new VectorLayer({
					id: 'v-layer',
					source: new VectorSource(),
					zIndex: 999
				})
				map.addLayer(vectorLayer);
				map.on('singleclick', evt => {
					vectorLayer.getSource().clear();
					console.log('evt', evt)
					this.showByWkt(evt.coordinate);
				})
			},
			showByWkt(coordinate) {
				// const source = map.getAllLayers().find(l => l.get('id') === 'business-layer')?.getSource();
				// if (source) {
				const view = map.getView();
				const viewResolution = view.getResolution();
				const [x1] = map.getCoordinateFromPixel([0, 0]);
				const [x2] = map.getCoordinateFromPixel([10, 0]);
				const radius = x2 - x1;
				const circle = new Circle(coordinate, radius);
				const polygon = fromCircle(circle);
				const wkt = new WKT().writeGeometry(polygon);
				// const url = source.getFeatureInfoUrl(
				// 	coordinate, viewResolution, view.getProjection(), {
				// 		'INFO_FORMAT': 'application/json',
				// 		'FEATURE_COUNT': 50
				// 	});
				this.ownerInstance?.callMethod('requestDetail', {
					wkt: wkt
				})
				// }
			}
		}
	}
</script>

<style scoped>
	.detail-tab {
		display: flex;
		flex-direction: row;
		overflow-x: auto;
		/* margin-bottom: 12px; */
		padding-bottom: 12px;
		flex-wrap: wrap;
	}

	.popup-detail-title {
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 12px;
		border-bottom: 1px solid #ddd;
	}

	.logout {}

	.search {
		margin-right: 24px;
	}

	.btn-logout {
		margin-top: 12px;
		border-radius: 10px;
	}

	.img-clear,
	.img-logout {
		opacity: 0.6;
	}

	.img-clear,
	.img-logout,
	.img-message,
	.img-search,
	.img-location {
		width: 30px;
		height: 30px;
	}

	.top-right {
		position: absolute;
		top: 40px;
		right: 28px;
		display: flex;
		align-items: center;
		left: 10px;
		justify-content: end;
		height: 56px;
	}

	.popup-title {
		font-weight: bold;
		font-size: 22px;
		text-align: center;
		margin: 24px 0 0 0;
	}

	.popup-content {
		padding: 24px;
	}

	.container>>>.checklist-box {
		margin-right: 0 !important;
	}

	.container>>>.checklist-group {
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.container>>>.checklist-content {
		width: 70vw;
		height: 32px;
	}

	.btn-img {
		width: 26px;
		height: 26px;
	}

	.right-btn {
		width: 48px;
		height: 48px;
		background-color: #fff;
		display: flex;
		align-items: center;
		padding: 0;
		justify-content: center;
	}

	.btn-location {
		border-top-left-radius: 10px;
		border-top-right-radius: 10px;
		border-bottom: 1px solid #ddd;
		margin-top: 12px;
	}

	.btn-clear {
		border-bottom-left-radius: 10px;
		border-bottom-right-radius: 10px;
	}

	.btn-tcdj {
		border-top-left-radius: 10px;
		border-top-right-radius: 10px;
		border-bottom: 1px solid #ddd;
	}

	.btn-mjcl {
		border-bottom: 1px solid #ddd;
	}

	.btn-xzgj {
		border-bottom-left-radius: 10px;
		border-bottom-right-radius: 10px;
	}

	.right-actions {
		position: absolute;
		top: 100px;
		right: 20px;
	}

	.map {
		height: 100vh;
	}

	.location {
		position: absolute;
		top: 100px;
		left: 20px;
	}

	.south {
		position: absolute;
		top: 100px;
		left: 20px;
		width: 48px;
		height: 48px;
		border-radius: 50%;
		padding: 0;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.south-img {
		position: absolute;
		top: 0;
		left: -5px;
		width: 60px;
		height: 60px;

	}

	.south-text {
		z-index: 1;
		font-weight: bold;
		font-size: 17px;
		margin-top: 8px;
	}

	.btn-workbench {
		width: 80px;
		height: 80px;
		border-radius: 80px;
		display: flex;
		flex-direction: column;
		align-items: center;
		padding: 0;
		justify-content: center;
		position: absolute;
		bottom: 20px;
		right: 20px;
		background: linear-gradient(0deg, #02C3AF, #00D883);
		color: #fff;
		/* height: 24px; */
		line-height: 24px;
		/* font-size: 16px; */
	}

	.workbench-img {
		width: 30px;
		height: 30px;
	}
</style>