: React.MouseEvent<HTMLButtonElement>, steps: WizardStepType[] = initialSteps) => {
    const newStep = [...steps]
      .reverse()
      .find((step: WizardStepType) => step.index < activeStepIndex && isStepEnabled(steps, step));

    setActiveStepIndex(newStep?.index);
    onStepChange?.(event, newStep, steps[activeStepIndex - 1], WizardStepChangeScope.Back);
    shouldFocusContent && focusMainContentElement();
  };

  const goToStepByIndex = (
    event: React.MouseEvent<HTMLButtonElement>,
    steps: WizardStepType[] = initialSteps,
    index: number
  ) => {
    const lastStepIndex = steps.length + 1;

    // Handle index when out of bounds or hidden
    if (index < 1) {
      index = 1;
    } else if (index > lastStepIndex) {
      index = lastStepIndex;
    }

    const currStep = steps[index - 1];
    const prevStep = steps[activeStepIndex - 1];

    setActiveStepIndex(index);
    onStepChange?.(event, currStep, prevStep, WizardStepChangeScope.Nav);
  };

  const goToStepById = (steps: WizardStepType[] = initialSteps, id: number | string) => {
    const step = steps.find((step) => step.id === id);
    const stepIndex = step?.index;
    const lastStepIndex = steps.length + 1;

    if (stepIndex > 0 && stepIndex < lastStepIndex && !step.isDisabled && !step.isHidden) {
      setActiveStepIndex(stepIndex);
    }
  };

  const goToStepByName = (steps: WizardStepType[] = initialSteps, name: string) => {
    const step = steps.find((step) => step.name === name);
    const stepIndex = step?.index;
    const lastStepIndex = steps.length + 1;

    if (stepIndex > 0 && stepIndex < lastStepIndex && !step.isDisabled && !step.isHidden) {
      setActiveStepIndex(stepIndex);
    }
  };

  return (
    <WizardContextProvider
      steps={initialSteps}
      activeStepIndex={activeStepIndex}
      footer={footer}
      onNext={goToNextStep}
      onBack={goToPrevStep}
      onClose={onClose}
      goToStepById={goToStepById}
      goToStepByName={goToStepByName}
      goToStepByIndex={goToStepByIndex}
      shouldFocusContent={shouldFocusContent}
      mainWrapperRef={wrapperRef}
    >
      <div
        className={css(styles.wizard, className)}
        style={{
          ...(height ? { [wizardHeightToken.name]: typeof height === 'number' ? `${height}px` : height } : {}),
          ...(width ? { width } : {})
        }}
        {...wrapperProps}
      >
        {header}
        <WizardInternal
          nav={nav}
          navAriaLabel={navAriaLabel}
          isVisitRequired={isVisitRequired}
          isProgressive={isProgressive}
        />
      </div>
    </WizardContextProvider>
  );
};

const WizardInternal = ({
  nav,
  navAriaLabel,
  isVisitRequired,
  isProgressive
}: Pick<WizardProps, 'nav' | 'navAriaLabel' | 'isVisitRequired' | 'isProgressive'>) => {
  const { activeStep, steps, footer, goToStepByIndex } = useWizardContext();
  const [isNavExpanded, setIsNavExpanded] = React.useState(false);

  const wizardNav = React.useMemo(() => {
    if (isCustomWizardNav(nav)) {
      return typeof nav === 'function' ? nav(isNavExpanded, steps, activeStep, goToStepByIndex) : nav;
    }

    return (
      <WizardNavInternal
        nav={nav}
        navAriaLabel={navAriaLabel}
        isNavExpanded={isNavExpanded}
        isVisitRequired={isVisitRequired}
        isProgressive={isProgressive}
      />
    );
  }, [activeStep, isVisitRequired, isProgressive, goToStepByIndex, isNavExpanded, nav, navAriaLabel, steps]);

  return (
    <WizardToggle
      nav={wizardNav}
      footer={footer}
      steps={steps}
      activeStep={activeStep}
      isNavExpanded={isNavExpanded}
      toggleNavExpanded={() => setIsNavExpanded((prevIsExpanded) => !prevIsExpanded)}
    />
  );
};

Wizard.displayName = 'Wizard';
