<template>
  <highcharts :options="chartOptions" />
</template>

<script>
import { Chart } from 'highcharts-vue';
import { hhMM } from '@/utilities/_sila/transformTime';

export default {
  components: {
    highcharts: Chart,
  },
  props: {
    data: {
      type: Array,
      default: () => [],
    },
    colors: {
      type: Array,
      default: () => [],
    },
    type: {
      type: String,
      default: '',
    },
    timeScale: {
      type: String,
      default: null,
    },
    warning: {
      type: Number,
      default: null,
    },
    shutdown: {
      type: Number,
      default: null,
    },
    notNormal: {
      type: Number,
      default: null,
    },
    critical: {
      type: Number,
      default: null,
    },
    float: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      categories: null,
      minRange: null,
      yMax: null,
      minTickInterval: null,
    };
  },
  computed: {
    readyData() {
      let filteredData = this.data.filter((metric) => {
        return metric.Value !== 'nan';
      });

      /*filteredData.sort((a, b) => {
        return new Date(a.Timestamp) - new Date(b.Timestamp);
      });*/

      let transform = filteredData.map((metric) => {
        let date = new Date(metric.Timestamp);
        let time = hhMM(date);
        return {
          ...metric,
          Timestamp: time,
          Value: this.float ? metric.Value : Math.round(metric.Value),
        };
      });

      return transform;
    },
    step() {
      return this.timeScale === 'hour' ? 10 : 60;
    },
    metricData() {
      let group = this.readyData.reduce(function (rv, x) {
        (rv[x['Sensor']] = rv[x['Sensor']] || []).push(x);
        return rv;
      }, {});

      let metricArr = Object.keys(group).map((key, index) => {
        let groupTime = group[key].reduce(function (rv, x) {
          (rv[x['Timestamp']] = rv[x['Timestamp']] || []).push(x);
          return rv;
        }, {});

        let arr = Object.keys(groupTime).map((key) => {
          const findAverage = (arr) => {
            const { length } = arr;
            return Math.round(
              arr.reduce((acc, val) => {
                return acc + val.Value / length;
              }, 0)
            );
          };
          return findAverage(groupTime[key]);
        });

        return {
          name: key,
          data: arr,
          color: this.colors[index],
        };
      });
      return metricArr.length > 0
        ? metricArr
        : [
            { color: '', data: [], name: '' },
            { color: '', data: [], name: '' },
          ];
    },

    metricTime() {
      let timeGroup = this.readyData.reduce(function (rv, x) {
        (rv[x['Timestamp']] = rv[x['Timestamp']] || []).push(x);
        return rv;
      }, {});

      let timeArr = Object.keys(timeGroup);

      return timeArr;
    },

    chartOptions() {
      return {
        chart: {
          type: 'spline',
          margin: [12, 50, 32, 60],
          height: '320px',
          zoomType: 'x',
        },
        title: null,
        xAxis: {
          categories: this.metricTime,
          title: null,
          labels: {
            step: this.step,
          },
          minorGridLineColor: '#1A3E5B1A',
        },
        yAxis: {
          categories: this.categories,
          min: 0,
          max: this.yMax,
          title: null,
          minRange: this.minRange,
          minTickInterval: this.minTickInterval,
          minorGridLineColor: '#1A3E5B1A',
          plotLines: this.plotLines,
          plotBands: this.plotBands,
        },
        series: this.metricData.map((item) => ({
          ...item,
          marker: {
            enabled: false,
          },
        })),
        legend: {
          enabled: false,
        },
        tooltip: {
          enabled: false,
          crosshairs: false,
        },
        plotOptions: {
          series: {
            showInLegend: true,
          },
        },
      };
    },

    plotLines() {
      let plotLines = [
        {
          color: '#F0AC0C',
          dashStyle: 'solid',
          value: this.warning,
          zIndex: '1000',
          width: 2,
        },
      ];

      switch (this.type) {
        case 'fans':
        case 'processors':
        case 'power':
        case 'memory':
          plotLines.push({
            color: '#E11717',
            dashStyle: 'solid',
            value: this.critical,
            width: 2,
            label: {
              text: this.$t('chart.thresholdFailure'),
              align: 'right',
              style: {
                fontFamily: 'Inter',
                fontSize: '12px',
                fontStyle: 'normal',
                fontWeight: '400',
                lineHeight: '16px',
                color: '#0C1C2999',
              },
            },
          });
          break;
        case 'voltage-input':
          plotLines.push({
            color: '#1A3E5B',
            dashStyle: 'solid',
            value: this.shutdown,
            width: 2,
            label: {
              text: this.$t('chart.thresholdFailure'),
              align: 'right',
              style: {
                fontFamily: 'Inter',
                fontSize: '12px',
                fontStyle: 'normal',
                fontWeight: '400',
                lineHeight: '16px',
                color: '#0C1C2999',
              },
            },
          });
          break;
        case 'voltage-output':
          plotLines.push({
            color: '#1A3E5B',
            dashStyle: 'solid',
            value: this.shutdown,
            width: 2,
            label: {
              text: this.$t('chart.thresholdFailure'),
              align: 'right',
              style: {
                fontFamily: 'Inter',
                fontSize: '12px',
                fontStyle: 'normal',
                fontWeight: '400',
                lineHeight: '16px',
                color: '#0C1C2999',
              },
            },
          });
          break;
        case 'current':
          plotLines.push({
            color: '#1A3E5B',
            dashStyle: 'solid',
            value: this.shutdown,
            width: 2,
            label: {
              text: this.$t('chart.thresholdFailure'),
              align: 'right',
              style: {
                fontFamily: 'Inter',
                fontSize: '12px',
                fontStyle: 'normal',
                fontWeight: '400',
                lineHeight: '16px',
                color: '#0C1C2999',
              },
            },
          });
          break;
        case 'psu-power':
          plotLines.push({
            color: '#1A3E5B',
            dashStyle: 'solid',
            value: this.shutdown,
            width: 2,
            label: {
              text: this.$t('chart.thresholdWarning'),
              align: 'right',
              style: {
                fontFamily: 'Inter',
                fontSize: '12px',
                fontStyle: 'normal',
                fontWeight: '400',
                lineHeight: '16px',
                color: '#0C1C2999',
              },
            },
          });
      }
      return plotLines;
    },

    plotBands() {
      let plotBands = null;

      switch (this.type) {
        case 'motherboard':
          plotBands = [
            {
              color: '#F0AC0C1A',
              dashStyle: 'solid',
              from: this.warning,
              to: Infinity,
            },
          ];
          break;
        case 'memory':
        case 'processors':
        case 'power':
          plotBands = [
            {
              color: '#F0AC0C1A',
              dashStyle: 'solid',
              from: this.warning,
              to: this.critical,
            },
            {
              color: '#FF41411A',
              dashStyle: 'solid',
              from: this.critical,
              to: Infinity,
            },
          ];
          break;
      }
      return plotBands;
    },
  },

  async created() {
    this.setOptions();
  },

  methods: {
    setOptions() {
      switch (this.type) {
        case 'fans':
          this.categories = this.setSpeed(10000);
          this.minRange = 10000;
          this.minTickInterval = 1000;
          break;
        case 'memory':
          this.categories = this.setCategories(101, 'С°');
          this.yMax = 100;
          this.minTickInterval = 25;
          break;
        case 'processors':
          this.categories = this.setCategories(101, 'С°');
          this.yMax = 100;
          this.minTickInterval = 25;
          break;
        case 'motherboard':
          this.categories = this.setCategories(101, 'С°');
          this.yMax = 100;
          this.minTickInterval = 25;
          break;
        case 'power':
          this.categories = this.setCategories(101, 'Вт');
          this.yMax = 100;
          this.minTickInterval = 25;
          break;
        case 'voltage-input':
          this.categories = this.setCategories(251, 'В');
          this.yMax = 250;
          this.minTickInterval = 25;
          break;
        case 'voltage-output':
          this.categories = this.setCategories(101, 'В');
          this.yMax = 100;
          this.minTickInterval = 25;
          break;
        case 'current':
          this.categories = this.setCategories(11, 'A');
          this.yMax = 10;
          this.minTickInterval = 2;
          break;
        case 'psu-power':
          this.categories = this.setCategories(126, 'Вт');
          this.yMax = 125;
          this.minTickInterval = 25;
      }
    },
    setCategories(count, desc) {
      const arr = [...new Array(count)].map((i, k) => `${k} ${desc}`);
      return arr;
    },
    setSpeed(count) {
      const arr = [...new Array(count)].map((i, k) => `${k}`);
      return arr;
    },
  },
};
</script>
