import React from 'react';
import * as Yup from 'yup';
import { TFunction } from 'i18next';
import {
  Button,
  Form,
  AlertVariant,
  Alert,
  Stack,
  StackItem,
  ModalBody,
  ModalFooter,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
import { Formik, FormikHelpers } from 'formik';
import {
  ImageCreateParams,
  ImageType,
  Proxy,
} from '@openshift-assisted/types/assisted-installer-service';
import { AlertFormikError } from '../../../common/components/ui';
import {
  httpProxyValidationSchema,
  noProxyValidationSchema,
  sshPublicKeyValidationSchema,
} from '../../validationSchemas';
import { ProxyFieldsType, StatusErrorType } from '../../types';
import ProxyFields from './ProxyFields';
import UploadSSH from './UploadSSH';
import DiscoveryImageTypeControlGroup from './DiscoveryImageTypeControlGroup';
import { getOCPStaticIPDocLink } from '../../config/docs_links';
import { useTranslation } from '../../hooks/use-translation-wrapper';

export const StaticIPInfo = ({ docVersion }: { docVersion?: string }) => {
  const { t } = useTranslation();
  return (
    <Alert
      title={t(
        'ai:To use static network configuration, follow the steps listed in the documentation.',
      )}
      isInline
      variant="info"
    >
      <Button
        variant="link"
        icon={<ExternalLinkAltIcon />}
        iconPosition="right"
        isInline
        onClick={() =>
          window.open(getOCPStaticIPDocLink(docVersion), '_blank', 'noopener,noreferrer')
        }
      >
        {t('ai:View documentation')}
      </Button>
    </Alert>
  );
};

export type DiscoveryImageFormValues = ImageCreateParams & ProxyFieldsType;

const getValidationSchema = (allowEmpty: boolean, t: TFunction) =>
  Yup.lazy((values: DiscoveryImageFormValues) =>
    Yup.object<DiscoveryImageFormValues>().shape({
      sshPublicKey: sshPublicKeyValidationSchema(t),
      httpProxy: httpProxyValidationSchema({ values, pairValueName: 'httpsProxy', allowEmpty, t }),
      httpsProxy: httpProxyValidationSchema({ values, pairValueName: 'httpProxy', allowEmpty, t }), // share the schema, httpS is currently not supported
      noProxy: noProxyValidationSchema(t),
    }),
  );

type DiscoveryImageConfigFormProps = Proxy & {
  onCancel: () => void;
  handleSubmit: (
    values: DiscoveryImageFormValues,
    formikActions: FormikHelpers<DiscoveryImageFormValues>,
  ) => Promise<void>;
  hasDHCP?: boolean;
  hideDiscoveryImageType?: boolean;
  sshPublicKey?: string;
  imageType?: ImageType;
  isIPXE?: boolean;
  allowEmpty?: boolean;
  docVersion: string;
};

export const DiscoveryImageConfigForm: React.FC<DiscoveryImageConfigFormProps> = ({
  handleSubmit,
  onCancel,
  sshPublicKey,
  httpProxy,
  httpsProxy,
  noProxy,
  imageType,
  hideDiscoveryImageType,
  hasDHCP,
  isIPXE,
  allowEmpty,
  docVersion,
}) => {
  const initialValues: DiscoveryImageFormValues = {
    sshPublicKey: sshPublicKey || '',
    httpProxy: httpProxy || '',
    httpsProxy: httpsProxy || '',
    noProxy: noProxy || '',
    enableProxy: !!(httpProxy || httpsProxy || noProxy),
    imageType: imageType || 'minimal-iso',
  };

  const { t } = useTranslation();
  return (
    <Formik
      initialValues={initialValues}
      initialStatus={{ error: null }}
      validationSchema={getValidationSchema(!!allowEmpty, t)}
      onSubmit={handleSubmit}
    >
      {({ submitForm, isSubmitting, status }) => {
        return (
          <>
            <ModalBody>
              <Stack hasGutter>
                {hasDHCP === false && (
                  <StackItem>
                    <StaticIPInfo docVersion={docVersion} />
                  </StackItem>
                )}
                <StackItem>
                  <Form>
                    {!hideDiscoveryImageType && <DiscoveryImageTypeControlGroup />}
                    <AlertFormikError status={status as StatusErrorType} />
                    <Alert
                      variant={AlertVariant.info}
                      isInline
                      title={
                        isIPXE
                          ? t('ai:To add hosts to the cluster, generate iPXE script.')
                          : t('ai:To add hosts to the cluster, generate a Discovery ISO.')
                      }
                    />
                    <UploadSSH />
                    <ProxyFields />
                  </Form>
                </StackItem>
              </Stack>
            </ModalBody>
            <ModalFooter>
              <Button
                // eslint-disable-next-line @typescript-eslint/no-misused-promises
                onClick={submitForm}
                isDisabled={isSubmitting}
                isLoading={isSubmitting}
              >
                {isSubmitting
                  ? t('ai:Generating')
                  : isIPXE
                  ? t('ai:Generate script file')
                  : t('ai:Generate Discovery ISO')}
              </Button>
              <Button key="cancel" variant="link" onClick={onCancel}>
                {t('ai:Cancel')}
              </Button>
            </ModalFooter>
          </>
        );
      }}
    </Formik>
  );
};
