<template>
  <div id="PlanSchedule" :style="{top: top+'px', height: height+'px'}">
    <div class="left">
      <div :id="runPlanId" />
    </div>
    <div v-show="showTrain" class="position">
      <data-table
        ref="serviceTable"
        :height="(height - 45)/2"
        :config="serviceNumberConfig"
        :style="{top: top-(height - 45)/2+'px'}"
        @touch="scheduleTouch"
      />
      <data-table
        ref="tripTable"
        :height="height/2"
        :config="tripNumberConfig"
        :style="{top: top-height/2+'px'}"
        @touch="trainNumTouch"
      />
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';
import { timeFormat } from '@/utils/date';
import { getStationListBySkinCode, queryRunPlan } from '@/api/runplan';
import { loadMapData } from '@/utils/loaddata';
import { getPublishMapInfo } from '@/api/jmap/map';
import DataTable from './menus/components/dataTable';

export default {
	name: 'PlanSchedule',
	components: {
		DataTable
	},
	props: {
		skinCode: {
			type: String,
			required: true
		},
		// planConvert: {
		// 	type: Object,
		// 	required: true
		// },
		maxWidth: {
			type: Number,
			required: true
		},
		maxHeight: {
			type: Number,
			required: true
		}
	},
	data() {
		return {
			planConvert: null,
			top: 0,
			height: 0,
			mapName: '',
			runPlanId: 'plan-tool',
			myChart: null,
			showTrain: false,
			serviceNumberConfig: {
				data: [],
				title: this.$t('planMonitor.serviceNumber'),
				showHeader: false,
				highlightCurrentRow: true,
				handleChange: this.serviceNumberChange,
				showClose: false,
				columns: [
					{
						prop: 'serviceNumber',
						label: this.$t('planMonitor.serviceNumber')
					}
				]
			},
			tripNumberConfig: {
				data: [],
				title: this.$t('planMonitor.tripNumber'),
				showHeader: false,
				highlightCurrentRow: true,
				handleChange: this.tripNumberChange,
				showClose: false,
				columns: [
					{
						prop: 'tripNumber',
						label: this.$t('planMonitor.tripNumber'),
					}
				]
			},
			realData: {},
			kmRangeCoordMap: {},
			option: {
				title: { // 标题
					text: '',
					left: 'center', // 居中对齐
					top: '10px'
				},
				grid: { // 整个坐标系位置
					top: '50px',
					left: '120px',
					right: '80px',
					bottom: '60px',
					containLabel: true,
					backgroundColor: 'floralwhite'
				},
				toolbox: { // 工具栏
					top: '10px',
					right: '120px',
					feature: {
						dataZoom: {
							yAxisIndex: 'none'
						},
						restore: {},
						saveAsImage: {}
					}
				},
				tooltip: {
					axisPointer: {
						trigger: 'item',
						type: 'cross',
						snap: true
					},
					formatter: this.axisTooltip,
					borderWidth: 1
				},
				xAxis: [
					{
						type: 'category',
						boundaryGap: false,
						data: [],
						axisLine: {
							onZero: false,
							lineStyle: {
								width: 1
								// color: '#d14a61'
							}
						},
						axisLabel: {
							formatter: this.xAxisLableFormat,
							textStyle: {
								color: '#333'
							}
						},
						axisPointer: {
							snap: true,
							label: {
								formatter: this.xAxisPointFormat,
								backgroundColor: 'rgb(255,0,0,0.5)',
								color: 'white'
							}
						}
					}
				],
				yAxis: {
					type: 'value',
					splitLine: {
						show: false
					},
					axisTick: {
						show: false
					},
					axisLine: {
						onZero: false,
						lineStyle: {
							width: 1
							// color: '#d14a61'
						}
					},
					axisLabel: {
						interval: 'auto',
						formatter: this.yAxisLableFormat
					},
					axisPointer: {
						xAxisIndex: 'all',
						label: {
							formatter: this.yAxisPointFormat,
							backgroundColor: 'rgb(0,100,0,0.5)',
							color: 'white'
						}
					},
					min: 0,
					max: 0
				},
				series: [],
				dataZoom: [ // 滑动滚轮
					{
						type: 'inside'
					},
					{
						fiterMode: 'filter',
						handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
						handleSize: '80%',
						handleStyle: {
							color: '#fff',
							shadowBlur: 3,
							shadowColor: 'rgba(0, 0, 0, 0.6)',
							shadowOffsetX: 2,
							shadowOffsetY: 2
						},
						bottom: '20px'
					}
				]
			},
			absoluteTime: 2 * 3600,
			indexKmRangeMap: {}
		};
	},
	computed: {
		...mapGetters('runPlan', [
			'stations'
		]),
		planId() {
			return this.$route.query.planId;
		}
	},
	watch: {
		maxWidth() {
			this.setPosition();
		},
		maxHeight() {
			this.setPosition();
		},
		'$store.state.runPlan.planSizeCount': function () {
			this.reSize({ width: this.$store.state.runPlan.width, height: this.$store.state.runPlan.height });
		},
		'$store.state.runPlan.refreshCount': function() {
			this.loadChartPage();
		},
		$route() {
			this.$nextTick(() => {
				this.loadChartPage();
			});
		}
	},
	mounted() {
		this.setPosition();
		this.loadChartPage();
	},
	beforeDestroy() {
		this.destroy();
	},
	methods: {
		displayTrain() {
			this.showTrain = !this.showTrain;
		},
		serviceNumberChange(row) {
			let serviceNumber = null;
			let serviceObj = {};
			if (row) {
				serviceNumber = row.serviceNumber;
				serviceObj = this.$store.state.runPlan.editData[row.serviceNumber] || {};

				const op = this.myChart.getOption();
				op.series.forEach((item, index) => {
					item.lineStyle.color = '#000';
					if (item.name == serviceNumber) {
						item.lineStyle.color = 'red';
					}
					if (item.name == 'trainLabel') {
						item.data = [];
					}
				});
				this.myChart.setOption(op);
			}
			this.$store.dispatch('runPlan/setSelected', { serviceNumber: serviceNumber, tripNumber: null });
			this.analyticalTripNumber(serviceObj.trainMap || {});
		},
		tripNumberChange(row) {
			const serviceNumber = this.$store.state.runPlan.selected.serviceNumber;
			let tripNumber = null;
			if (row) {
				const data = [];
				tripNumber = row.tripNumber;
				const op = this.myChart.getOption();
				op.series.forEach(item => {
					if (item.name == serviceNumber) {
						item.data.forEach(nor => {
							if (nor[3] == tripNumber) {
								data.push(nor);
							}
						});
					}
					if (item.name == 'trainLabel') {
						item.data = [];
					}
				});
				op.series.push({
					name: 'trainLabel',
					lineStyle: {
						color: 'green'
					},
					type: 'line',
					data: data
				});
				this.myChart && this.myChart.setOption(op);
			}

			this.$store.dispatch('runPlan/setSelected', { serviceNumber: serviceNumber, tripNumber: tripNumber });
		},
		async analyticalServiceNumber(data) {
			this.serviceNumberConfig.data = Object.keys(data || {})
				.sort((a, b) => { return data[a].oldIndex - data[b].oldIndex; })
				.map(serviceNumber => { return { serviceNumber }; });
		},
		async analyticalTripNumber(data) {
			this.tripNumberConfig.data = Object.keys(data || {})
				.sort((a, b) => { return data[a].oldIndex - data[b].oldIndex; })
				.map(tripNumber => { return { tripNumber }; });
		},
		async setPosition() {
			this.$nextTick(() => {
				let top = 3;
				const width = this.maxWidth;
				let height = this.maxHeight;

				const titleBar = document.getElementById('PlanTitleBar');
				const menuBar = document.getElementById('PlanMenuBar');
				const menuTool = document.getElementById('PlanMenuTool');
				const statusBar = document.getElementById('PlanStatusBar');

				if (titleBar) {
					top += (titleBar.offsetHeight || 0);
				}

				if (menuBar) {
					top += (menuBar.offsetHeight || 0);
				}

				if (menuTool) {
					top += (menuTool.offsetHeight || 0);
				}

				if (statusBar) {
					height -= (statusBar.offsetHeight || 0);
				}

				height = height - top;
				this.$store.dispatch('runPlan/resize', { width, height });

				if (this.top != top) {
					this.top = top;
				}

				if (this.height != height) {
					this.height = height - 20 * 2;
				}
			});
		},
		async loadChartPage() {
			try {
				getPublishMapInfo(this.$route.query.mapId).then(resp => {
					this.mapName = `${resp.data.name} (${this.$route.query.planName || ''})`;
				});
				this.planConvert = this.$theme.loadPlanConvert(this.skinCode);
				this.$store.dispatch('runPlan/clear').then(() => {
					this.loadInitChart().then(() => {
						if (this.skinCode) {
							loadMapData(this.skinCode);
							getStationListBySkinCode(this.$route.query.skinCode).then(resp => {
								this.$store.dispatch('runPlan/setStations', resp.data).then(() => {
									this.loadInitData();
									if (this.planId) {
										this.myChart && this.myChart.showLoading();
										queryRunPlan(this.planId).then(rest => {
											this.$store.dispatch('runPlan/setPlanData', rest.data).then(() => {
												this.analyticalServiceNumber(this.$store.state.runPlan.editData);
												this.loadChartData();
												this.myChart && this.myChart.hideLoading();
											});
										}).catch(() => {
											this.myChart && this.myChart.hideLoading();
											this.$messageBox(this.$t('error.obtainOperationGraphFailed'));
										});
									} else {
										this.clearCanvas();
									}
								});
							}).catch(() => {
								this.$messageBox(this.$t('tip.requestingStationDataFailed'));
								this.$store.dispatch('runPlan/setStations', []);
							});
						}
					});
				});
			} catch (error) {
				this.$messageBox(this.$t('error.loadingOperationGraphFailed'));
			}
		},
		async loadChartData() {
			try {
				const stations = this.$store.state.runPlan.stations;
				const planData = this.$store.state.runPlan.planData;

				this.viewDisabled = true;

				this.option.series = [];
				this.kmRangeCoordMap = this.planConvert.convertStationsToMap(stations);
				this.pushModels(this.option.series, [this.planConvert.initializeYaxis(this.stations)]);
				this.pushModels(this.option.series, this.planConvert.convertDataToModels(planData, stations, this.kmRangeCoordMap, { width: 0.5, color: '#000' }));
				await this.loadInitChart();

				this.viewDisabled = false;
			} catch (error) {
				this.viewDisabled = false;
				this.$messageBox(this.$t('error.loadingOperationGraphFailed')+this.$t('global.colon')+error.message);
			}
		},
		async loadInitData() {
			await this.xAxisInit();
			await this.yAxisInit();
			await this.loadInitChart();
		},
		pushModels(series, models) {
			if (models && models.length) {
				models.forEach(elem => {
					if (elem) {
						series.push(elem);
					}
				});
			}

			return series;
		},
		popModels(series, models) {
			if (models && models.length) {
				models.forEach(elem => {
					const index = series.indexOf(elem);
					if (index >= 0) {
						series.split(index, 1);
					}
				});
			}

			return series;
		},
		loadInitChart() {
			return new Promise((resolve, reject) => {
				try {
					const that = this;
					// 加载echart配置
					require.config(
						{
							paths: {
								echarts: './js/dist'
							}
						}
					);
					// 按需加载所需图表，如需动态类型切换功能，别忘了同时加载相应图表
					require(
						[
							'echarts',
							'echarts/lib/chart/line'
						],
						function (ec) {
							if (that.myChart && that.myChart.isDisposed) {
								that.myChart.clear();
							}
							if (that.$route.query.planName) {
								that.option.title.text = that.mapName;
							}
							that.myChart = ec.init(document.getElementById(that.runPlanId));
							that.myChart.setOption(that.option);
							that.reSize({ width: that.$store.state.runPlan.width, height: that.$store.state.runPlan.height });
							// that.myChart.on('click', that.mouseClick);
							resolve(true);
						}
					);
				} catch (error) {
					reject(error);
				}
			});
		},
		clearCanvas() {
			this.option.series = [];
			this.option.title.text = '';
			if (this.myChart) {
				this.myChart.clear();
			}
			this.myChart.setOption(this.option);
		},
		xAxisPointFormat(params) {
			return timeFormat(params.value);
		},
		yAxisPointFormat(params) {
			return this.planConvert.computedFormatYAxis(this.stations, params);
		},
		xAxisLableFormat(value, index) {
			if (value % 60 === 0) {
				return timeFormat(value);
			}
		},
		yAxisLableFormat(value, index) {
			return '';
		},
		xAxisInit() {
			const list = [];
			for (var time = 0 + this.planConvert.TranslationTime; time < 3600 * 24 + this.planConvert.TranslationTime; time++) {
				list.push(time);
			}

			const startValue = 3600 * 6;
			const offsetTime = 3600 * 1;

			this.option.xAxis[0].data = list;
			if (!this.option.dataZoom[0].startValue) {
				this.option.dataZoom[0].startValue = this.option.dataZoom[1].startValue = startValue - offsetTime;
			}

			if (!this.option.dataZoom[0].endValue) {
				this.option.dataZoom[0].endValue = this.option.dataZoom[1].endValue = startValue + offsetTime;
			}
		},
		yAxisInit() {
			if (Object.keys(this.planConvert).length) {
				this.pushModels(this.option.series, [this.planConvert.initializeYaxis(this.stations)]);
				this.option.yAxis.min = this.planConvert.computedYaxisMinValue(this.stations);
				this.option.yAxis.max = this.planConvert.computedYaxisMaxValue(this.stations);
			}
		},
		axisTooltip(param) {
			const station = this.stations[Math.floor((param.data[1] - this.planConvert.EdgeHeight) / this.planConvert.CoordMultiple)] || { name: '', kmRange: '' };
			return [
				`Point Data <hr size=1 style="margin: 3px 0">`,
				`${this.$t('planMonitor.stationName')}${station.name}<br>`,
				`${this.$t('planMonitor.stationKilometerMark')}${station.kmRange} km <br>`,
				`${this.$t('planMonitor.arriveTime')}${timeFormat(param.data[0] + this.planConvert.TranslationTime)} (${param.data[0]})<br>`
			].join('');
		},
		// mouseClick(params) {
		// 	const model = {
		// 		serviceNumber: params.seriesName
		// 	};

		// 	const op = this.myChart.getOption();
		// 	op.series.forEach(item => {
		// 		item.lineStyle.color = '#000';
		// 		if (item.name == params.seriesName) {
		// 			item.lineStyle.color = 'red';
		// 		}
		// 		if (item.name == 'trainLabel') {
		// 			item.data = [];
		// 		}
		// 	});
		// 	this.myChart.setOption(op);
		// 	this.$store.dispatch('runPlan/setSelected', model);
		// },
		reSize(opt) {
			if (this.myChart) {
				this.myChart.resize({
					width: opt.width,
					height: opt.height,
					silent: false
				});
			}
		},
		destroy() {
			if (this.myChart && this.myChart.isDisposed) {
				this.myChart.dispose();
				this.myChart = null;
			}
		},
		scheduleTouch() {

		},
		trainNumTouch() {

		}
	}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
    @import "src/styles/mixin.scss";

    #PlanSchedule {
        z-index: 0;
        position: absolute;
        width: 100%;

        .left {
            height: 100%;
			width: 100%;
            float: left;
        }

        .position {
            position: absolute;
			top: 2px;
			right: 50px;
			width: 220px;
			height: calc(100% - 45px);
        }
    }
</style>
