<template>
  <div class="q-pa-md row items-start q-gutter-md">
    <q-card class="dispatch-controller" flat bordered v-if="dispatchInfo != null">

      <q-card-section>
        <div class="text-overline text-orange-9">
          {{ moment(dispatchInfo.submissionDate).format("YYYY-MM-DD HH:mm:ss") }}
        </div>
        <div class="text-h7 q-mt-sm q-mb-xs text-grey">
          <q-btn :icon="(status === 'PAUSED' || status === 'SCHEDULED_PAUSE') ? 'play_arrow' : 'pause'" size="xs" dense v-if="canCancel" @click="pauseResume"></q-btn>
          <q-btn icon="cancel" size="xs" dense v-if="canCancel" @click="cancel"></q-btn>
          Stare: {{ statusText }}
        </div>
        <q-linear-progress size="25px" stripe rounded :value="progress" color="primary" class="q-mt-sm">
          <div class="absolute-full flex flex-center">
            <q-badge color="white" text-color="primary" :label="progressLabel"></q-badge>
          </div>
        </q-linear-progress>
        <q-linear-progress size="25px" stripe rounded :value="deliveryProgress" color="secondary" class="q-mt-sm" v-if="askForDeliveryReport">
          <div class="absolute-full flex flex-center">
            <q-badge color="white" text-color="primary" :label="deliveryProgressLabel"></q-badge>
          </div>
        </q-linear-progress>
        <div class="text-caption text-grey" v-if="sendFailedCount != null && sendFailedCount > 0">
          Expedieri eșuate: {{ sendFailedCount }}
          <q-icon name="warning"></q-icon>
        </div>
        <div class="text-caption text-grey" v-else>
          Nici-o expediere eșuată
        </div>
        <template v-if="askForDeliveryReport">
          <div class="text-caption text-grey" v-if="deliveryFailedCount != null && deliveryFailedCount > 0">
            Livrări eșuate: {{ deliveryFailedCount }}
            <q-icon name="warning"></q-icon>
          </div>
          <div class="text-caption text-grey" v-else>
            Nici-o livrare eșuată
          </div>
        </template>
        <div class="text-caption text-grey">
          Pauză între expedieri: {{ pauseBetweenMessagesSeconds }} secunde
        </div>
      </q-card-section>

      <q-card-actions>
        <q-btn
            color="grey"
            round
            flat
            dense
            :icon="expanded ? 'keyboard_arrow_up' : 'keyboard_arrow_down'"
            @click="expanded = !expanded"
        />
      </q-card-actions>

      <q-slide-transition>
        <div v-show="expanded">
          <q-separator></q-separator>
          <q-card-section class="text-subtitle2">
            <div class="text-caption text-grey">
              <div>
                Numar mesaje: {{ dispatchInfo.totalMessageCount }}
              </div>
              <div v-for="(count, status) in dispatchInfo.messagesCountsByStatus">
                {{ status }}: {{ count }}
              </div>
            </div>
          </q-card-section>
        </div>
      </q-slide-transition>
    </q-card>
  </div>
</template>


<script>
module.exports = {
  name: "DispatchController",
  data() {
    return {
      dispatchInfo: null,
      subscription: null,
      expanded: false,
      finishNotified: false,
      statusInterval: null
    };
  },
  props: {
    dispatchUuid: String,
    stompClient: Object,
    connected: Boolean
  },
  computed: {
    askForDeliveryReport() {
      if (this.dispatchInfo == null) {
        return false;
      } else {
        return this.dispatchInfo.askForDeliveryReport;
      }
    },
    pauseBetweenMessagesSeconds() {
      if (this.dispatchInfo == null) {
        return 0;
      } else {
        return this.dispatchInfo.pauseBetweenMessagesSeconds;
      }
    },
    status() {
      if (this.dispatchInfo == null)
        return "";
      return Object.keys(this.dispatchInfo.status)[0];
    },
    statusText() {
      switch (this.status) {
        case "REQUESTED":
          return "SOLICITAT";
        case "IN_PROGRESS":
          return "ACTIV";
        case "CANCELLED":
          return "ANULAT";
        case "PAUSED":
          return "PAUZĂ";
        case "SCHEDULED_PAUSE":
          return "ÎN AFARA ORARULUI";
        case "COMPLETED":
          return "TERMINAT";
        default:
            return status;
      }
    },
    sent() {
      if (this.dispatchInfo == null) {
        return 0;
      }
      var byStatus = this.dispatchInfo.messagesCountsByStatus;
      return (byStatus["SENT"] || 0) +
        (byStatus["SENDING_FAILED"] || 0) +
        (byStatus["DELIVERED"] || 0) +
        (byStatus["DELIVERY_FAILED"] || 0);
    },
    sendFailedCount() {
      if (this.dispatchInfo == null) {
        return null;
      }
      var byStatus = this.dispatchInfo.messagesCountsByStatus;
      return (byStatus["SENDING_FAILED"] || 0);
    },
    deliveryFailedCount() {
      if (this.dispatchInfo == null) {
        return null;
      }
      var byStatus = this.dispatchInfo.messagesCountsByStatus;
      return (byStatus["DELIVERY_FAILED"] || 0);
    },
    delivered() {
      if (this.dispatchInfo == null) {
        return 0;
      }
      var byStatus = this.dispatchInfo.messagesCountsByStatus;
      return (byStatus["DELIVERED"] || 0)/* +
        (byStatus["DELIVERY_FAILED"] || 0)*/;
    },
    progress() {
      if (this.dispatchInfo == null) {
        return 0;
      }
      return this.sent / this.dispatchInfo.totalMessageCount;
    },
    progressLabel() {
      if (this.dispatchInfo == null) {
        return "Nici-o informație";
      }
      return `${this.sent} / ${this.dispatchInfo.totalMessageCount}`;
    },
    deliveryProgress() {
      if (this.dispatchInfo == null) {
        return 0;
      }
      return this.delivered / this.dispatchInfo.totalMessageCount;
    },
    deliveryProgressLabel() {
      if (this.dispatchInfo == null) {
        return "Nici-o informație";
      }
      return `${this.delivered} livrate`;
    },
    canCancel() {
      switch (this.status) {
        case "REQUESTED":
          return true;
        case "IN_PROGRESS":
          return true;
        case "CANCELLED":
          return false;
        case "PAUSED":
          return true;
        case "SCHEDULED_PAUSE":
          return true;
        case "COMPLETED":
          return false;
      }
    }
  },
  watch: {
    dispatchUuid: {
      immediate: true,
      handler(newDispatchUuid, oldDispatchUuid) {
        if (this.dispatchUuid != null) {
          this.finishNotified = false;
          this.dispatchInfo = null;
          if (oldDispatchUuid != null) {
            this.stompClient.unsubscribe("/user/topic/dispatch/" + oldDispatchUuid + "/status-updates");
          }
          this.subscription = this.stompClient.subscribe(
              "/user/topic/dispatch/" + this.dispatchUuid + "/status-updates",
              (message) => {
                this.dispatchInfo = message.data;
                this.checkIfFinishedUnnotified();
              }
          );
          this.updateStatus();
        }
      }
    }
  },
  methods: {
    updateStatus() { // used when delivery updates are requested
      if (this.dispatchUuid != null) {
        if (this.dispatchInfo != null && this.askForDeliveryReport) {
          // check status
          var status = Object.keys(this.dispatchInfo.status)[0];
          if (status !== "COMPLETED") {
            return;
          }
          // check if already finished, stop requesting updates
          var mc = this.dispatchInfo.messagesCountsByStatus;
          if ((mc["CREATED"] || 0) + (mc["ALLOCATED"] || 0) + (mc["RESERVED"] || 0) + (mc["SENT"] || 0) === 0) { // everything's been sent
            return; // no need to request a status update anymore
          }
        }
        axios.get('/api/v1/sms/status/' + this.dispatchUuid)
            .then(response => {
              this.dispatchInfo = response.data;
              this.checkIfFinishedUnnotified();
            });
      }
    },
    checkIfFinishedUnnotified() {
      if (this.dispatchInfo != null && !this.finishNotified) {
        if (Object.keys(this.dispatchInfo.status)[0] === "COMPLETED" || Object.keys(this.dispatchInfo.status)[0] === "CANCELLED") {
          this.finishNotified = true;
          this.$emit("sending-finished");
        }
      }
    },
    moment(timestamp) {
      return moment(timestamp);
    },
    cancel() {
      this.pause();
      this.$q.dialog({
        title: "Confirmare",
        message: "Sigur doriți să anulați aceată expediere ?",
        cancel: true,
        persistent: true
      })
          .onOk(() => {
            this.stompClient.sendJson(
                "/app/sms/dispatches/" + this.dispatchUuid + "/" + "cancel",
                {}
            );
          });

    },
    pause() {
      this.stompClient.sendJson(
          "/app/sms/dispatches/" + this.dispatchUuid + "/pause",
          {}
      );
    },
    resume() {
      this.stompClient.sendJson(
          "/app/sms/dispatches/" + this.dispatchUuid + "/resume",
          {}
      );
    },
    pauseResume() {
      ((this.status === "PAUSED" || this.status === "SCHEDULED_PAUSE") ? this.resume : this.pause)();
    }
  },
  created() {
    this.statusInterval = setInterval(() => {
      this.updateStatus()
    }, 15000); // update status once in a while, in case workers are gone and the delivery information has changed
  },
  beforeDestroy() {
    clearInterval(this.statusInterval);
  }
}

</script>

<style scoped>
  .dispatch-controller {
    width: 100%;
    min-width: 200px;
    max-width: 400px;
  }

  .row, .col {
    padding: 0 !important;
  }
</style>

<style>
</style>