<script>
import _ from 'underscore';
import dateFormat from 'dateformat';
import { mapState, mapGetters, mapActions } from 'vuex';
import GlLineChart from '@gitlab/ui/dist/components/charts/line/line';
import { __, s__, sprintf } from '~/locale';
import ChartTooltip from './vulnerability_chart_tooltip.vue';
import ChartButtons from './vulnerability_chart_buttons.vue';
import { DAY_IN_MS, DAYS } from '../store/modules/vulnerabilities/constants';
import { SEVERITY_LEVELS } from '../store/constants';
import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue';

export default {
  name: 'VulnerabilityChart',
  components: {
    GlLineChart,
    ChartTooltip,
    ChartButtons,
    ResizableChartContainer,
  },
  DAYS,
  data: () => ({
    tooltipTitle: '',
    tooltipEntries: [],
    lines: [
      {
        name: SEVERITY_LEVELS.critical,
        color: '#C0341D',
      },
      {
        name: SEVERITY_LEVELS.high,
        color: '#DE7E00',
      },
      {
        name: SEVERITY_LEVELS.medium,
        color: '#6E49CB',
      },
      {
        name: SEVERITY_LEVELS.low,
        color: '#4F4F4F',
      },
      {
        name: __('Total'),
        color: '#1F78D1',
      },
    ],
  }),
  computed: {
    ...mapState('vulnerabilities', [
      'vulnerabilitiesHistory',
      'vulnerabilitiesHistoryDayRange',
      'vulnerabilitiesHistoryMaxDayInterval',
    ]),
    ...mapGetters('vulnerabilities', ['getFilteredVulnerabilitiesHistory']),
    series() {
      return this.lines.map(line => {
        const { name, color } = line;
        const data = this.getFilteredVulnerabilitiesHistory(name);

        return {
          color,
          lineStyle: {
            color,
          },
          data,
          name,
        };
      });
    },
    options() {
      return {
        grid: {
          bottom: 30,
          left: 30,
          right: 20,
          top: 10,
        },
        tooltip: {
          formatter: this.renderTooltip,
          padding: 0,
          trigger: 'axis',
        },
        xAxis: {
          axisLabel: {
            color: '#707070',
            formatter: date => dateFormat(date, 'd mmm'),
            margin: 8,
          },
          maxInterval: DAY_IN_MS * this.vulnerabilitiesHistoryMaxDayInterval,
          min: this.startDate,
          type: 'time',
        },
        yAxis: {
          axisLabel: {
            color: '#707070',
          },
          boundaryGap: [0, '5%'],
          minInterval: 1,
          type: 'value',
        },
      };
    },
    startDate() {
      return Date.now() - DAY_IN_MS * this.vulnerabilitiesHistoryDayRange;
    },
    dateInfo() {
      const formattedStartDate = dateFormat(this.startDate, 'mmmm dS');

      return sprintf(s__('VulnerabilityChart|%{formattedStartDate} to today'), {
        formattedStartDate,
      });
    },
    days() {
      const { $options } = this;
      return [$options.DAYS.THIRTY, $options.DAYS.SIXTY, $options.DAYS.NINETY];
    },
  },
  methods: {
    ...mapActions('vulnerabilities', ['setVulnerabilitiesHistoryDayRange']),
    noop: _.noop, // Used to tell line-chart to render external tooltip
    renderTooltip(params) {
      this.tooltipTitle = dateFormat(params[0].axisValue, 'd mmmm');
      this.tooltipEntries = params;
      return ' ';
    },
  },
};
</script>

<template>
  <section class="border rounded p-3">
    <header>
      <h4 class="mt-0 mb-1">
        {{ __('Vulnerabilities over time') }}
      </h4>
      <p class="text-secondary mt-0 js-vulnerabilities-chart-time-info">
        {{ dateInfo }}
      </p>
    </header>
    <div class="align-self-center mb-3">
      <chart-buttons
        :days="days"
        :active-day="vulnerabilitiesHistoryDayRange"
        @click="setVulnerabilitiesHistoryDayRange"
      />
    </div>

    <div class="vulnerabilities-chart">
      <div class="vulnerabilities-chart-wrapper">
        <resizable-chart-container>
          <gl-line-chart
            slot-scope="{ width }"
            class="js-vulnerabilities-chart-line-chart"
            :width="width"
            :option="options"
            :data="series"
            :format-tooltip-text="noop"
            :include-legend-avg-max="true"
          >
            <span slot="tooltipTitle">{{ tooltipTitle }}</span>
            <chart-tooltip slot="tooltipContent" :entries="tooltipEntries" />
          </gl-line-chart>
        </resizable-chart-container>
      </div>
    </div>
  </section>
</template>
