<script>
import { mapState, mapGetters, mapActions } from 'vuex';

import dateFormat from 'dateformat';
import { GlTooltipDirective, GlTable } from '@gitlab/ui';
import { GlSparklineChart } from '@gitlab/ui/dist/charts';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
import { s__, sprintf } from '~/locale';

import { firstAndLastY } from '~/lib/utils/chart_utils';
import { formattedChangeInPercent } from '~/lib/utils/number_utils';
import { differenceInMilliseconds, millisecondsPerDay } from '~/lib/utils/datetime_utility';
import ChartButtons from './vulnerability_chart_buttons.vue';

import { DAYS } from '../store/modules/vulnerabilities/constants';
import { SEVERITY_LEVELS } from '../store/constants';

export default {
  name: 'VulnerabilityChart',
  components: {
    ChartButtons,
    GlSparklineChart,
    GlTable,
    SeverityBadge,
  },
  directives: {
    GlTooltip: GlTooltipDirective,
  },
  DAYS,
  fields: [
    { key: 'severityLevel', label: s__('VulnerabilityChart|Severity'), tdClass: 'border-0' },
    { key: 'chartData', label: '', tdClass: 'border-0 w-100' },
    { key: 'changeInPercent', label: '%', thClass: 'text-right', tdClass: 'border-0 text-right' },
    {
      key: 'currentVulnerabilitiesCount',
      label: '#',
      thClass: 'text-right',
      tdClass: 'border-0 text-right',
    },
  ],
  severityLevels: [
    SEVERITY_LEVELS.critical,
    SEVERITY_LEVELS.high,
    SEVERITY_LEVELS.medium,
    SEVERITY_LEVELS.low,
  ],
  computed: {
    ...mapState('vulnerabilities', [
      'vulnerabilitiesHistory',
      'vulnerabilitiesHistoryDayRange',
      'vulnerabilitiesHistoryMaxDayInterval',
    ]),
    ...mapGetters('vulnerabilities', ['getFilteredVulnerabilitiesHistory']),
    charts() {
      const { severityLevels } = this.$options;

      return severityLevels.map(severityLevel => {
        const history = this.getFilteredVulnerabilitiesHistory(severityLevel);
        const chartData = history.length ? history : this.emptyDataSet;

        const [pastVulnerabilitiesCount, currentVulnerabilitiesCount] = firstAndLastY(chartData);

        const changeInPercent = formattedChangeInPercent(
          pastVulnerabilitiesCount,
          currentVulnerabilitiesCount,
        );

        return {
          severityLevel,
          chartData,
          currentVulnerabilitiesCount,
          changeInPercent,
        };
      });
    },
    startDate() {
      return differenceInMilliseconds(millisecondsPerDay * 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];
    },
    emptyDataSet() {
      const format = 'isoDate';
      const formattedStartDate = dateFormat(this.startDate, format);
      const formattedEndDate = dateFormat(Date.now(), format);

      return [[formattedStartDate, 0], [formattedEndDate, 0]];
    },
  },
  methods: {
    ...mapActions('vulnerabilities', ['setVulnerabilitiesHistoryDayRange']),
  },
};
</script>

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

    <gl-table
      :fields="$options.fields"
      :items="charts"
      :borderless="true"
      thead-class="thead-white"
      class="js-vulnerabilities-chart-severity-level-breakdown mb-2"
    >
      <template #head(changeInPercent)="{ label }">
        <span v-gl-tooltip :title="__('Difference between start date and now')">{{ label }}</span>
      </template>

      <template #head(currentVulnerabilitiesCount)="{ label }">
        <span v-gl-tooltip :title="__('Current vulnerabilities count')">{{ label }}</span>
      </template>

      <template #cell(severityLevel)="{ value }">
        <severity-badge :ref="`severityBadge${value}`" :severity="value" />
      </template>
      <template #cell(chartData)="{ item }">
        <div class="position-relative h-32-px">
          <gl-sparkline-chart
            :ref="`sparklineChart${item.severityLevel}`"
            :height="32"
            :data="item.chartData"
            :tooltip-label="__('Vulnerabilities')"
            :show-last-y-value="false"
            class="position-absolute w-100 position-top-0 position-left-0"
          />
        </div>
      </template>
      <template #cell(changeInPercent)="{ value }">
        <span ref="changeInPercent">{{ value }}</span>
      </template>
      <template #cell(currentVulnerabilitiesCount)="{ value }">
        <span ref="currentVulnerabilitiesCount">{{ value }}</span>
      </template>
    </gl-table>
  </section>
</template>
