import './VulnerabilityCard.scss';

import * as AppActions from '../../AppActions';

import {
    Button,
    TextContent,
    Tooltip,
    TooltipPosition
} from '@patternfly/react-core/dist/esm/components';
import { Flex } from '@patternfly/react-core/dist/esm/layouts';
import React, { useEffect } from 'react';
import { fitContent, Table, TableBody, TableHeader, TableText, textCenter } from '@patternfly/react-table';
import { TemplateCard, TemplateCardBody, TemplateCardHeader } from '../../PresentationalComponents/Template/TemplateCard';
import { useDispatch, useSelector } from 'react-redux';

import { CompoundCard } from '../../PresentationalComponents/Template/CompoundCard';
import { ExpandableCardTemplate } from '../../PresentationalComponents/Template/ExpandableCardTemplate';
import FailState from '../../PresentationalComponents/FailState/FailState';
import InfoIcon from '../../Icons/InfoIcon';
import Loading from '../../PresentationalComponents/Loading/Loading';
import { PieChart } from '../../ChartTemplates/PieChart/PieChartTemplate';
import { UI_BASE } from '../../AppConstants';
import global_disabled_color_100 from '@patternfly/react-tokens/dist/esm/global_disabled_color_100';
import messages from '../../Messages';
import { useIntl } from 'react-intl';
import { useChromePush } from '../../Utilities/hooks/useChromePush';

const VulnerabilityCard = () => {
    const intl = useIntl();
    const pieChartPadding = { bottom: 0, left: 0, right: 0, top: 0 };
    let chartData = [];
    let rows = [];
    let legendLink = [];
    const dispatch = useDispatch();
    const vulnerabilities = useSelector(({ DashboardStore }) => DashboardStore.vulnerabilities);
    const vulnerabilitiesFetchStatus = useSelector(({ DashboardStore }) => DashboardStore.vulnerabilitiesFetchStatus);
    const selectedTags = useSelector(({ DashboardStore }) => DashboardStore.selectedTags);
    const workloads = useSelector(({ DashboardStore }) => DashboardStore.workloads);
    const SID = useSelector(({ DashboardStore }) => DashboardStore.SID);
    const strong = str => <strong>{str}</strong>;

    const navigateTo = useChromePush();

    const iconTooltip = text => <Tooltip
        key={text}
        position={TooltipPosition.right}
        content={<div>{text}</div>}>
        <span aria-label='Action' className='insd-c-info-icon pf-u-ml-sm'>
            <InfoIcon />
        </span>
    </Tooltip>;

    const columns = [
        {
            title: 'CVSS score'
        },
        {
            title: 'CVE totals',
            transforms: [textCenter],
            cellTransforms: [textCenter]
        },
        {
            title: (
                <span>Known exploits{iconTooltip(intl.formatMessage(messages.exploitedCveTooltip))}</span>
            ),
            transforms: [fitContent]
        }];

    useEffect(() => {
        const options = {
            ...workloads?.SAP?.isSelected && { sap_system: true },
            ...workloads?.['Ansible Automation Platform']?.isSelected
                && { ansible: 'not_nil' },
            ...workloads?.['Microsoft SQL']?.isSelected
                && { mssql: 'not_nil' },
            ...SID?.length > 0 && { sap_sids: SID },
            ...selectedTags?.length > 0 && { tags: selectedTags }
        };
        const fetchVulnerabilities = options => dispatch(AppActions.fetchVulnerabilities(options));

        fetchVulnerabilities(options);
    }, [workloads, SID, selectedTags, dispatch]);

    if (vulnerabilitiesFetchStatus === 'fulfilled') {
        let { cves_by_severity: bySeverity } = vulnerabilities;

        chartData = [{
            x: 'CVSS 8.0 - 10',
            from: 8.0,
            to: 10.0,
            y: bySeverity['8to10'].count,
            fill: '#a30000',
            data: bySeverity['8to10']
        },
        {
            x: 'CVSS 4.0 - 7.9',
            from: 4.0,
            to: 7.9,
            y: bySeverity['4to7.9'].count,
            fill: '#ec7a08',
            data: bySeverity['4to7.9']
        },
        {
            x: 'CVSS 0.0 - 3.9',
            from: 0.0,
            to: 3.9,
            y: bySeverity['0to3.9'].count,
            fill: '#f0ab00',
            data: bySeverity['0to3.9']
        }];

        legendLink = (from, to) => `${UI_BASE}/vulnerability/cves?cvss_from=${from}&cvss_to=${to}`;

        rows = chartData.map(({ data, from, to, fill }) => [{
            title: <TableText wrapModifier='nowrap' className='insd-c-legend__dot'
                style={{ '--insd-c-legend__dot--BackgroundColor': `${fill}` }}>
                <a onClick={e => navigateTo(e, legendLink(from, to))} href={legendLink(from, to)}>{`${from}.0 - ${to}`}</a>
            </TableText>
        }, {
            title:
                <a
                    onClick={e => navigateTo(e, legendLink(from, to))}
                    href={legendLink(from, to)}
                    className='pf-u-text-align-center'
                >
                    {data.count}
                </a>,
            props: { textCenter: true }
        }, {
            title:
                <a
                    onClick={e => navigateTo(e, legendLink(from, to) + '&known_exploit=true')}
                    href={legendLink(from, to) + '&known_exploit=true'}
                    className='pf-u-text-align-center'
                >
                    {data.known_exploits === undefined ? 'N/A' : data.known_exploits}
                </a>,
            props: { textCenter: true }
        }]);
    }

    if (vulnerabilitiesFetchStatus === 'rejected') {
        return <TemplateCard isFilled={false} className='ins-c-card__vulnerability' data-ouia-safe>
            <TemplateCardHeader title={intl.formatMessage(messages.vulnerabilitiesTitle)} />
            <TemplateCardBody><FailState appName='Vulnerability' /></TemplateCardBody>
        </TemplateCard>;
    }

    return <CompoundCard className='insd-c-dashboard-card-parent insd-c-dashboard__card--compound--Vulnerabilities'
        data-ouia-safe={vulnerabilitiesFetchStatus !== 'pending'}>
        <ExpandableCardTemplate
            appName='Vulnerabilities'
            className='insd-m-toggle-right-on-md insd-m-short-header'
            data-ouia-safe={vulnerabilitiesFetchStatus !== 'pending'}
            title={intl.formatMessage(messages.vulnerabilitiesTitle)}
            isExpanded={JSON.parse(localStorage.getItem('dashboard_expanded_vulnerability1') || 'true')}
            isExpandedCallback={isExpanded => localStorage.setItem('dashboard_expanded_vulnerability1', isExpanded)}
            body={vulnerabilitiesFetchStatus === 'fulfilled' ? <TemplateCardBody className='insd-c-dashboard__card--Vulnerabilities__card-body'>
                <Flex
                    direction={{ default: 'column' }}
                    spaceItems={{ default: 'spaceItemsLg' }}
                    flexWrap={{ default: 'nowrap' }}
                >
                    <TextContent
                        className='insd-c-width-limiter'
                        style={{ '--insd-c-width-limiter--MaxWidth': '54ch' }}>
                        <p className='pf-u-font-size-sm'>
                            {intl.formatMessage(messages.vulnerabilityMessage)}
                        </p>
                    </TextContent>
                    <div className="insd-c-dashboard__card--Vulnerabilities--SplitMetrics">
                        <div className="insd-c-dashboard__card--Vulnerabilities--SplitMetrics__item">
                            <div className="insd-c-dashboard__card--Vulnerabilities--SplitMetrics__content">
                                <a className='pf-u-font-size-2xl pf-u-color-100'
                                    onClick={e => navigateTo(e, `${UI_BASE}/vulnerability/cves?affecting=true&rule_presence=true`)}
                                    href={`${UI_BASE}/vulnerability/cves?affecting=true&rule_presence=true`}
                                    rel='noreferrer'>
                                    {vulnerabilities.rules_cves_total}
                                </a>
                                <TextContent>
                                    <p className='pf-u-font-size-sm'>
                                        {intl.formatMessage(messages.cvesImpactingOneOrMoreSystems, {
                                            cves: vulnerabilities.rules_cves_total,
                                            strong: string => strong(string)
                                        })}
                                    </p>
                                </TextContent>
                            </div>
                            <Button component='a' href={`${UI_BASE}/vulnerability/cves?affecting=true&rule_presence=true`}
                                onClick={e => navigateTo(e, `${UI_BASE}/vulnerability/cves?affecting=true&rule_presence=true`)}
                                rel='noreferrer'
                                variant='secondary' isSmall>
                                {intl.formatMessage(messages.vulnerabilityCardCTAText)}
                            </Button>
                        </div>
                        <div className="insd-c-dashboard__card--Vulnerabilities--SplitMetrics__item">
                            <div className="insd-c-dashboard__card--Vulnerabilities--SplitMetrics__content">
                                <a className='pf-u-font-size-2xl pf-u-color-100'
                                    onClick={e => navigateTo(e, `${UI_BASE}/vulnerability/cves?known_exploit=true&affecting=true`)}
                                    href={`${UI_BASE}/vulnerability/cves?known_exploit=true&affecting=true`} rel='noreferrer'>
                                    {vulnerabilities.exploited_cves_count}
                                </a>
                                <TextContent>
                                    <p className='pf-u-font-size-sm'>
                                        {intl.formatMessage(messages.knownExploitsOneOrMoreSystems, {
                                            cves: vulnerabilities.exploited_cves_count,
                                            strong: string => strong(string),
                                            tooltip: () => iconTooltip(intl.formatMessage(messages.exploitedCveTooltip))
                                        })}
                                    </p>
                                </TextContent>
                            </div>
                            <Button component='a' href={`${UI_BASE}/vulnerability/cves?known_exploit=true&affecting=true`}
                                onClick={e => navigateTo(e, `${UI_BASE}/vulnerability/cves?known_exploit=true&affecting=true`)}
                                rel='noreferrer'
                                variant='secondary' isSmall>
                                {intl.formatMessage(messages.vulnerabilityCardKnownExploitsCTAText)}
                            </Button>
                        </div>
                    </div>
                </Flex>
            </TemplateCardBody>
                : <Loading />
            } />
        <ExpandableCardTemplate
            appName='CVESbyCVSS'
            className='insd-m-toggle-right-on-md'
            data-ouia-safe={vulnerabilitiesFetchStatus !== 'pending'}
            title={intl.formatMessage(messages.cveByCvssScoreTitle)}
            isExpanded={JSON.parse(localStorage.getItem('dashboard_expanded_vulnerability2') || 'true')}
            isExpandedCallback={isExpanded => localStorage.setItem('dashboard_expanded_vulnerability2', isExpanded)}
            hasDivider
            body={vulnerabilitiesFetchStatus === 'fulfilled' ? <TemplateCardBody className='ins-c-cves-by-cvss-card-body pf-u-pt-sm'>
                <div className="insd-c-dashboard__card-chart-container">
                    <div className="insd-c-dashboard__card-pie-chart">
                        <PieChart
                            ariaDesc={intl.formatMessage(messages.cvesImpactingSystems,
                                { cves: vulnerabilities.cves_total })}
                            ariaTitle='Vulnerabilities chart'
                            constrainToVisibleArea={true}
                            data={chartData}
                            padding={pieChartPadding}
                            colorScale={vulnerabilitiesFetchStatus === 'fulfilled' && vulnerabilities.cves_total === 0 ?
                                [global_disabled_color_100.value] : ['#a30000', '#ec7a08', '#f0ab00']} />
                    </div>
                    <div className="insd-c-dashboard__card-pie-chart-legend">
                        <Table
                            borders={false}
                            aria-label='Simple Table'
                            cells={columns}
                            rows={rows}
                            className='insd-m-no-styling'
                            gridBreakPoint=''
                        >
                            <TableHeader />
                            <TableBody />
                        </Table>
                    </div>
                </div>
            </TemplateCardBody>
                : <Loading />
            } />
    </CompoundCard>;
};

export default VulnerabilityCard;
