<template>
  <div id="PlanSchedule" :style="{ height: height+'px'}">
    <div class="left">
      <div :id="runPlanId" />
    </div>
    <div class="right">
      <data-table
        ref="serviceTable1"
        :height="height/2"
        :config="serviceNumberConfig"
        :style="{top: top-height/2+'px'}"
        @touch="scheduleTouch"
      />
      <data-table
        ref="tripTable1"
        :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 DataTable from '@/views/planSchedule/menusPlan/components/dataTable';
import echarts from 'echarts';
import {toTimeStamp, formatDuring} from '@/utils/date';
import { deepAssign } from '@/utils/index';
import { EventBus } from '@/scripts/event-bus';

export default {
    name: 'PlanSchedule',
    components: {
        DataTable
    },
    data() {
        return {
            top: 0,
            height: 0,
            inter:null,
            runPlanId: 'run-plan-view',
            myChart: null,
            PlanParser: {},
            serviceNumberConfig: {
                data: [],
                highlightCurrentRow: true,
                handleChange: this.serviceNumberChange,
                showClose: false,
                columns: [
                    {
                        prop: 'serviceNumber',
                        label: '表号'
                    },
                    {
                        width: 40
                    }
                ]
            },
            tripNumberConfig: {
                data: [],
                highlightCurrentRow: true,
                handleChange: this.tripNumberChange,
                showClose: false,
                columns: [
                    {
                        prop: 'tripNumber',
                        label: '车次号'
                    },
                    {
                        width: 40
                    }
                ]
            },
            realData: {},
            kmRangeMap: {},
            absoluteTime: 2 * 3600,
            indexKmRangeMap: {},
            dialogLoading: false,
            dialogShow: false,
            seriesMap: {},
            staticSeries: [],
            runSeries: [],
            selectSeries: [],
            runPlanData: {}
        };
    },
    computed: {
        ...mapGetters('runPlan', [
            'stations'
        ]),
        maxWidth() {
            return this.$store.state.app.width > 1920 ? 1920 : this.$store.state.app.width;
        },
        maxHeight() {
            return this.$store.state.app.height > 1080 ? 1050 : this.$store.state.app.height - 30;
        },
        title() {
            return this.$t('display.runPlan.previewRunDiagram');
        }
    },
    watch: {
        maxWidth() {
            this.setPosition();
        },
        maxHeight() {
            this.setPosition();
        },
        '$store.state.runPlan.planLoadedCount': async function () {
            try {
                await this.loadChartPage();
                this.selectSeries = []; this.runSeries = []; this.runPlanData = {};
                if (this.dialogShow) {
                    await this.loadInitData();
                }
            } catch (e) {
                console.error(e);
            } finally {
                this.loading = false;
            }
        },
        '$store.state.socket.simulationReset': function (val) {
            this.selectSeries = []; this.runSeries = []; this.runPlanData = {};
            if (this.dialogShow) {
                this.loadInitData();
            }
        },
        '$store.state.runPlan.planSizeCount': function () {
            this.reSize({ width: this.$store.state.runPlan.width, height: this.$store.state.runPlan.height });
        },
        '$store.state.socket.trainStationList': function (val) {
            if (val.length) {
                this.updateRunPlanData(val);
            }
        }
    },
    mounted() {
        this.staticSeries = []; this.selectSeries = []; this.runSeries = []; this.runPlanData = {};
        this.PlanParser = this.$theme.loadPlanParser(this.$route.query.lineCode);
        this.loadChartPage();
        EventBus.$on('clearRunSeries', () => {
            this.runSeries = [];
        });
    },
    beforeDestroy() {
        this.$store.dispatch('runPlan/setSelected', null);
        this.destroy();
    },
    methods: {
        async doClose() {
            this.dialogShow = false;
            this.inter && clearInterval(this.inter);
        },
        serviceNumberChange(row) {
            if (row) {
                this.$store.dispatch('runPlan/setSelected', { serviceNumber: row.serviceNumber, tripNumber: null });
                this.renderTripNumber({ serviceNumber: row.serviceNumber, tripNumber: null });
                const serviceObj = this.$store.state.runPlan.editData[row.serviceNumber];
                if (serviceObj) {
                    this.analyticalTripNumber(serviceObj.trainMap);
                }
            }
        },
        tripNumberChange(row) {
            if (row) {
                this.$store.dispatch('runPlan/setSelected', { serviceNumber: this.$store.state.runPlan.selected.serviceNumber, tripNumber: row.tripNumber });
                this.renderTripNumber({ serviceNumber: this.$store.state.runPlan.selected.serviceNumber, tripNumber: row.tripNumber });
            }
        },
        async analyticalServiceNumber(data) {
            this.serviceNumberConfig.data = Object.keys(data || {})
                .sort((a, b) => { return parseInt(data[a].serviceNumber) - parseInt(data[b].serviceNumber); })
                .map(serviceNumber => { return { serviceNumber }; });
        },
        async analyticalTripNumber(data) {
            this.tripNumberConfig.data = Object.keys(data || {})
                .sort((a, b) => { return data[a].tripNumber - data[b].tripNumber; })
                .map(tripNumber => { return { tripNumber }; });
        },
        async setPosition() {
            this.$nextTick(() => {
                const top = 54;
                const width = this.maxWidth * 0.85;
                let height = this.maxHeight;

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

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

                if (this.height != height) {
                    this.height = height - top;
                }
            });
        },
        updateRunPlanData(data) {
            const stations = this.$store.state.runPlan.stations;
            data.forEach(item => {
                item.secondTime = item.second;
            });
            this.kmRangeMap = this.PlanParser.convertStationsToMap(stations);
            this.runSeries = this.PlanParser.updateDataToModels(data, stations, this.kmRangeMap,
                this.runPlanData, this.runSeries, { color: '#FF00DE', width: 2 }
            );
            const series = [...this.staticSeries, ...this.runSeries, ... this.selectSeries];
            this.myChart && this.myChart.setOption({series: series});
        },
        async loadChartPage() {
            try {
                this.seriesMap = {};
                this.staticSeries = [];
                const stations = this.$store.state.runPlan.stations;
                const planData = this.$store.state.runPlan.planData;
                this.kmRangeMap = this.PlanParser.convertStationsToMap(stations);
                this.pushModels(this.staticSeries, [this.PlanParser.initializeAxisY(stations)]);
                this.staticSeries = this.pushModels(this.staticSeries, this.PlanParser.convertDataToModels(planData, stations, this.kmRangeMap, { color: '#000', width: 0.5 }));
                this.staticSeries.forEach(item => {
                    this.seriesMap[item.name] = item;
                });
                await this.analyticalServiceNumber(this.$store.state.runPlan.editData);
                await this.setPosition();
                await this.loadInitData();
                this.inter && clearInterval(this.inter);
            } catch (error) {
                console.log(error);
                this.$messageBox(`加载运行图数据失败`);
            }
        },

        async loadInitData() {
            this.myChart && this.myChart.showLoading();
            const option = {
                tooltip: {
                    axisPointer: {
                        trigger: 'item',
                        type: 'cross'
                    },
                    formatter: this.axisTooltip,
                    borderWidth: 1
                },
                grid: {
                    right: '40px',
                    left: '120px',
                    height: '85%'
                },
                xAxis: [
                    {
                        type: 'category',
                        data: [],
                        axisLine: {
                            onZero: false,
                            lineStyle: {
                                width: 2,
                                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',
                        yAxisIndex: 0,
                        splitLine: {
                            show: false
                        },
                        axisTick: {
                            show: false
                        },
                        axisLine: {
                            onZero: false,
                            lineStyle: {
                                width: 2,
                                color: '#d14a61'
                            }
                        },
                        axisLabel: {
                            interval: 'auto',
                            formatter: this.yAxisLableFormat
                        },
                        axisPointer: {
                            xAxisIndex: 'all',
                            label: {
                                formatter: this.yAxisPointFormat,
                                backgroundColor: 'rgb(0,100,0,0.5)',
                                color: 'white'
                            }
                        }
                    }
                ],
                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'
                }],
                series: [

                ]
            };
            await this.xAxisInit(option);
            await this.yAxisInit(option);
            await this.loadInitChart(option);
            this.myChart && this.myChart.hideLoading();
        },
        pushModels(series, models) {
            if (models && models.length) {
                models.forEach(elem => {
                    if (elem) {
                        series.push(elem);
                    }
                });
            }
            return series;
        },
        loadInitChart(option) {
            return new Promise((resolve, reject) => {
                try {
                    this.destroy();
                    let startValue = 3600 + this.PlanParser.getTranslation();
                    const offsetTime = 3600;
                    const initTime = toTimeStamp(formatDuring(this.$store.state.training.initTime));
                    startValue = initTime - this.PlanParser.getTranslation();
                    option.dataZoom[0].startValue = option.dataZoom[1].startValue = startValue - offsetTime;
                    option.dataZoom[0].endValue = option.dataZoom[1].endValue = startValue + offsetTime;
                    option.series = [...this.staticSeries, ...this.runSeries, ...this.selectSeries];
                    this.myChart = echarts.init(document.getElementById(this.runPlanId));
                    if (this.myChart) {
                        this.myChart.setOption(option);
                        this.reSize({ width: this.$store.state.runPlan.width, height: this.$store.state.runPlan.height });
                        this.myChart.on('click', this.mouseClick);
                    }
                    resolve(true);
                } catch (error) {
                    reject(error);
                }
            });
        },
        xAxisPointFormat(params) {
            return timeFormat(params.value);
        },
        yAxisPointFormat(params) {
            return this.PlanParser.computedFormatAxisY(this.stations, params);
        },
        xAxisLableFormat(value, index) {
            return timeFormat(value);
        },
        yAxisLableFormat(value, index) {
            return '';
        },
        xAxisInit(option) {
            const list = [];
            for (var time = 0 + this.PlanParser.getTranslation(); time < 3600 * 24 + this.PlanParser.getTranslation(); time++) {
                list.push(time);
            }
            const startValue = 3600 * 6;
            const offsetTime = 3600 * 1;

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

            if (!option.dataZoom[0].endValue) {
                option.dataZoom[0].endValue = option.dataZoom[1].endValue = startValue + offsetTime;
            }
        },
        yAxisInit(option) {
            if (Object.keys(this.PlanParser).length) {
                option.yAxis[0].min = this.PlanParser.computedAxisYMinValue(this.stations);
                option.yAxis[0].max = this.PlanParser.computedAxisYMaxValue(this.stations);
            }
        },
        axisTooltip(param) {
            const station = (this.$store.getters['map/getDeviceByCode'](param.data[2])) || { name: '', kmRange: '' };
            return [
                `Point Data <hr size=1 style=" margin: 3px 0">`,
                `车站名称: ${station.name}<br>`,
                `车站公里标: ${station.kmRange} km <br>`,
                `到站时间: ${timeFormat(param.data[0] + this.PlanParser.getTranslation())} (${param.data[0]})<br>`
            ].join('');
        },
        renderTripNumber(params) {
            const tripNumber = params.tripNumber; // 车次号
            const serviceNumber = params.serviceNumber; // 服务号
            let data, markPoint;
            if (tripNumber && this.seriesMap[serviceNumber]) {
                const temp = this.seriesMap[serviceNumber].data.filter(elem => elem[3] == tripNumber);
                if (temp.length) {
                    data = temp;
                    this.seriesMap[serviceNumber].markPoint.data.forEach(each=> {
                        if (each.name == temp[0][4]) {
                            markPoint = deepAssign({}, {data:[each]});
                            markPoint.symbol = 'roundRect';
                            markPoint.symbolSize = 1;
                            markPoint.data[0].label.color = '#f00';
                        }
                    });
                }
            } else if (this.seriesMap[serviceNumber]) {
                markPoint = deepAssign({}, this.seriesMap[serviceNumber].markPoint);
                markPoint.data.forEach(each => {
                    each.label.color = '#f00';
                });
                data = this.seriesMap[serviceNumber].data;
            }
            this.selectSeries = [{
                name: 'trainLabel',
                lineStyle: {
                    color: '#f00',
                    width: 2,
                    type: 'solid'
                },
                z: 10,
                type: 'line',
                markPoint:markPoint,
                animation: false,
                data: data
            }];
            const series = [...this.staticSeries, ...this.runSeries, ...this.selectSeries];
            this.myChart && this.myChart.setOption({series: series});
        },
        mouseClick(params) {
            const model = {
                serviceNumber: params.seriesName
            };
            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 {
		position: absolute;
		width: 100%;

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

		.right {
			height: 100%;
			width: 15%;
			float: right;
		}
	}
</style>

