<script>
import { API } from "./Api";
import BsDashboard from "./components/BsDashboard.vue";
import BsDashboardSkeleton from "./components/BsDashboardSkeleton.vue";
import Shapley from "./components/Shapley.vue";
import { useQuasar } from "quasar";

export default {
  components: {
    BsDashboardSkeleton,
    BsDashboard,
    Shapley,
    useQuasar,
  },
  data() {
    return {
      page: "1",
      dashboard: { 1: {}, 2: {}, 3: {} },
      filters: { 1: {}, 2: {}, 3: {} },
      filterSelection: { 1: {}, 2: {}, 3: {} },
      scenarioParams: { 1: {}, 2: {}, 3: {} },
      scenarioSelection: { 1: {}, 2: {}, 3: {} },
      scenarioRunning: { 1: false, 2: false, 3: false },
      dashboardLoading: { 1: true, 2: true, 3: true },
      metrics: { 1: {}, 2: {}, 3: {} },
      explanations: {},
      failure_risk: 0,
      $q: useQuasar(),
    };
  },
  created() {
    this.loadPage();
  },
  methods: {
    loadPage(page) {
      this.scenarioRunning = false;
      if (this.page == "1") {
        this.dashboard[this.page] = {};
        API.getBatchPage(this.filterSelection[this.page]).then((response) => {
          this.dashboard[this.page] = response.dashboard;
          this.dashboardLoading[this.page] = false;
          this.metrics[this.page] = response.metrics;
          this.filters[this.page] = response.filters;
          if (Object.keys(this.filterSelection[this.page]).length === 0) {
            this.filters[this.page].forEach((element) => {
              this.filterSelection[this.page][element.name] = element.values;
            });
          }
        });
      } else if (this.page == "2") {
        this.dashboard[this.page] = {};
        API.getSensorScenarioParams().then((response) => {
          this.scenarioParams[this.page] = response;
          this.scenarioParams[this.page].forEach((element) => {
            this.scenarioSelection[this.page][element.name] = element.selection;
          });
        });
        API.getSensorPage(this.filterSelection[this.page]).then((response) => {
          this.dashboard[this.page] = response.dashboard;
          this.dashboardLoading[this.page] = false;
          this.filters[this.page] = response.filters;
          if (Object.keys(this.filterSelection[this.page]).length === 0) {
            this.filters[this.page].forEach((element) => {
              this.filterSelection[this.page][element.name] = element.values;
            });
          }
        });
      } else if (this.page == "3") {
        this.dashboard[this.page] = {};
        API.getPredictionScenarioParams().then((response) => {
          this.scenarioParams[this.page] = response;
          this.scenarioParams[this.page].forEach((element) => {
            this.scenarioSelection[this.page][element.name] = element.selection;
          });
        });
        API.getPrediction().then((response) => {
          this.dashboardLoading[this.page] = false;
          this.explanations = response.explanations;
          this.failure_risk = response.failure_risk;
        });
      }
    },
    filterChanged(value, filterName) {
      this.dashboard[this.page] = {};
      this.dashboardLoading[this.page] = true;
      this.filterSelection[this.page][filterName] = value;
      if (this.page == "1") {
        API.getBatchPage(this.filterSelection[this.page]).then((response) => {
          this.dashboard[this.page] = response.dashboard;
          this.dashboardLoading[this.page] = false;
          this.metrics[this.page] = response.metrics;
        });
      } else if (this.page == "2") {
        API.getSensorPage(this.filterSelection[this.page]).then((response) => {
          this.dashboard[this.page] = response.dashboard;
          this.dashboardLoading[this.page] = false;
        });
      }
    },
    runScenario() {
      this.scenarioRunning = true;
      const notif = this.$q.notify({
        message: "Waiting for the scenario to complete...",
        type: "ongoing",
        position: "bottom",
      });
      if (this.page == "2") {
        API.setSensorScenarioParams(this.scenarioSelection[this.page]).then(
          (response) => {
            notif({
              type: "positive",
              message: "Scenario complete.",
              timeout: 500,
            });
            this.dashboardLoading[this.page] = true;
            this.filterSelection[this.page] = {};
            this.loadPage(this.page);
          },
          (err) => {
            notif({
              message:
                "Scenario failed. Check the 'Jobs' tab for more information.",
              type: "negative",
              timeout: 1000,
            });
            this.dashboardLoading[this.page] = true;
            this.loadPage(this.page);
          }
        );
      } else if (this.page == "3") {
        API.setPredictionScenarioParams(this.scenarioSelection[this.page]).then(
          (response) => {
            notif({
              type: "positive",
              message: "Scenario complete.",
              timeout: 500,
            });
            this.dashboardLoading[this.page] = true;
            this.loadPage(this.page);
          },
          (err) => {
            this.$q.notify({
              message:
                "Scenario failed. Check the 'Jobs' tab for more information.",
              color: "red",
              position: "top",
            });
            this.dashboardLoading[this.page] = true;
            this.loadPage(this.page);
          }
        );
      }
    },
  },
};
</script>
<template>
  <BsLayoutDefault
    :header="true"
    :leftpanel="this.page != 3"
    :doc="false"
    v-cloak
  >
    <template #header>
      <div>
        <q-tabs
          v-model="page"
          dense
          class="text-grey"
          :style="
            page >= 2 ? 'border-bottom: 1px solid rgba(0, 0, 0, 0.12' : ''
          "
          active-color="primary"
          indicator-color="primary"
          align="justify"
          narrow-indicator
          @update:model-value="
            (value) => {
              dashboardLoading[value] = true;
              loadPage(value);
            }
          "
        >
          <q-tab name="1" label="General Analysis"></q-tab>
          <q-tab name="2" label="Sensor Values Analysis"></q-tab>
          <q-tab name="3" label="Next Batch Prediction"></q-tab>
        </q-tabs>
      </div>

      <div
        class="fit row wrap items-center justify-left q-gutter-sm"
        v-if="page >= 2"
      >
        <div
          v-for="param in scenarioParams[this.page]"
          :key="param.name"
          class="q-pa-md"
        >
          <div v-if="param.type == 'string'" class="row">
            <BsSelect
              v-model="scenarioSelection[this.page][param.name]"
              :bsLabel="param.name"
              :options="param.values"
              style="width: 230px"
            >
            </BsSelect>
          </div>
        </div>

        <BsButton
          class="bs-btn dku-text"
          :loading="scenarioRunning"
          :disabled="scenarioRunning"
          style="margin: 10px; margin-top: 40px; padding-right: 14px"
          @click="runScenario()"
        >
          <q-icon left name="play_arrow" />
          Run the analysis
          <template v-slot:loading>
            <q-spinner-gears class="on-left" />
            Computing
          </template>
        </BsButton>
      </div>
    </template>
    <template #leftpanel>
      <div class="q-pa-sm">
        <div class="dku-grand-title-sb">Filters</div>
        <div
          v-for="filter in filters[this.page]"
          :key="filter.name"
          class="q-pa-md"
        >
          <div v-if="filter.type == 'string'" class="row">
            <BsSelect
              :bsLabel="filter.name"
              :model-value="filterSelection[this.page][filter.name]"
              @update:model-value="(value) => filterChanged(value, filter.name)"
              :debounce="5000"
              :options="filter.values"
              class="nobold"
              multiple
              outlined
              clearable
              clear-icon="clear"
              style="width: 235px"
            >
              <template v-slot:selected>
                {{
                  filterSelection[this.page][filter.name]
                    ? filterSelection[this.page][filter.name].length
                    : 0
                }}
                selected items</template
              >
              <template
                v-slot:option="{ itemProps, opt, selected, toggleOption }"
              >
                <q-item v-bind="itemProps">
                  <q-item-section>
                    <q-item-label v-html="opt"></q-item-label>
                  </q-item-section>
                  <q-item-section side>
                    <q-checkbox
                      :model-value="selected"
                      @update:model-value="toggleOption(opt)"
                    ></q-checkbox>
                  </q-item-section>
                </q-item>
              </template>
            </BsSelect>
          </div>
          <div v-else-if="filter.type == 'date'" class="row">
            <BsDateRange
              v-model="filterSelection[this.page][filter.name]"
              :bsLabel="filter.name"
              style="width: 235px"
              @update:model-value="(value) => filterChanged(value, filter.name)"
            ></BsDateRange>
          </div>
          <div v-else-if="filter.type == 'boolean'" class="row">
            <BsToggle
              v-model="filterSelection[this.page][filter.name]"
              :labelLeft="filter.label"
              color="#3B99FC"
              @update:model-value="(value) => filterChanged(value, filter.name)"
            />
          </div>
        </div>
      </div>
    </template>
    <template #content>
      <div class="kpi-wrapper justify-center" v-if="page == 1">
        <q-card class="kpi" v-for="metric in metrics[this.page]">
          <q-card-section class="bg-primary text-white">
            <div class="text-h8">{{ metric.name }}</div>
          </q-card-section>

          <q-card-actions align="right">
            <div class="text-h4">{{ metric.value }}</div>
          </q-card-actions>
        </q-card>
      </div>
      <BsDashboard
        :title="dashboard[this.page].title"
        :charts="dashboard[this.page].charts"
        v-if="page < 3 && this.dashboardLoading[this.page] == false"
      ></BsDashboard>
      <BsDashboardSkeleton
        :fakeCharts="[1, 2, 3]"
        v-if="page < 3 && this.dashboardLoading[this.page] == true"
      ></BsDashboardSkeleton>
      <div class="ShapleyWrapper" v-if="page == 3">
        <Shapley
          :explanations="this.explanations"
          :prediction="this.dashboard[this.page].charts"
          :failure_risk="this.failure_risk"
        >
        </Shapley>
      </div>
    </template>
  </BsLayoutDefault>
</template>

<style>
.nobold .q-field__native {
  font-weight: 400 !important;
}
.kpi {
  width: 100%;
  max-width: 250px;
  margin: 10px;
}
.kpi-wrapper {
  display: flex;
}
.q-page-container {
  min-height: inherit !important;
}
</style>
