import PropTypes from 'prop-types';
import React, { useCallback, useEffect } from 'react';
import {
  Divider,
  Flex,
  FlexItem,
  Button,
  DescriptionList,
  DescriptionListTerm,
  DescriptionListGroup,
  DescriptionListDescription,
} from '@patternfly/react-core';
import {
  TableComposable,
  TableText,
  Tr,
  Tbody,
  Td,
} from '@patternfly/react-table';
import { useSelector, useDispatch } from 'react-redux';
import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
import CardTemplate from 'foremanReact/components/HostDetails/Templates/CardItem/CardTemplate';
import RelativeDateTime from 'foremanReact/components/common/dates/RelativeDateTime';
import SkeletonLoader from 'foremanReact/components/common/SkeletonLoader';
import DefaultLoaderEmptyState from 'foremanReact/components/HostDetails/DetailsCard/DefaultLoaderEmptyState';
import { statusFormatter } from 'foremanReact/components/HostDetails/Tabs/ReportsTab/helpers';
import { translate as __ } from 'foremanReact/common/I18n';

import { getReportByIdAction } from './ConfigStatusCardActions';
import { FOREMAN_PUPPET_LAST_REPORT_KEY } from './ConfigStatusCardConstants';
import './styles.scss';

const cardHeaderDivider = () => (
  <Divider
    orientation={{
      default: 'vertical',
    }}
    inset={{ default: 'insetMd' }}
  />
);

const generateCardHeader = (allReports = [], reportsCount) =>
  reportsCount > 0 ? (
    <>
      {__('Last configuration status')}
      <Flex>
        <FlexItem>
          <Button
            ouiaId="foreman-puppet-last-report-button"
            variant="link"
            component="a"
            isInline
            isDisabled={!allReports.length}
            href={`/config_reports/${allReports[0].id}`}
          >
            <RelativeDateTime
              date={allReports[0].reported_at}
              defaultValue={__('Never')}
            />
          </Button>
        </FlexItem>
        <FlexItem>{statusFormatter('failed', allReports[0])}</FlexItem>
        {cardHeaderDivider()}
        <FlexItem>{statusFormatter('failed_restarts', allReports[0])}</FlexItem>
        {cardHeaderDivider()}
        <FlexItem>{statusFormatter('restarted', allReports[0])}</FlexItem>
        {cardHeaderDivider()}
        <FlexItem>{statusFormatter('applied', allReports[0])}</FlexItem>
        {cardHeaderDivider()}
        <FlexItem>{statusFormatter('skipped', allReports[0])}</FlexItem>
        {cardHeaderDivider()}
        <FlexItem>{statusFormatter('pending', allReports[0])}</FlexItem>
      </Flex>
    </>
  ) : (
    <> {__('No configuration status available')} </>
  );

const createPuppetMetricsTableElement = (name, value = '--') => (
  <>
    <Td modifier="truncate" key={`metrics-name-${name}`}>
      <TableText
        className={name === 'Total' ? 'last-config-puppet-metrics-total' : ''}
      >
        {name}
      </TableText>
    </Td>
    <Td modifier="truncate" key={`metrics-name-${value}`}>
      <TableText
        className={name === 'Total' ? 'last-config-puppet-metrics-total' : ''}
      >
        {value}
      </TableText>
    </Td>
  </>
);

const createPuppetMetricsTable = (metrics = undefined) => (
  <TableComposable
    aria-label="foreman puppet metrics table"
    variant="compact"
    borders="compactBorderless"
    ouiaId="foreman-puppet-metrics-table"
    key="foreman-puppet-metrics-table"
  >
    <Tbody>
      <Tr>
        {createPuppetMetricsTableElement(__('Failed'), metrics.failed)}
        {createPuppetMetricsTableElement(__('Changed'), metrics.changed)}
        {createPuppetMetricsTableElement(__('Scheduled'), metrics.scheduled)}
      </Tr>
      <Tr>
        {createPuppetMetricsTableElement(
          __('Failed to start'),
          metrics.failed_to_start
        )}
        {createPuppetMetricsTableElement(__('Restarted'), metrics.restarted)}
        {createPuppetMetricsTableElement(
          __('Corrective Change'),
          metrics.corrective_change
        )}
      </Tr>
      <Tr>
        {createPuppetMetricsTableElement(__('Skipped'), metrics.skipped)}
        {createPuppetMetricsTableElement(
          __('Out of sync'),
          metrics.out_of_sync
        )}
        {createPuppetMetricsTableElement(__('Total'), metrics.total)}
      </Tr>
    </Tbody>
  </TableComposable>
);

const ConfigStatusCard = ({ hostName, parentStatus }) => {
  const dispatch = useDispatch();
  // get already fetched results from reports tab
  const API_KEY = `get-reports-${hostName}`;
  const { reports, itemCount } = useSelector(state =>
    selectAPIResponse(state, API_KEY)
  );

  // we need to fetch the last Puppet report to get all Puppet metrics
  const getLastReport = useCallback(() => {
    if (hostName && reports?.length)
      dispatch(getReportByIdAction(reports[0].id));
  }, [hostName, reports, dispatch]);

  useEffect(() => {
    getLastReport();
  }, [hostName, reports]);

  const { metrics } = useSelector(state =>
    selectAPIResponse(state, FOREMAN_PUPPET_LAST_REPORT_KEY)
  );

  return (
    <CardTemplate header={generateCardHeader(reports, itemCount)} expandable>
      <DescriptionList isCompact>
        <DescriptionListGroup>
          <DescriptionListTerm>{__('Puppet metrics')}</DescriptionListTerm>
          <DescriptionListDescription>
            <SkeletonLoader
              status={parentStatus}
              emptyState={<DefaultLoaderEmptyState />}
            >
              {metrics && createPuppetMetricsTable(metrics.resources)}
            </SkeletonLoader>
          </DescriptionListDescription>
        </DescriptionListGroup>
      </DescriptionList>
    </CardTemplate>
  );
};

ConfigStatusCard.propTypes = {
  hostName: PropTypes.string,
  parentStatus: PropTypes.string,
};

ConfigStatusCard.defaultProps = {
  hostName: undefined,
  parentStatus: undefined,
};

export default ConfigStatusCard;