<template>
<Navbar />
<!-- <button id="hoverButton" @click="postLiveTrainData">Populate Database</button> -->

<!--Sidebar, fades out on click of X button-->
<transition id="sidebar" name="slideLeft">
  <div v-if="store.display && store.selectedDataMap">
    <SidebarPanel />
  </div>
</transition>

<ol-map :loadTilesWhileAnimating="true" :loadTilesWhileInteracting="true" style="position:absolute; height:90.7vh; width:100%;">
    <ol-view ref="view" :center="center" :rotation="rotation" :zoom="zoom" :projection="projection" />
    <ol-tile-layer>
    <ol-source-osm />
    </ol-tile-layer>

    <template v-for="coordinate, i in coordinates" :position="inline-block">
    <!-- overlay offset is the size of the image so that it is centered-->
    <ol-overlay :position="coordinate" :positioning="center-center" :offset="[-14,-16]">
        <div class="overlay-content" @click="getSelectedTrain(i)">
            <img v-if="isTrainLate(i)" src="../assets/red-train-solid.png" class="trainMapIcon" alt="Train Icon">
            <img v-else src="../assets/green-train-solid.png" class="trainMapIcon" alt="Train Icon">
        </div>
    </ol-overlay>
    </template>
</ol-map>

<div>
  <MarqueeText v-if="publicMessages.length > 0" id="publicMessageTicker" :paused="isPaused" :duration="800" :repeat="1"
    @mouseenter="isPaused = !isPaused" @mouseleave="isPaused = false">
    <!-- <span v-for="message in publicMessages"> {{ "---" + message + "---" }} </span>  -->
    <span v-for="message in publicMessages"> {{ message + " • " }} </span> 
  </MarqueeText>
</div>
</template>

<script>
import {store} from '../store/store'
import { ref } from 'vue';
import {fromLonLat, toLonLat} from 'ol/proj.js';
import app from '../api/firebase';
import { getFunctions, httpsCallable, connectFunctionsEmulator } from "firebase/functions";
import Navbar from '../components/Navbar.vue'
import MarqueeText from 'vue-marquee-text-component'
import SidebarPanel from '../components/SidebarPanel.vue';

export default {
    name: "MapPage",

    data() {
        const center = ref(fromLonLat([-7.5029786, 53.4494762]))
        const projection = ref('EPSG:3857')
        const zoom = ref(7)
        const rotation = ref(0)
        const radius = ref(10)
        const strokeWidth = ref(1)
        const strokeColor = ref('black')
        const fillColor = ref('red')

        return {
            center,
            projection,
            zoom,
            rotation,
            radius,
            strokeWidth,
            strokeColor,
            fillColor,

            coordinates: [],
            dbLiveTrainData: [],
            allDataMap: {},
            store,

            publicMessages: [],
            isPaused: false,
       }
    },

    components: {
      Navbar,
      MarqueeText,
      SidebarPanel
    },

    created() {
        let host = window.location.hostname
        if (host === '127.0.0.1' || host === 'localhost') {
            this.postLiveTrainData();
        }  
        else {
            this.getLiveTrainData();
        }
        // request new data every 60 seconds
        // window.setInterval(this.getLiveTrainData, 60000);
    },

    methods: {
        // method to assign a single train's data to the selected hashmap
        getSelectedTrain(i) {
          store.setSelectedDataMap(this.allDataMap[i]);
          store.setDisplay(true)
        },

        // method to determine whether or not a selected train is late 
        isTrainLate(i) {
            // check if the train is running
            if (this.allDataMap[i]["TrainStatus"][0] == "R") {
                let publicMessage = this.allDataMap[i]["PublicMessage"][0];
                let startTimeStr = publicMessage.indexOf("(");

                // check if the train is late
                if (publicMessage[startTimeStr+1] != "-" && publicMessage[startTimeStr+1] != "0") {
                    return true;
                }
            }
            return false;
        },

        // method to fetch live train data from the database
        getLiveTrainData() {
            const functions = getFunctions(app);
            let host = window.location.hostname
            if (host === '127.0.0.1' || host == 'localhost') {
                connectFunctionsEmulator(functions, host, 5001);
            }
            const getData = httpsCallable(functions, 'getLiveTrainData');
            let loader = this.$loading.show({
                loader: 'dots',
                container: this.$refs.container,
                canCancel: false
            });
            
            getData().then((response) => {
                try {
                    this.dbLiveTrainData = response.data;
                    if (!this.dbLiveTrainData) throw new Error("Error fetching live train data from the database");

                    var insights =  {
                                        "numRunningTrains": 0,
                                        "numLateRunningTrains": 0,
                                        "numMainland": 0,
                                        "numSuburban": 0,
                                        "numDart": 0
                                    };
                    var unorderedTrains = [];
                    var latest = null;
                    var earliest = null;
                    var currLatestTime = null;
                    var currEarliestTime = null;

                    var currentMessages = [];

                    // create an array of coordinates and hashmap with the key-values {index: JSON obj}
                    for (var i=0; i<this.dbLiveTrainData.length; i++) {
                        let train = this.dbLiveTrainData[i];

                        // filtering out \n in public message 
                        train["PublicMessage"][0] = train["PublicMessage"][0].replace(/\\n/g, ". ");

                        this.coordinates[i] = ref(fromLonLat([train["TrainLongitude"][0], train["TrainLatitude"][0]]))
                        this.allDataMap[i] = train;

                        if (train["TrainType"][0] == "M") insights["numMainland"] += 1;
                        else if (train["TrainType"][0] == "S") insights["numSuburban"] += 1;
                        else if (train["TrainType"][0] == "D") insights["numDart"] += 1;
                        
                        let publicMessage = train["PublicMessage"][0];
                        currentMessages.push(publicMessage);

                        // check if the train is running
                        if (this.dbLiveTrainData[i]["TrainStatus"][0] == "R") {
                            insights["numRunningTrains"] += 1;
                            let startTimeStr = publicMessage.indexOf("(");
                            let timeEnd = publicMessage.indexOf(" ", startTimeStr+1);
                            let num = parseInt(publicMessage.substring(startTimeStr+1, timeEnd))
                            unorderedTrains.push({"time": num, "jsonIndex": i})

                            // check if the train is late
                            if (publicMessage[startTimeStr+1] != "-" && publicMessage[startTimeStr+1] != "0") {
                                insights["numLateRunningTrains"] += 1;

                                if (!latest) latest = train;

                                // check for a new latest train
                                if (num > currLatestTime) {
                                    latest = train;
                                    currLatestTime = num;
                                }
                            }
                            // train is early or ontime
                            else {
                                if (!earliest) earliest = train;
                                
                                // check for a new earliest train (early trains are -x mins late)
                                if (num < currEarliestTime) {
                                    earliest = train;
                                    currEarliestTime = num;
                                }
                            }
                        }
                    }

                    insights["percentageLate"] = ((insights["numLateRunningTrains"] / insights["numRunningTrains"]) * 100).toFixed(2);
                    insights["percentageNotLate"] = (100 - insights["percentageLate"]).toFixed(2);
                    insights["totalNumTrains"] = Object.keys(this.allDataMap).length;
                    insights["latestTime"] = currLatestTime;
                    insights["earliestTime"] = currEarliestTime;
                    this.publicMessages = currentMessages;

                    // assign the results to the Vue Store
                    store.setInsights(insights);
                    store.setEarliestTrain(earliest);
                    store.setLatestTrain(latest);
                    store.setRawData(this.dbLiveTrainData);
                    store.setOrderedTrains(unorderedTrains);
                    loader.hide();
              }
              catch (error) {
                  console.log(error)
                  loader.hide();
              }
            })
        },

        // method to populate the database for local testing
        postLiveTrainData() {
            const functions = getFunctions(app);
            let host = window.location.hostname
            if (host === '127.0.0.1' || host === 'localhost') {
                connectFunctionsEmulator(functions, host, 5001);
            }
            const postData = httpsCallable(functions, 'postLiveTrainData');
            postData().then((response) => {
                this.getLiveTrainData()
            })
        }
    }
}
</script>

<style scoped>
.overlay-content {
  width: 1%;
}

.trainMapIcon {
  width: 28px;
  height: 32px;
}

#sidebar{
  position: absolute;
  height: 85%;
  width: 20%;
  left: 2%;
  top: 12%;
  z-index: 2;
  text-align: center;
  animation: gradient 15s ease infinite;
  background: linear-gradient(45deg, #000000, #111111, #222222, #333333, #444444, #555555);
  background-size: 400%, 400%;
  box-shadow: 0 0 4px 2px #333333;
  overflow: hidden;
  font-family:'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif
}

.slideLeft-enter-active, .slideLeft-leave-active {
  transition: opacity .5s;
  transition: all 0.8s;

}
.slideLeft-enter-from, .slideLeft-leave-to{
  opacity: 0;
  transform: translateX(-100px);
}

@keyframes gradient {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
    100% {
  background-position: 0% 50%;
  }
}

#publicMessageTicker {
  z-index: 3;
  position: absolute;
  bottom:0px;
  width:100%;
  background-color: rgb(255, 255, 125);
  color: black;
  font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
  text-align: bottom;
  font-size: 17px;
}
</style>
