import * as React from 'react';
import {
  Alert,
  AlertVariant,
  Grid,
  GridItem,
  useWizardContext,
  useWizardFooter,
  WizardFooter,
} from '@patternfly/react-core';
import { PlatformType } from '@openshift-assisted/types/assisted-installer-service';
import { canNextFromReviewStep } from '../wizardTransition';
import {
  AgentClusterInstallK8sResource,
  AgentK8sResource,
  ClusterDeploymentK8sResource,
  ClusterImageSetK8sResource,
  InfraEnvK8sResource,
} from '../../../types';
import {
  ClusterWizardStepHeader,
  DetailList,
  DetailItem,
  ReviewHostsInventory,
  ClusterValidations,
  HostsValidations,
  useAlerts,
  getPlatforms,
} from '../../../../common';
import {
  getSelectedVersion,
  getAICluster,
  getClusterDeploymentCpuArchitecture,
} from '../../helpers';
import { isAgentOfCluster } from '../helpers';
import { wizardStepNames } from '../constants';
import { wizardStepsValidationsMap, allClusterWizardSoftValidationIds } from '../wizardTransition';
import { useTranslation } from '../../../../common/hooks/use-translation-wrapper';
import { ClusterDeploymentWizardContext } from '../ClusterDeploymentWizardContext';
import { ReviewConfigMapsTable } from './ReviewConfigMapsTable';
import { ValidationSection } from '../components/ValidationSection';
import { ClusterDeploymentWizardStepsType } from '../types';

type ClusterDeploymentReviewStepProps = {
  clusterDeployment: ClusterDeploymentK8sResource;
  agentClusterInstall: AgentClusterInstallK8sResource;
  agents: AgentK8sResource[];
  // eslint-disable-next-line
  onFinish: () => Promise<any>;
  clusterImages: ClusterImageSetK8sResource[];
  infraEnv?: InfraEnvK8sResource;
};

export const ClusterDeploymentReviewStep = ({
  agentClusterInstall,
  agents,
  onFinish,
  clusterDeployment,
  clusterImages,
  infraEnv,
}: ClusterDeploymentReviewStepProps) => {
  const { addAlert, clearAlerts } = useAlerts();
  const { activeStep, goToPrevStep, goToStepById, close } = useWizardContext();
  const { syncError } = React.useContext(ClusterDeploymentWizardContext);
  const [isSubmitting, setSubmitting] = React.useState(false);
  const cdName = clusterDeployment.metadata?.name;
  const cdNamespace = clusterDeployment.metadata?.namespace;
  const cpuArchitecture = getClusterDeploymentCpuArchitecture(clusterDeployment, infraEnv);

  const clusterAgents = React.useMemo(
    () => agents.filter((a) => isAgentOfCluster(a, cdName, cdNamespace)),
    [agents, cdName, cdNamespace],
  );

  const canContinue = canNextFromReviewStep(agentClusterInstall, clusterAgents);
  const { t } = useTranslation();

  const onNext = React.useCallback(async () => {
    clearAlerts();
    setSubmitting(true);
    try {
      await onFinish();
    } catch (err) {
      const error = err as Error;
      addAlert({ title: error.message || t('ai:An error occurred while starting installation.') });
    } finally {
      setSubmitting(false);
    }
  }, [addAlert, clearAlerts, onFinish, t]);

  const footer = React.useMemo(
    () => (
      <WizardFooter
        activeStep={activeStep}
        onNext={onNext}
        isNextDisabled={isSubmitting || !canContinue || !!syncError}
        nextButtonText={t('ai:Install cluster')}
        nextButtonProps={{ isLoading: isSubmitting }}
        onBack={goToPrevStep}
        onClose={close}
      />
    ),
    [activeStep, canContinue, close, goToPrevStep, isSubmitting, onNext, syncError, t],
  );
  useWizardFooter(footer);

  const openShiftVersion = getSelectedVersion(clusterImages, agentClusterInstall, t);
  const platform =
    getPlatforms(t)[
      (agentClusterInstall?.spec?.platformType?.toLowerCase() || 'baremetal') as PlatformType
    ];

  const cluster = React.useMemo(
    () => getAICluster({ clusterDeployment, agentClusterInstall, agents: clusterAgents }),
    [clusterDeployment, agentClusterInstall, clusterAgents],
  );

  return (
    <Grid hasGutter>
      <GridItem>
        <ClusterWizardStepHeader>Review and create</ClusterWizardStepHeader>
      </GridItem>
      <GridItem>
        <DetailList>
          <DetailItem
            title={t('ai:Cluster address')}
            value={`${clusterDeployment.metadata?.name || ''}.${
              clusterDeployment.spec?.baseDomain || ''
            }`}
            testId="cluster-address"
          />
          <DetailItem
            title={t('ai:OpenShift version')}
            value={openShiftVersion}
            testId="openshift-version"
          />
          <DetailItem
            title={t('ai:CPU architecture')}
            value={cpuArchitecture}
            testId="cpu-architecture"
          />
          <DetailItem
            title={t('ai:External partner platform')}
            value={platform}
            testId="platform-type"
          />
          <DetailItem
            title={t('ai:API IP (Primary)')}
            value={agentClusterInstall?.status?.apiVIPs?.[0]}
            testId="api-vip-primary"
          />
          {(agentClusterInstall?.status?.apiVIPs?.length ?? 0) > 1 ? (
            <DetailItem
              title={t('ai:API IP (Secondary)')}
              value={agentClusterInstall?.status?.apiVIPs?.[1]}
              testId="api-vip-secondary"
            />
          ) : undefined}
          <DetailItem
            title={t('ai:Ingress IP (Primary)')}
            value={agentClusterInstall?.status?.ingressVIPs?.[0]}
            testId="ingress-vip-primary"
          />
          {(agentClusterInstall?.status?.ingressVIPs?.length ?? 0) > 1 ? (
            <DetailItem
              title={t('ai:Ingress IP (Secondary)')}
              value={agentClusterInstall?.status?.ingressVIPs?.[1]}
              testId="ingress-vip-secondary"
            />
          ) : undefined}
          <DetailItem
            title={t('ai:Cluster summary')}
            testId="cluster-summary"
            value={<ReviewHostsInventory hosts={cluster.hosts} />}
          />

          {!!agentClusterInstall.spec?.manifestsConfigMapRefs?.length ? (
            <DetailItem
              title={t('ai:Custom manifests')}
              value={<ReviewConfigMapsTable agentClusterInstall={agentClusterInstall} />}
            />
          ) : undefined}

          <DetailItem
            title={t('ai:Cluster validations')}
            value={
              <ClusterValidations<ClusterDeploymentWizardStepsType>
                validationsInfo={cluster.validationsInfo}
                setCurrentStepId={goToStepById}
                wizardStepNames={wizardStepNames(t)}
                wizardStepsValidationsMap={wizardStepsValidationsMap}
              />
            }
            testId="cluster-validations"
          />
          <DetailItem
            title={t('ai:Host validations')}
            value={
              <HostsValidations<
                ClusterDeploymentWizardStepsType,
                typeof allClusterWizardSoftValidationIds
              >
                hosts={cluster.hosts}
                setCurrentStepId={goToStepById}
                wizardStepNames={wizardStepNames(t)}
                allClusterWizardSoftValidationIds={allClusterWizardSoftValidationIds}
                wizardStepsValidationsMap={wizardStepsValidationsMap}
              />
            }
            testId="host-validations"
          />
        </DetailList>
      </GridItem>
      {syncError && (
        <GridItem>
          <ValidationSection currentStepId={'review'} hosts={[]}>
            <Alert variant={AlertVariant.danger} title={t('ai:An error occurred')} isInline>
              {syncError}
            </Alert>
          </ValidationSection>
        </GridItem>
      )}
    </Grid>
  );
};
