"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClusterDeploymentHostSelectionStep = exports.useHostsSelectionFormik = void 0;
const tslib_1 = require("tslib");
const react_1 = tslib_1.__importDefault(require("react"));
const Yup = tslib_1.__importStar(require("yup"));
const formik_1 = require("formik");
const react_core_1 = require("@patternfly/react-core");
const common_1 = require("../../../../common");
const ClusterDeploymentHostsSelection_1 = tslib_1.__importDefault(require("./ClusterDeploymentHostsSelection"));
const validationSchemas_1 = require("../validationSchemas");
const helpers_1 = require("../../helpers");
const wizardTransition_1 = require("../wizardTransition");
const use_translation_wrapper_1 = require("../../../../common/hooks/use-translation-wrapper");
const ValidationSection_1 = require("../components/ValidationSection");
const ClusterDeploymentWizardContext_1 = require("../ClusterDeploymentWizardContext");
const getInitialValues = ({ agents, clusterDeployment, agentClusterInstall, }) => {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j;
    const isSNOCluster = (0, helpers_1.getIsSNOCluster)(agentClusterInstall);
    const cdName = (_a = clusterDeployment === null || clusterDeployment === void 0 ? void 0 : clusterDeployment.metadata) === null || _a === void 0 ? void 0 : _a.name;
    const cdNamespace = (_b = clusterDeployment === null || clusterDeployment === void 0 ? void 0 : clusterDeployment.metadata) === null || _b === void 0 ? void 0 : _b.namespace;
    let hostCount = (((_d = (_c = agentClusterInstall === null || agentClusterInstall === void 0 ? void 0 : agentClusterInstall.spec) === null || _c === void 0 ? void 0 : _c.provisionRequirements) === null || _d === void 0 ? void 0 : _d.controlPlaneAgents) || 0) +
        (((_f = (_e = agentClusterInstall === null || agentClusterInstall === void 0 ? void 0 : agentClusterInstall.spec) === null || _e === void 0 ? void 0 : _e.provisionRequirements) === null || _f === void 0 ? void 0 : _f.arbiterAgents) || 0) +
        (((_h = (_g = agentClusterInstall === null || agentClusterInstall === void 0 ? void 0 : agentClusterInstall.spec) === null || _g === void 0 ? void 0 : _g.provisionRequirements) === null || _h === void 0 ? void 0 : _h.workerAgents) || 0);
    if (isSNOCluster) {
        hostCount = 1;
    }
    else if (hostCount === 2 || hostCount === 0) {
        hostCount = 3;
    }
    else if (hostCount === 4) {
        hostCount = 5;
    }
    const agentSelector = (0, helpers_1.getAgentSelectorFieldsFromAnnotations)((_j = clusterDeployment === null || clusterDeployment === void 0 ? void 0 : clusterDeployment.metadata) === null || _j === void 0 ? void 0 : _j.annotations);
    const selectedIds = agents
        .filter((agent) => {
        var _a, _b, _c, _d;
        return ((_b = (_a = agent.spec) === null || _a === void 0 ? void 0 : _a.clusterDeploymentName) === null || _b === void 0 ? void 0 : _b.name) === cdName &&
            ((_d = (_c = agent.spec) === null || _c === void 0 ? void 0 : _c.clusterDeploymentName) === null || _d === void 0 ? void 0 : _d.namespace) === cdNamespace;
    })
        .map((agent) => { var _a; return (_a = agent.metadata) === null || _a === void 0 ? void 0 : _a.uid; });
    const autoSelectHosts = agentSelector.autoSelect;
    return {
        autoSelectHosts,
        hostCount,
        useMastersAsWorkers: hostCount === 1 || hostCount === 3, // TODO: Recently not supported - https://issues.redhat.com/browse/MGMT-7677
        agentLabels: (agentSelector === null || agentSelector === void 0 ? void 0 : agentSelector.labels) || [],
        locations: (agentSelector === null || agentSelector === void 0 ? void 0 : agentSelector.locations) || [],
        selectedHostIds: selectedIds,
        autoSelectedHostIds: selectedIds,
    };
};
const getValidationSchema = (agentClusterInstall, t) => {
    const isSNOCluster = (0, helpers_1.getIsSNOCluster)(agentClusterInstall);
    return Yup.lazy((values) => {
        return Yup.object({
            hostCount: isSNOCluster ? Yup.number() : (0, validationSchemas_1.hostCountValidationSchema)(t),
            useMastersAsWorkers: Yup.boolean().required(t('ai:Required field')),
            autoSelectedHostIds: values.autoSelectHosts
                ? Yup.array(Yup.string()).min(values.hostCount).max(values.hostCount)
                : Yup.array(Yup.string()),
            selectedHostIds: values.autoSelectHosts
                ? Yup.array(Yup.string())
                : isSNOCluster
                    ? Yup.array(Yup.string()).length(1, t('ai:Please select one host for the cluster.'))
                    : Yup.array(Yup.string()).min(3, t('ai:Please select at least 3 hosts for the cluster.')),
        });
    });
};
const useHostsSelectionFormik = ({ agents, clusterDeployment, agentClusterInstall, t, }) => {
    const initialValues = react_1.default.useMemo(() => getInitialValues({ agents, clusterDeployment, agentClusterInstall }), [agentClusterInstall, agents, clusterDeployment]);
    const validationSchema = react_1.default.useMemo(() => getValidationSchema(agentClusterInstall, t), [agentClusterInstall, t]);
    return [initialValues, validationSchema];
};
exports.useHostsSelectionFormik = useHostsSelectionFormik;
const getSelectedAgents = (agents, values) => {
    const selectedHostIds = values.autoSelectHosts
        ? values.autoSelectedHostIds
        : values.selectedHostIds;
    return agents.filter((agent) => { var _a; return selectedHostIds.includes(((_a = agent.metadata) === null || _a === void 0 ? void 0 : _a.uid) || ''); });
};
const HostSelectionForm = ({ agents, agentClusterInstall, clusterDeployment, aiConfigMap, onEditRole: onEditRoleInit, onSetInstallationDiskId, isNutanix, }) => {
    const { activeStep, goToNextStep, goToPrevStep, close } = (0, react_core_1.useWizardContext)();
    const { syncError } = react_1.default.useContext(ClusterDeploymentWizardContext_1.ClusterDeploymentWizardContext);
    const { alerts } = (0, common_1.useAlerts)();
    const [showClusterErrors, setShowClusterErrors] = react_1.default.useState(false);
    const { values, isValid, isValidating, isSubmitting, touched, errors, validateForm, setTouched, submitForm, setSubmitting, } = (0, formik_1.useFormikContext)();
    const [nextRequested, setNextRequested] = react_1.default.useState(false);
    const [hasAttemptedSubmit, setHasAttemptedSubmit] = react_1.default.useState(false);
    const selectedAgents = getSelectedAgents(agents, values);
    const { t } = (0, use_translation_wrapper_1.useTranslation)();
    const onEditRole = react_1.default.useCallback((agent, role) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
        setNextRequested(false);
        setShowClusterErrors(false);
        setSubmitting(true);
        const response = yield (onEditRoleInit === null || onEditRoleInit === void 0 ? void 0 : onEditRoleInit(agent, role));
        setSubmitting(false);
        return response;
    }), [onEditRoleInit, setSubmitting]);
    const onAutoSelectChange = react_1.default.useCallback(() => {
        setNextRequested(false);
        setShowClusterErrors(false);
        setHasAttemptedSubmit(false);
    }, []);
    const onHostSelect = react_1.default.useCallback(() => {
        setNextRequested(false);
        setShowClusterErrors(false);
    }, []);
    const onNext = react_1.default.useCallback(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
        if (!hasAttemptedSubmit) {
            setHasAttemptedSubmit(true);
            const errors = yield validateForm();
            setTouched(Object.keys(errors).reduce((acc, curr) => {
                acc[curr] = true;
                return acc;
            }, {}));
            if (Object.keys(errors).length) {
                return;
            }
        }
        void submitForm();
        setNextRequested(true);
    }), [setTouched, hasAttemptedSubmit, submitForm, validateForm]);
    react_1.default.useEffect(() => {
        if (nextRequested && !isSubmitting) {
            const agentStatuses = selectedAgents.map((agent) => (0, helpers_1.getWizardStepAgentStatus)(agent, 'hosts-selection', t).status.key);
            if (agentStatuses.some((status) => ['disconnected', 'disabled', 'error', 'insufficient', 'cancelled'].includes(status))) {
                setNextRequested(false);
            }
            else if (!!selectedAgents.length &&
                selectedAgents.every((agent) => (0, helpers_1.getWizardStepAgentStatus)(agent, 'hosts-selection', t).status.key === 'known')) {
                setShowClusterErrors(true);
                if ((0, wizardTransition_1.canNextFromHostSelectionStep)(agentClusterInstall, selectedAgents)) {
                    void goToNextStep();
                }
            }
        }
    }, [nextRequested, selectedAgents, agentClusterInstall, isSubmitting, t, goToNextStep]);
    const submittingText = react_1.default.useMemo(() => {
        if (isSubmitting) {
            return t('ai:Saving changes...');
        }
        else if (nextRequested && !showClusterErrors) {
            return t('ai:Binding hosts...');
        }
        return undefined;
    }, [isSubmitting, nextRequested, showClusterErrors, t]);
    react_1.default.useEffect(() => {
        if (syncError) {
            setNextRequested(false);
        }
    }, [syncError]);
    const errorsSection = (react_1.default.createElement(ValidationSection_1.ValidationSection, { currentStepId: 'cluster-details', hosts: [] }, syncError && (react_1.default.createElement(react_core_1.Alert, { variant: react_core_1.AlertVariant.danger, title: t('ai:An error occurred'), isInline: true }, syncError))));
    const footer = react_1.default.useMemo(() => {
        const hasValidationErrors = hasAttemptedSubmit && (!isValid || isValidating);
        const isNextDisabled = nextRequested || isSubmitting || hasValidationErrors; // || !!syncError
        return (react_1.default.createElement(react_core_1.WizardFooter, { activeStep: activeStep, onNext: onNext, isNextDisabled: isNextDisabled, nextButtonText: submittingText || t('ai:Next'), nextButtonProps: { isLoading: !!submittingText }, onBack: goToPrevStep, onClose: close }));
    }, [
        activeStep,
        onNext,
        nextRequested,
        isSubmitting,
        hasAttemptedSubmit,
        isValid,
        isValidating,
        submittingText,
        t,
        goToPrevStep,
        close,
    ]);
    (0, react_core_1.useWizardFooter)(footer);
    return (react_1.default.createElement(react_core_1.Grid, { hasGutter: true },
        react_1.default.createElement(react_core_1.GridItem, null,
            react_1.default.createElement(common_1.ClusterWizardStepHeader, null, t('ai:Cluster hosts'))),
        react_1.default.createElement(react_core_1.GridItem, null,
            react_1.default.createElement(ClusterDeploymentHostsSelection_1.default, { agentClusterInstall: agentClusterInstall, agents: agents, clusterDeployment: clusterDeployment, aiConfigMap: aiConfigMap, onEditRole: onEditRole, onSetInstallationDiskId: onSetInstallationDiskId, onAutoSelectChange: onAutoSelectChange, onHostSelect: onHostSelect, isNutanix: isNutanix, hostsBinding: nextRequested && !showClusterErrors })),
        (showClusterErrors || hasAttemptedSubmit) && !!alerts.length && (react_1.default.createElement(react_core_1.GridItem, null,
            react_1.default.createElement(common_1.Alerts, null))),
        syncError && react_1.default.createElement(react_core_1.GridItem, null, errorsSection),
        hasAttemptedSubmit && errors.selectedHostIds && touched.selectedHostIds && (react_1.default.createElement(react_core_1.GridItem, null,
            react_1.default.createElement(react_core_1.Alert, { variant: react_core_1.AlertVariant.danger, title: t('ai:Provided cluster configuration is not valid'), isInline: true }, errors.selectedHostIds)))));
};
const ClusterDeploymentHostSelectionStep = (_a) => {
    var { onSaveHostsSelection } = _a, rest = tslib_1.__rest(_a, ["onSaveHostsSelection"]);
    const { t } = (0, use_translation_wrapper_1.useTranslation)();
    const { addAlert } = (0, common_1.useAlerts)();
    const { agents, clusterDeployment, agentClusterInstall } = rest;
    const [initialValues, validationSchema] = (0, exports.useHostsSelectionFormik)({
        agents,
        clusterDeployment,
        agentClusterInstall,
        t,
    });
    const handleSubmit = (values_1, _a) => tslib_1.__awaiter(void 0, [values_1, _a], void 0, function* (values, { setSubmitting }) {
        try {
            yield onSaveHostsSelection(values);
        }
        catch (e) {
            const error = e;
            addAlert({
                title: t('ai:Failed to save host selection.'),
                message: error.message,
            });
        }
        finally {
            setSubmitting(false);
        }
    });
    return (react_1.default.createElement(formik_1.Formik, { initialValues: initialValues, validationSchema: validationSchema, onSubmit: handleSubmit },
        react_1.default.createElement(HostSelectionForm, Object.assign({}, rest))));
};
exports.ClusterDeploymentHostSelectionStep = ClusterDeploymentHostSelectionStep;
//# sourceMappingURL=ClusterDeploymentHostSelectionStep.js.map