<script>
import { GlLink, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { PortalTarget } from 'portal-vue';
import groupProjectsQuery from 'ee/security_dashboard/graphql/queries/group_projects.query.graphql';
import instanceProjectsQuery from 'ee/security_dashboard/graphql/queries/instance_projects.query.graphql';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
import { s__ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import GroupVulnerabilities from '../group/group_vulnerabilities.vue';
import InstanceVulnerabilities from '../instance/instance_vulnerabilities.vue';
import PipelineFindings from '../pipeline/pipeline_findings.vue';
import ProjectVulnerabilities from '../project/project_vulnerabilities.vue';
import AutoFixUserCallout from './auto_fix_user_callout.vue';
import CsvExportButton from './csv_export_button.vue';
import ReportNotConfiguredGroup from './empty_states/report_not_configured_group.vue';
import ReportNotConfiguredInstance from './empty_states/report_not_configured_instance.vue';
import ReportNotConfiguredOperational from './empty_states/report_not_configured_operational.vue';
import Filters from './filters/filters_layout.vue';
import ProjectPipelineStatus from './project_pipeline_status.vue';
import SurveyRequestBanner from './survey_request_banner.vue';
import VulnerabilitiesCountList from './vulnerability_count_list.vue';
import VulnerabilityReportLayout from './vulnerability_report_layout.vue';

export default {
  components: {
    AutoFixUserCallout,
    VulnerabilityReportLayout,
    GroupVulnerabilities,
    InstanceVulnerabilities,
    ProjectVulnerabilities,
    PipelineFindings,
    Filters,
    CsvExportButton,
    SurveyRequestBanner,
    ReportNotConfiguredGroup,
    ReportNotConfiguredInstance,
    ReportNotConfiguredOperational,
    PortalTarget,
    ProjectPipelineStatus,
    GlLink,
    GlLoadingIcon,
    GlSprintf,
    VulnerabilitiesCountList,
  },
  mixins: [glFeatureFlagsMixin()],
  provide() {
    return {
      vulnerabilityReportAlertsPortal: this.$options.vulnerabilityReportAlertsPortal,
    };
  },
  inject: {
    dashboardType: {},
    groupFullPath: { default: undefined },
    autoFixDocumentation: { default: undefined },
    dashboardDocumentation: { default: undefined },
    pipeline: { default: undefined },
  },
  apollo: {
    projects: {
      query() {
        return this.isGroup ? groupProjectsQuery : instanceProjectsQuery;
      },
      variables() {
        return this.isGroup ? { fullPath: this.groupFullPath } : {};
      },
      update(data) {
        return this.isGroup ? data.group.projects.nodes : data.instance.projects.nodes;
      },
      skip() {
        // Only run this query on the group and instance-level dashboards.
        return !(this.isGroup || this.isInstance);
      },
    },
  },
  data() {
    const shouldShowAutoFixUserCallout =
      this.dashboardType === DASHBOARD_TYPES.PROJECT &&
      this.glFeatures.securityAutoFix &&
      !Cookies.get(this.$options.autoFixUserCalloutCookieName);

    return {
      filters: null,
      projects: [],
      shouldShowAutoFixUserCallout,
    };
  },
  computed: {
    projectsWereFetched() {
      return !this.$apollo.queries.projects?.loading;
    },
    isGroup() {
      return this.dashboardType === DASHBOARD_TYPES.GROUP;
    },
    isInstance() {
      return this.dashboardType === DASHBOARD_TYPES.INSTANCE;
    },
    isProject() {
      return this.dashboardType === DASHBOARD_TYPES.PROJECT;
    },
    isPipeline() {
      return this.dashboardType === DASHBOARD_TYPES.PIPELINE;
    },
    shouldShowSurvey() {
      return !this.isPipeline;
    },
    isDashboardConfigured() {
      // Projects can have manually created vulnerabilities, so we always show the report
      if (this.isProject) {
        return true;
      }

      if (this.isPipeline) {
        return Boolean(this.pipeline?.id);
      }

      // Group and Instance Dashboards
      return this.projects.length > 0;
    },
    shouldShowPipelineStatus() {
      return this.isProject && Boolean(this.pipeline);
    },
  },
  methods: {
    handleFilterChange(filters) {
      this.filters = filters;
    },
    handleAutoFixUserCalloutClose() {
      Cookies.set(this.$options.autoFixUserCalloutCookieName, 'true');
      this.shouldShowAutoFixUserCallout = false;
    },
  },
  vulnerabilityReportAlertsPortal: 'vulnerability-report-alerts-portal',
  autoFixUserCalloutCookieName: 'auto_fix_user_callout_dismissed',
  i18n: {
    title: s__('SecurityReports|Vulnerability Report'),
    description: s__(
      "SecurityReports|The Vulnerability Report shows the results of the latest successful pipeline on your project's default branch, as well as vulnerabilities from your latest container scan. %{linkStart}Learn more.%{linkEnd}",
    ),
  },
};
</script>

<template>
  <div>
    <gl-loading-icon v-if="!projectsWereFetched" size="lg" class="gl-mt-6" />
    <template v-else-if="!isDashboardConfigured">
      <survey-request-banner v-if="shouldShowSurvey" class="gl-mt-5" />
      <report-not-configured-group v-if="isGroup" />
      <report-not-configured-instance v-else-if="isInstance" />
    </template>
    <template v-else>
      <portal-target :name="$options.vulnerabilityReportAlertsPortal" multiple />
      <auto-fix-user-callout
        v-if="shouldShowAutoFixUserCallout"
        :help-page-path="autoFixDocumentation"
        @close="handleAutoFixUserCalloutClose"
      />
      <vulnerability-report-layout>
        <template v-if="!isPipeline" #header>
          <survey-request-banner class="gl-mt-5" />
          <header class="gl-mt-6 gl-mb-3 gl-display-flex gl-align-items-center">
            <h2 class="gl-flex-grow-1 gl-my-0">
              {{ $options.i18n.title }}
            </h2>
            <csv-export-button />
          </header>
          <gl-sprintf :message="$options.i18n.description">
            <template #link="{ content }">
              <gl-link :href="dashboardDocumentation" target="_blank">
                {{ content }}
              </gl-link>
            </template>
          </gl-sprintf>
        </template>
        <template #summary>
          <project-pipeline-status
            v-if="shouldShowPipelineStatus"
            class="gl-mb-6"
            :pipeline="pipeline"
          />
          <vulnerabilities-count-list :filters="filters" />
        </template>
        <template #sticky>
          <filters :projects="projects" @filterChange="handleFilterChange" />
        </template>
        <group-vulnerabilities v-if="isGroup" :filters="filters" />
        <instance-vulnerabilities v-else-if="isInstance" :filters="filters" />
        <project-vulnerabilities v-else-if="isProject" :filters="filters" />
        <pipeline-findings v-else-if="isPipeline" :filters="filters" />

        <template #operational-empty-state>
          <report-not-configured-operational />
        </template>
      </vulnerability-report-layout>
    </template>
  </div>
</template>
