import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
import vueDebounce from 'vue-debounce'
import { mapMutations, mapActions } from 'vuex';
import { markdown, markdownInline } from './lib/markdown';
import { geometryAsString } from './lib/utils';
import { mapGetters } from 'vuex';


Vue.config.productionTip = false

Vue.use(vueDebounce);

Vue.filter('markdown', markdown);
Vue.filter('markdownInline', markdownInline);
Vue.filter('position', (str, item, opts) =>
  str
  .replace(/@POS(ITION)?@/g, geometryAsString(item, opts) || "(position unknown)")
  .replace(/@DMS@/g, geometryAsString(item, {...opts, dms:true}) || "(position unknown)")
);
// Vue.filter('position', (str, item, opts) => str.replace(/@POS(ITION)?@/, "☺"));

new Vue({
  data () {
    return {
      apiUrl: "/api",
      snack: false,
      snackText: null,
      snackColour: null,

      user: null,

      wsUrl: "/ws",
      ws: null,
      wsCredentialsCheckInterval: 300*1000, // ms
      wsCredentialsCheckTimer: null
    }
  },

  computed: {
    ...mapGetters(["jwt"])
  },

  methods: {

    async sleep (ms = 0) {
      return await new Promise( (resolve) => {
        setTimeout( resolve, ms );
      });
    },

    markdown (value) {
      return markdown(value);
    },

    markdownInline (value) {
      return markdownInline(value);
    },

    showSnack(text, colour = "primary") {
      console.log("showSnack", text, colour);
      this.$store.dispatch("showSnack", [text, colour]);
    },

    sendJwt () {
      if (this.jwt) {
        this.ws.send(JSON.stringify({ jwt: this.jwt }));
      }
    },

    initWs () {

      if (this.ws) {
        console.log("WebSocket initWs already called");
        return;
      }

      this.ws = new WebSocket(this.wsUrl);

      this.ws.addEventListener("message", (ev) => {
        const msg = JSON.parse(ev.data);
        this.processServerEvent(msg);
      });

      this.ws.addEventListener("open", (ev) => {
        console.log("WebSocket connection open", ev);
        this.sendJwt()
        this.setServerConnectionState(true);
      });

      this.ws.addEventListener("close", (ev) => {
        console.warn("WebSocket connection closed", ev);
        delete this.ws;
        this.ws = null;
        setTimeout( this.initWs, 5000 );
      });

      this.ws.addEventListener("error", (ev) => {
        console.error("WebSocket connection error", ev);
        this.ws.close();
        delete this.ws;
        this.ws = null;
        setTimeout( this.initWs, 60000 );
        this.setServerConnectionState(false);
      });

      if (this.wsCredentialsCheckTimer) {
        clearInterval(this.wsCredentialsCheckTimer);
        this.wsCredentialsCheckTimer = null;
      }

      this.wsCredentialsCheckTimer = setInterval( () => {
        this.sendJwt();
      }, this.wsCredentialsCheckInterval);

    },

    ...mapMutations(['setServerConnectionState']),
    ...mapActions(['processServerEvent'])

  },

  created () {
    this.wsUrl = location.protocol == "https:"
      ? "wss://"+location.host+this.wsUrl
      : "ws://"+location.host+this.wsUrl;

    this.$nextTick( () =>  this.initWs() );
  },

  router,
  store,
  vuetify,
  render: h => h(App)
}).$mount('#app')
