<script>
import { GlLoadingIcon } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { PortalTarget } from 'portal-vue';
import Filters from 'ee/security_dashboard/components/first_class_vulnerability_filters.vue';
import SecurityDashboardLayout from 'ee/security_dashboard/components/security_dashboard_layout.vue';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
import { s__ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import groupProjectsQuery from '../graphql/queries/group_projects.query.graphql';
import instanceProjectsQuery from '../graphql/queries/instance_projects.query.graphql';
import AutoFixUserCallout from './auto_fix_user_callout.vue';
import CsvExportButton from './csv_export_button.vue';
import DashboardNotConfiguredGroup from './empty_states/group_dashboard_not_configured.vue';
import DashboardNotConfiguredInstance from './empty_states/instance_dashboard_not_configured.vue';
import DashboardNotConfiguredProject from './empty_states/reports_not_configured.vue';
import GroupVulnerabilities from './first_class_group_security_dashboard_vulnerabilities.vue';
import InstanceVulnerabilities from './first_class_instance_security_dashboard_vulnerabilities.vue';
import PipelineFindings from './pipeline_findings.vue';
import ProjectPipelineStatus from './project_pipeline_status.vue';
import ProjectVulnerabilities from './project_vulnerabilities.vue';
import SurveyRequestBanner from './survey_request_banner.vue';
import VulnerabilitiesCountList from './vulnerability_count_list.vue';

export default {
  components: {
    AutoFixUserCallout,
    SecurityDashboardLayout,
    GroupVulnerabilities,
    InstanceVulnerabilities,
    ProjectVulnerabilities,
    PipelineFindings,
    Filters,
    CsvExportButton,
    SurveyRequestBanner,
    DashboardNotConfiguredGroup,
    DashboardNotConfiguredInstance,
    DashboardNotConfiguredProject,
    PortalTarget,
    ProjectPipelineStatus,
    GlLoadingIcon,
    VulnerabilitiesCountList,
  },
  mixins: [glFeatureFlagsMixin()],
  provide() {
    return {
      vulnerabilityReportAlertsPortal: this.$options.vulnerabilityReportAlertsPortal,
    };
  },
  inject: {
    dashboardType: {},
    groupFullPath: { default: undefined },
    autoFixDocumentation: { default: undefined },
    pipeline: { default: undefined },
  },
  queries: {
    [DASHBOARD_TYPES.GROUP]: groupProjectsQuery,
    [DASHBOARD_TYPES.INSTANCE]: instanceProjectsQuery,
  },
  apollo: {
    projects: {
      query() {
        return this.$options.queries[this.dashboardType];
      },
      variables() {
        return this.isGroup ? { fullPath: this.groupFullPath } : {};
      },
      update(data) {
        return this.isGroup
          ? data.group.projects.nodes
          : data.instanceSecurityDashboard.projects.nodes;
      },
      skip() {
        return !this.$options.queries[this.dashboardType];
      },
    },
  },
  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() {
      return this.isProject || this.isPipeline
        ? Boolean(this.pipeline?.id)
        : this.projects.length > 0 && this.projectsWereFetched;
    },
  },
  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'),
  },
};
</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" />
      <dashboard-not-configured-group v-if="isGroup" />
      <dashboard-not-configured-instance v-else-if="isInstance" />
      <dashboard-not-configured-project v-else-if="isProject" />
    </template>
    <template v-else>
      <portal-target :name="$options.vulnerabilityReportAlertsPortal" multiple />
      <auto-fix-user-callout
        v-if="shouldShowAutoFixUserCallout"
        :help-page-path="autoFixDocumentation"
        @close="handleAutoFixUserCalloutClose"
      />
      <security-dashboard-layout>
        <template v-if="!isPipeline" #header>
          <survey-request-banner class="gl-mt-5" />
          <header class="gl-my-6 gl-display-flex gl-align-items-center">
            <h2 class="gl-flex-grow-1 gl-my-0">
              {{ $options.i18n.title }}
            </h2>
            <csv-export-button />
          </header>
          <project-pipeline-status v-if="isProject" 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" />
      </security-dashboard-layout>
    </template>
  </div>
</template>
