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

<script>
import { Chart } from 'highcharts-vue';

export default {
  components: {
    highcharts: Chart,
  },
  props: {
    data: {
      type: Array,
      default: () => [],
    },
    colors: {
      type: Array,
      default: () => [],
    },
    type: {
      type: String,
      default: '',
    },
    timeScale: {
      type: String,
      default: 'hour',
    },
    warning: {
      type: Number,
      default: 70,
    },
    shutdown: {
      type: Number,
      default: 3150,
    },
    nonNormal: {
      type: Number,
      default: 70,
    },
    criticalStart: {
      type: Number,
      default: 70,
    },
  },
  data() {
    return {
      categories: null,
      minRange: null,
      yMax: null,
      minTickInterval: null,
      plotBands: null,
    };
  },
  computed: {
    step() {
      return this.timeScale === 'hour' ? 10 : 1;
    },
    metricData() {
      let filteredData = this.data.filter((metric) => {
        return metric.MetricValue !== 'nan';
      });

      let transform = filteredData.map((metric) => {
        let date = new Date(metric.Timestamp);
        let time;
        if (this.timeScale === 'hour') {
          time =
            date.getHours() + ':' + String(date.getMinutes()).padStart(2, '0');
        } else {
          time = date.getHours() + ':00';
        }
        return {
          ...metric,
          Timestamp: time,
          MetricValue: Math.round(metric.MetricValue),
        };
      });

      let group = transform.reduce(function (rv, x) {
        (rv[x['MetricProperty']] = rv[x['MetricProperty']] || []).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.MetricValue / length;
              }, 0)
            );
          };
          return findAverage(groupTime[key]);
        });

        return {
          name: key,
          data: arr,
          color: this.colors[index],
        };
      });

      return metricArr;
    },

    metricTime() {
      let filteredData = this.data.filter((metric) => {
        return metric.MetricValue !== 'nan';
      });

      let transform = filteredData.map((metric) => {
        let date = new Date(metric.Timestamp);
        let time;
        if (this.timeScale === 'hour') {
          time =
            date.getHours() + ':' + String(date.getMinutes()).padStart(2, '0');
        } else {
          time = date.getHours() + ':00';
        }
        return {
          ...metric,
          Timestamp: time,
          MetricValue: Math.round(metric.MetricValue),
        };
      });

      let timeGroup = transform.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: 'line',
          margin: [12, 50, 32, 60],
          height: '320px',
        },
        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: [
            {
              color: '#E11717',
              dashStyle: 'solid',
              value: this.warning,
              zIndex: '1000',
              width: 2,
              label: {
                text: 'Пороговое значение предупреждения',
                align: 'right',
                style: {
                  fontFamily: 'Inter, sans-serif',
                  fontSize: '12px',
                  fontStyle: 'normal',
                  fontWeight: '400',
                  lineHeight: '16px',
                  color: '#0C1C2999',
                },
              },
            },
          ],
          plotBands: this.plotBands,
        },
        series: this.metricData.map((item) => ({
          ...item,
          marker: {
            enabled: false,
          },
        })),
        legend: {
          enabled: false,
        },
        tooltip: {
          enabled: false,
          crosshairs: false,
        },
        plotOptions: {
          series: {
            showInLegend: true,
          },
        },
      };
    },
  },

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

  methods: {
    setOptions() {
      switch (this.type) {
        case 'fans':
          this.categories = this.setSpeed(4000);
          this.minRange = 4000;
          this.minTickInterval = 1000;
          this.plotBands = [
            {
              color: '#F0AC0C1A',
              dashStyle: 'solid',
              from: this.nonNormal,
              to: this.criticalStart,
            },
            {
              color: '#FF41411A',
              dashStyle: 'solid',
              from: this.criticalStart,
              to: this.warning,
            },
          ];
          break;
        case 'memory':
          this.categories = this.setCategories(101, 'С°');
          this.yMax = 100;
          this.minTickInterval = 25;
          this.plotBands = [
            {
              color: '#F0AC0C1A',
              dashStyle: 'solid',
              from: this.nonNormal,
              to: this.criticalStart,
            },
            {
              color: '#FF41411A',
              dashStyle: 'solid',
              from: this.criticalStart,
              to: this.warning,
            },
          ];
          break;
        case 'processors':
          this.categories = this.setCategories(101, 'С°');
          this.yMax = 100;
          this.minTickInterval = 25;
          this.plotBands = [
            {
              color: '#F0AC0C1A',
              dashStyle: 'solid',
              from: this.nonNormal,
              to: this.criticalStart,
            },
            {
              color: '#FF41411A',
              dashStyle: 'solid',
              from: this.criticalStart,
              to: this.warning,
            },
          ];
          break;
        case 'motherboard':
          this.categories = this.setCategories(101, 'С°');
          this.yMax = 100;
          this.minTickInterval = 25;
          break;
      }
    },
    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>
<style lang="scss">
.highcharts-credits {
  display: none;
}

.highcharts-plot-line-label {
  transform: translate(-8px, 0) !important;
}
</style>
