<script setup lang="ts">
import SceneViewer from "@/components/SceneViewer.vue";
import BottomBar from "@/components/BottomBar.vue";
import {ArrowBackOutline,ArrowForwardOutline,Save,Add, SaveOutline} from "@vicons/ionicons5";
import {nextTick, onBeforeUnmount, onMounted, ref} from "vue";
import {darkTheme, useMessage} from "naive-ui";
import {route,route2,route3} from "@/assets/js/testData.ts";
import {useRouteStore} from "@/store/RouteStore.ts";
import {Airline} from "@/types/entityoptions.ts";
import {newAirline, newAirlinePt} from "@/assets/js/TypeInitial.ts";
import * as echarts from "echarts";
import {EChartsType} from "echarts";
import {transLonlat2Car3} from "@/utils/map/geocomputation.ts";
import {drawEcharts_RouteDetection, profileAnalyse} from "@/utils/map/SpatialAnalysis.ts";
import RouteManageViewer from "@/assets/js/RouteManageViewer.js";
import {query_surface_forecast, query_upper_forecast, requireWeatherLevel} from "@/assets/js/weatherRequest.ts";
import {setChartOptions} from "@/assets/js/weatherCharts.ts";
import type { NotificationType } from 'naive-ui'
import { useNotification } from 'naive-ui'

let myChart: EChartsType = undefined
let weatherChart: EChartsType = undefined
let routeStore = useRouteStore()
let selectedRouteCode = ref(null)
let selectedLevel = ref(null)
let showPtList = ref(true)
let selectedRoute = ref<Airline>(newAirline())
let routesInstore = ref<{ value: string|number; label: string}[]>(null)
let routeViewer = null
let routePtNumber = ref(1)
let uiMsg = useMessage()
let nowTime = ref('')
let timer = null
let PtOptions =  [
	{label: '删除航点', key: 'deletePt'},
	{label: '插入航点', key: 'insertPt'},
]
let routeCode = [
	{
		label: "任务航线1",
		value: 1,
	},{
		label: "任务航线2",
		value: 2,
	},{
		label: "任务航线3",
		value: 3,
	},{
		label: "任务航线4",
		value: 4,
	},{
		label: "任务航线5",
		value: 5,
	}
]
let levelOptions = ref<any[]>()
const notification = useNotification()
const notify = (type: NotificationType, title: string, detail: string) =>{
	notification[type]({
		title: title,
		meta: detail,
		duration: 3000,
		closable: true,
		keepAliveOnHover: true
	})
}
onBeforeUnmount(()=>{
	clearInterval(timer)
})
onMounted(()=>{
	routeViewer = new RouteManageViewer(window.viewer)
	myChart = echarts.init(document.getElementById('echarts-profile'),'dark')
	weatherChart = echarts.init(document.getElementById('weatherChart'),'dark')

	timer = setInterval(getTimesInterval, 1000);

	routeStore.addRoute(route)
	routeStore.addRoute(route2)
	routeStore.addRoute(route3)

	routesInstore.value = routeStore.flyRoute.map((route)=> {
		return {
			value: route.unicode,
			label: route.name
		}
	})
	requireWeatherLevel().then(res=>{
		console.log(res)
		// 查询失败
		if(!res.data.success){
			notify('error', '气象信息查询失败', res.data.message)
			return
		}
		levelOptions.value = res.data.data.levelsAvailableList[0].pressureLevels.map((level,index)=>{
			return {
				value: level,
				label: level+'hPa/ '+ res.data.data.levelsAvailableList[0].heightLevels[index] + 'm'
			}
		})
		levelOptions.value.reverse()
		levelOptions.value.unshift({value: -1, label: '地面'})
		selectedLevel.value = -1
	})
})


function getTimesInterval() {
	let now = new Date();
	let year = now.getFullYear(); // 年
	let month = (now.getMonth() + 1).toString().padStart(2, '0'); // 月
	let day = now.getDate().toString().padStart(2, '0'); // 日
	let hours = now.getHours().toString().padStart(2, '0'); // 时
	let minutes = now.getMinutes().toString().padStart(2, '0'); // 分
	let seconds = now.getSeconds().toString().padStart(2, '0'); // 秒

// 格式化时间
	nowTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

// 航线选择回调
function checkRoute(key:number|string){
	new Promise((resolve,reject)=>{
		selectedRoute.value = routeStore.flyRoute.filter(element => element.unicode === String(key))[0]
		if(selectedRoute.value == null) 	reject('未找到航线')
		routeViewer.routeParams.isClose =  selectedRoute.value.isClose
		window.viewer.flyTo(routeViewer.addAirLine(selectedRoute.value), {duration: 2})
		queryWeather(selectedRoute.value.points[0].lon,selectedRoute.value.points[0].lat)
		setTimeout(()=>resolve('success'),2500)
	}).then((result)=>{
		//绘制地形图表
		let Cartain3 = transLonlat2Car3(selectedRoute.value.points)
		// 计算地形剖面，默认采样间隔为1km
		let res = profileAnalyse(window.viewer, Cartain3, 1000)
		// 计算航线距离数组
		let orderArr = []
		let hArr = []
		Cartain3.forEach((_,index) => {
			orderArr.push(index + 1)
			hArr.push(selectedRoute.value.points[index].alt)
		})
		console.log(orderArr,hArr)
		// 弹出图表窗口
		drawEcharts_RouteDetection(myChart, res.distanceArray, res.elevationArray, orderArr, hArr)

	}).catch((err)=>{
		uiMsg.error(err)
	})
}

// 在尾部添加航点
function addPtToTail() {
	let newPt = newAirlinePt()
	newPt.nPt = selectedRoute.value.points.at(-1).nPt + 1
	selectedRoute.value.points.push(newPt)
}

// 保存航点编辑
// 1 重新编辑航点的ch2属性
// 2 刷新航线属性
// 3 将改动更新到store中
function savePt() {
	selectedRoute.value.points.forEach((pt,index) => {
		pt.ch2 = 3
		pt.nPt = index+1	//航点序号从1起
	})
	selectedRoute.value.points.at(-1).ch2 = 1
	selectedRoute.value.PtNum = selectedRoute.value.points.length
	routeStore.addRoute(selectedRoute.value)
}

/** 删除或在此前插入航点
 *
 * @param key 下拉菜单key
 * @param index 航点索引
 */
function handlePtSelect(key:any, index:number) {
	if(key=='deletePt'){
		selectedRoute.value.points.splice(index,1)
		selectedRoute.value.points.forEach((pt,i) => {
			pt.nPt = i+1
		})
		showPtList.value = false
		nextTick(()=>{
			showPtList.value = true
		})
	}
	else if(key=='insertPt'){
		selectedRoute.value.points.forEach((pt,i) => {
			if(i>=index) pt.nPt = i + 2
		})
		let newPt = newAirlinePt()
		newPt.nPt = index + 1
		showPtList.value = false
		nextTick(()=>{
			selectedRoute.value.points.splice(index,0,newPt)
			showPtList.value = true
		})
	}
}

//查询上一航点的气象信息
function prevPtWeather() {
	routePtNumber.value -= 1
	window.viewer.flyTo(window.viewer.entities.getById(selectedRoute.value.unicode + "-航点" + (routePtNumber.value).toString()),
			{duration: 1})
	let lat = selectedRoute.value.points[routePtNumber.value-1].lat
	let lon = selectedRoute.value.points[routePtNumber.value-1].lon
	if(lat && lon){
		queryWeather(lon,lat, selectedLevel.value)
	}
}

//查询下一航点的气象信息
function nextPtWeather() {
	routePtNumber.value += 1
	window.viewer.flyTo(window.viewer.entities.getById(selectedRoute.value.unicode + "-航点" + (routePtNumber.value).toString()),
			{duration: 1})

	let lat = selectedRoute.value.points[routePtNumber.value-1].lat
	let lon = selectedRoute.value.points[routePtNumber.value-1].lon
	if(lat && lon){
		queryWeather(lon,lat, selectedLevel.value)
	}
}

function queryWeather(lon:number,lat:number,level?: number) {
	let response : Promise<any>
	if(level==null|| level==-1){	//地面
		response = query_surface_forecast(lon,lat)
	}else{
		response = query_upper_forecast(lon,lat, level)
	}
	response.then(res=>{
		// 查询失败
		if(!res.data.success){
			notify('error', '气象信息查询失败', res.data.message)
			return
		}
		let weatherData = res.data.data
		let timeArr = weatherData.time.map(item=>{
			let i = item.indexOf('T')
			return item.slice(i+1,i+3) + '时'
		})
		if(!Reflect.has(weatherData,'precip')){
			weatherData.precip = Array.from({length:timeArr.length},(v,k)=>0)
		}
		setChartOptions(weatherChart, timeArr.slice(0,8),weatherData.temp.slice(0,8),weatherData.windSpeed.slice(0,8),
				weatherData.wind360.slice(0,8), weatherData.precip.slice(0,8),weatherData.humidity.slice(0,8))
	})
}

function levelChanged(key: string | number) {
	selectedLevel.value = key
	let lat = selectedRoute.value.points[routePtNumber.value-1].lat
	let lon = selectedRoute.value.points[routePtNumber.value-1].lon
	if(lat && lon){
		queryWeather(lon,lat, Number(key))
	}
}
</script>

<template>
	<n-config-provider :theme="darkTheme">
	<div style="display: flex;">
		<div id="left">
			<n-layout style="height: 100%;">
				<n-layout-header :bordered="true">
					<n-popover trigger="hover">
						<template #trigger>
					<n-button quaternary type="success" size="large">
						<template #icon>
							<n-icon><ArrowBackOutline/></n-icon>
						</template>
					</n-button>
						</template>
						返回
					</n-popover>
					<n-popover trigger="hover">
						<template #trigger>
							<n-button quaternary  type="success" size="large">
								<template #icon>
									<n-icon><Save/></n-icon>
								</template>
							</n-button>
						</template>
						保存编辑
						</n-popover>
				</n-layout-header>
				<n-layout-content>
					<n-flex vertical style="margin-left: 1.2rem; margin-top: .5rem;overflow: hidden">
						<n-ellipsis><h3>航线列表</h3></n-ellipsis>
						<n-radio-group v-model:value="selectedRouteCode" name="radiogroup" @update:value="checkRoute">
							<n-scrollbar style="height: 20vh">
							<n-space vertical>
								<n-space v-for="r in routesInstore" justify="space-between"
												 style="margin-right: 2rem; border-bottom: #383737 1px solid">
									<n-radio :key="r.value" :value="r.value">
										{{ r.label }}
									</n-radio>
									<n-button-group>
<!--										TODO: 下发、删除功能实现-->
										<n-button secondary size="small" type="info" style="height: 1.3rem; margin: 0 3px 4px 0">下发</n-button>
										<n-button secondary size="small" type="error" style="height: 1.3rem; margin-bottom: 4px">删除</n-button>
									</n-button-group>
								</n-space>

							</n-space>
							</n-scrollbar>
						</n-radio-group>

						<n-divider style="margin: .2rem -.5rem"></n-divider>
						<n-space vertical>
							<n-space>
								<n-space>
									<n-ellipsis>开闭</n-ellipsis>
									<n-switch v-model:value="selectedRoute.isClose" size="small">
										<template #checked>
											闭
										</template>
										<template #unchecked>
											开
										</template>
									</n-switch>
								</n-space>
								<n-space style="margin-left: .5rem">
								<n-ellipsis>航点数</n-ellipsis>
									<n-input-number :show-button="false" disabled size="tiny" style="width: 5rem"
																	v-model:value="selectedRoute.PtNum"></n-input-number>
								</n-space>
							</n-space>
							<n-space>
								<n-ellipsis style="width: 4rem">航线名称</n-ellipsis>
								<n-input size="tiny" style="width:10rem" v-model:value="selectedRoute.name"></n-input>
							</n-space>
							<n-space>
								<n-ellipsis style="width: 4rem">航线类型</n-ellipsis>
								<n-select style="width:10rem" size="tiny" v-model:value="selectedRoute.code" :options="routeCode"/>
							</n-space>
						</n-space>

						<n-divider style="margin: .2rem -.5rem"></n-divider>
						<n-ellipsis><h3>地形剖面图</h3></n-ellipsis>
						<n-space justify="start">
							<n-ellipsis>采样间隔</n-ellipsis>
							<n-input-number size="tiny" placeholder="默认1000米"
															style="width:8vw" :min="100" :step="100">
							</n-input-number>
							<n-button type="success" size="tiny">重新绘图</n-button>
						</n-space>
						<div id="echarts-profile">
						<!--	Echarts地形剖面绘图区	-->
						</div>
					</n-flex>
				</n-layout-content>
			</n-layout>
		</div>

		<div id="map2">
			<SceneViewer id="scene-viewer-route"></SceneViewer>
			<BottomBar></BottomBar>
		</div>

		<div id="right">
			<n-layout style="height: 100%">
				<n-layout-header :bordered="true">
					<n-space justify="center">
						<n-button quaternary type="default" size="large"><h4>航点详情 {{'— '+selectedRoute.name}}</h4></n-button>
					</n-space>
				</n-layout-header>
				<n-layout-content>
					<n-flex vertical >
						<n-space justify="space-around" style="margin-top:.5rem;">
							<n-ellipsis style="margin-left:.2rem; width: 2rem">序号</n-ellipsis>
							<n-ellipsis style="width: 5.5rem">经度</n-ellipsis>
							<n-ellipsis style="width: 5.5rem">纬度</n-ellipsis>
							<n-ellipsis style="width: 3rem">高度</n-ellipsis>
						</n-space>
						<n-scrollbar style="height: 30vh">
							<div v-if="selectedRoute.points.length>0 && showPtList" >
								<n-space justify="space-around" style="margin: .2rem 0" v-for="(pt,index) in selectedRoute.points" >
									<n-dropdown trigger="hover" size="small" placement="top-start" :show-arrow="true"
															:options="PtOptions" @select="handlePtSelect($event,index)">
										<n-button secondary type="info" size="tiny" style="margin-left:.2rem; width: 1.7rem">{{ pt.nPt }}</n-button>
									</n-dropdown>
									<n-input-number size="tiny" v-model:value="pt.lon" :show-button="false" style="width: 5.5rem"
																	placeholder="经度" max="180" min="-180"></n-input-number>
									<n-input-number size="tiny" v-model:value="pt.lat" :show-button="false" style="width: 5.5rem"
																	placeholder="纬度" max="90" min="-90"></n-input-number>
									<n-input-number size="tiny" v-model:value="pt.alt" :show-button="false" style="width: 3rem"
																	placeholder="高度" max="12000" min="-500"></n-input-number>
								</n-space>

								<n-space justify="center" style="margin: .5rem 0">
									<n-button type="info" size="small" @click="addPtToTail">
										<template #icon>
											<Add/>
										</template>
										添加点
									</n-button>
									<n-button type="info" size="small" @click="savePt">
										<template #icon>
											<SaveOutline/>
										</template>
										保存编辑
									</n-button>
								</n-space>
							</div>

							<n-space v-else justify="space-around">
								<n-empty style="margin-top:3rem " description="无内容">
								</n-empty>
							</n-space>
						</n-scrollbar>

					</n-flex>
					<n-divider style="margin: .2rem -.5rem"></n-divider>

					<n-flex vertical>
						<n-row style="margin-left: 1rem; margin-top: .5rem;"><n-ellipsis><h3>气象信息</h3></n-ellipsis></n-row>
						<n-space justify="space-around" class="routePtSelector">
							<n-button size="small"  @click="prevPtWeather" :disabled="routePtNumber<=1">
								<template #icon><ArrowBackOutline/></template>
							</n-button>
							<n-ellipsis>航点 {{routePtNumber}}</n-ellipsis>
							<n-button size="small" @click="nextPtWeather" :disabled="selectedRoute.points.length<=routePtNumber">
								<template #icon><ArrowForwardOutline/></template>
							</n-button>
						</n-space>

						<n-space justify="center">
							<n-ellipsis>{{nowTime}}</n-ellipsis>
							<n-select style="width: 10rem" size="tiny" :options="levelOptions" v-model:value="selectedLevel"
												@update:value="levelChanged" placeholder="选择高度层"></n-select>
						</n-space>
						<n-scrollbar x-scrollable id="weatherChart" style="height:41.5vh; width: 100%">
							<!--	Echarts气象信息绘图区	-->
						</n-scrollbar>
					</n-flex>
				</n-layout-content>
			</n-layout>
		</div>
	</div>
	</n-config-provider>


</template>

<style scoped>
#left{
	width: 20vw;
	height: 100vh;
}
#map2 {
	width: 57vw;
	height: 100vh;
	position: relative;
}
#right{
	width: 23vw;
	height: 100vh;
}

#echarts-profile{
	margin-left: -1rem;
	margin-top: -.5rem;
	height: 40vh;
}
#scene-viewer-route {
	width: 100%;
	height: 100%;
	overflow: hidden;
}
.routePtSelector {
	width: 110%;
	color: #63e2b7;
	font-weight: bold;
	margin-left: -1rem
}
.routePtSelector:hover{
	background: rgb(24, 24, 28);
}

.border{
	border: #22ee22 solid 1px;
}
</style>