<template>
  <collapse
    id="collapse_FansCpu"
    :class="{ disabledDiv: (loading || isPageLoading) && opened }"
    :title="$t('pageFans.speed')"
    :opened="true"
    @opened="onOpened"
  >
    <template #image>
      <img src="@/assets/images/_sila/collapsed/fan.svg" />
    </template>
    <page-section>
      <b-form novalidate>
        <b-row class="align-items-end limit-container">
          <b-col xs="12" md="6" xl="3" class="pt-4">
            <b-form-group :label="$t('pageFans.labels.warning')">
              <b-form-input
                v-model.number="warning"
                :disabled="$store.getters['authentication/role'] === 'ReadOnly'"
                type="number"
                :state="getValidationState($v.warning)"
                @blur="$v.warning.$touch()"
              >
              </b-form-input>
              <b-form-invalid-feedback class="absolute" role="alert">
                <div v-if="!$v.warning.between">
                  {{ $t('global.form.invalidValue') }}
                </div>
                <div v-if="!$v.warning.required">
                  {{ $t('global.form.fieldRequired') }}
                </div>
              </b-form-invalid-feedback>
            </b-form-group>
          </b-col>
          <b-col xs="12" md="6" xl="3" class="pt-4">
            <b-form-group :label="$t('pageFans.labels.critical')">
              <b-form-input
                v-model.number="critical"
                :disabled="$store.getters['authentication/role'] === 'ReadOnly'"
                type="number"
                :state="getValidationState($v.critical)"
                @blur="$v.critical.$touch()"
              ></b-form-input>
              <b-form-invalid-feedback class="absolute" role="alert">
                <div v-if="!$v.critical.between">
                  {{ $t('global.form.invalidValue') }}
                </div>
                <div v-if="!$v.critical.required">
                  {{ $t('global.form.fieldRequired') }}
                </div>
              </b-form-invalid-feedback>
            </b-form-group>
          </b-col>
          <b-col xs="12" md="6" xl="3" class="pt-4">
            <b-button
              variant="primary"
              style="height: 35px"
              :disabled="
                loading ||
                isPageLoading ||
                $store.getters['authentication/role'] === 'ReadOnly'
              "
              @click="saveLimit"
            >
              {{ $t('global.action.save') }}
            </b-button>
          </b-col>
        </b-row>
      </b-form>
      <chart
        type="fans"
        :colors="colors"
        :time-scale="timeScale"
        :data="filteredForChart"
        :warning="warningLimit"
        :critical="criticalLimit"
        :max="maxLimit"
        :opened="opened"
      ></chart>

      <b-table
        responsive="md"
        show-empty
        table-variant="accessory"
        hover
        :items="items"
        :fields="fields"
        :empty-text="$t('global.table.emptyMessage')"
        :bisy="isBusy"
      >
        <template #cell(name)="{ value, index }">
          <div
            class="item-color"
            :style="`background-color: ${colors[index]}`"
          ></div>
          {{ value }}
        </template>
        <template #cell(minDate)="{ value }">
          <span style="color: rgb(12, 28, 41)">
            {{ value.time }}
          </span>
          <span>
            {{ value.date }}
          </span>
        </template>
        <template #cell(maxDate)="{ value }">
          <span style="color: rgb(12, 28, 41)">
            {{ value.time }}
          </span>
          <span>
            {{ value.date }}
          </span>
        </template>
        <template #cell(pwm)="{ value }">
          <span>
            {{ `${value}%` }}
          </span>
        </template>
      </b-table>
    </page-section>
  </collapse>
</template>
<script>
import Chart from '@/components/_sila/Global/Chart';
import PageSection from '@/components/Global/PageSection';

import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin';
import LoadingBarMixin, {
  loading,
} from '@/components/_sila/Mixins/LoadingBarMixin';
import TableFilterMixin from '@/components/_sila/Mixins/TableFilterMixin';
import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
import Collapse from '@/components/_sila/Global/Collapse';

import { getGroups, getItems } from '@/utilities/_sila/metricProperties';
import { between, required } from 'vuelidate/lib/validators';
import { fanFilter } from '@/utilities/_sila/psuFilter';

export default {
  components: { PageSection, Chart, Collapse },
  mixins: [
    DataFormatterMixin,
    LoadingBarMixin,
    TableFilterMixin,
    BVToastMixin,
    VuelidateMixin,
  ],
  props: {
    timeScale: {
      type: String,
      default: 'hour',
    },
  },
  data() {
    return {
      loading,
      warning: null,
      critical: null,
      isBusy: false,
      opened: false,
      fields: [
        {
          key: 'name',
          label: this.$t('pageFans.table.name'),
        },
        {
          key: 'current',
          label: this.$t('pageFans.table.current'),
        },
        {
          key: 'middle',
          label: this.$t('pageFans.table.middle'),
        },
        {
          key: 'pwm',
          label: this.$t('pageFans.table.pwm'),
        },
        {
          key: 'min',
          label: this.$t('pageFans.table.min'),
        },
        {
          key: 'minDate',
          label: this.$t('pageFans.table.minDate'),
        },
        {
          key: 'max',
          label: this.$t('pageFans.table.max'),
        },
        {
          key: 'maxDate',
          label: this.$t('pageFans.table.maxDate'),
        },
      ],
    };
  },

  validations() {
    return {
      warning: {
        required,
        between: between(1, this.critical),
      },
      critical: {
        required,
        between: between(this.warning, this.maxLimit),
      },
    };
  },

  computed: {
    groups() {
      return getGroups(this.filteredForChart);
    },

    items() {
      const allArr = getItems(this.filteredSensors);

      let pwmArr = allArr.filter((item) => {
        return item.name.toLowerCase().includes('pwm');
      });

      let cpuArr = allArr.filter((item) => {
        return !item.name.toLowerCase().includes('pwm');
      });

      return cpuArr.map((cpu) => {
        let pwm = pwmArr.find((pwm) => pwm.name === this.getPwmByCpu(cpu.name))
          .middle;
        return {
          pwm,
          ...cpu,
        };
      });
    },

    limits() {
      return this.$store.getters['fan/limits'];
    },

    isPageLoading() {
      return this.$store.getters['fan/isLoading'];
    },

    warningLimit() {
      return this.limits.find((limit) => {
        return (
          limit?.UpperThresholdNonCritical &&
          this.groups.includes(limit.MemberId)
        );
      })?.UpperThresholdNonCritical;
    },

    criticalLimit() {
      return this.limits.find((limit) => {
        return (
          limit?.UpperThresholdCritical && this.groups.includes(limit.MemberId)
        );
      })?.UpperThresholdCritical;
    },

    maxLimit() {
      return this.limits.find((limit) => {
        return limit?.MaxReadingRange;
      })?.MaxReadingRange;
    },

    allSensors() {
      return this.timeScale === 'hour'
        ? this.$store.getters['fan/fansLastHour']
        : this.$store.getters['fan/fans'];
    },

    preFiltered() {
      return fanFilter(this.allSensors, 'CPU').concat(
        fanFilter(this.allSensors, 'pwm')
      );
    },

    filteredForChart() {
      return fanFilter(this.allSensors, 'CPU');
    },

    filteredSensors() {
      return this.getFilteredTableData(this.preFiltered, this.activeFilters);
    },

    colors() {
      return this.$randomColor({
        count: this.items?.length,
        hue: 'random',
        luminosity: 'random',
      });
    },
  },

  watch: {
    limits() {
      if (this.limits && this.limits.length > 0) {
        this.warning = this.warningLimit;
        this.critical = this.criticalLimit;
      }
    },

    timeScale() {
      if (!this.opened) {
        return;
      }

      this.loadData();
    },
  },

  methods: {
    saveLimit() {
      this.$v.$touch();
      if (this.$v.$invalid) return;

      this.startLoader();
      this.$store
        .dispatch('fan/patchLimits', {
          warning: this.warning,
          critical: this.critical,
          groups: this.groups,
        })
        .catch(({ message }) => this.errorToast(message))
        .finally(() => this.endLoader());
    },

    getPwmByCpu(cpu) {
      switch (cpu) {
        case 'CPU1_Fan':
          return 'Pwm_7';
        case 'CPU2_Fan':
          return 'Pwm_8';
        default:
          return null;
      }
    },

    onOpened(state) {
      if (state) {
        this.loadData();
      }
      this.opened = state;
    },

    loadData() {
      if (this.isPageLoading) {
        return;
      }

      let payload = { lastHour: false };
      if (this.timeScale === 'hour') {
        payload = { lastHour: true };
      }

      this.start();
      this.$store.dispatch('fan/getFans', payload).finally(() => {
        this.$store.dispatch('fan/getLimits').finally(() => {
          this.warning = this.warningLimit;
          this.critical = this.criticalLimit;
          this.end();
        });
      });
    },

    start() {
      this.startLoader();
      this.isBusy = true;
      this.$store.commit('fan/setIsLoading', true);
      this.$root.$emit('fan-cpu', true);
    },

    end() {
      this.endLoader();
      this.isBusy = false;
      this.$store.commit('fan/setIsLoading', false);
      this.$root.$emit('fan-cpu', false);
    },
  },
};
</script>
