import { clsx } from 'clsx';
import { useIntl } from 'react-intl';

import { Breakpoint, Layout } from '../common';
import { CloseButton } from '../common/closeButton';
import FlowHeader from '../common/flowHeader/FlowHeader';
import Logo from '../logo';
import Stepper, { type Step } from '../stepper/Stepper';

import { useScreenSize } from '../common/hooks/useScreenSize';
import messages from './FlowNavigation.messages';
import AnimatedLabel from './animatedLabel';
import IconButton from '../iconButton';
import { ArrowLeft } from '@transferwise/icons';

export interface FlowNavigationProps {
  /** @default 0 */
  activeStep?: number;
  avatar?: React.ReactNode;
  /** @default <Logo /> */
  logo?: React.ReactNode;
  /** @default false */
  done?: boolean;
  /** Called when the close button is clicked. If not provided the close button won't show */
  onClose?: () => void;
  /** Called when the back button is clicked. If not provided the back button won't show. The back button only shows on small screens */
  onGoBack?: () => void;
  /** Steps to be displayed in stepper. If you don't need the stepper, please use OverlayHeader instead */
  steps: readonly Step[];
}

const FlowNavigation = ({
  activeStep = 0,
  avatar,
  logo = <Logo />,
  done = false,
  onClose,
  onGoBack,
  steps,
}: FlowNavigationProps) => {
  const intl = useIntl();

  const closeButton = onClose != null && <CloseButton size="lg" onClick={onClose} />;

  const screenSm = useScreenSize(Breakpoint.SMALL);
  const screenLg = useScreenSize(Breakpoint.LARGE);

  const newAvatar = done ? null : avatar;

  const displayGoBack = onGoBack != null && activeStep > 0;

  return (
    <div
      className={clsx('np-flow-navigation d-flex align-items-center justify-content-center p-y-3', {
        'np-flow-navigation--border-bottom': !done,
      })}
    >
      <FlowHeader
        className={clsx(
          'np-flow-navigation__content p-x-3',
          screenSm == null
            ? 'np-flow-navigation--hidden'
            : {
                'np-flow-navigation--xs-max': !screenSm,
                // Size switches on parent container which may or may not have the same size as the window.
                'np-flow-navigation--sm': screenSm,
                'np-flow-navigation--lg': screenLg,
              },
        )}
        leftContent={
          <>
            {!screenSm && displayGoBack ? (
              <IconButton
                size={40}
                priority="tertiary"
                type="default"
                aria-label={intl.formatMessage(messages.back)}
                onClick={onGoBack}
              >
                <ArrowLeft />
              </IconButton>
            ) : (
              <div className="np-flow-header__left">{logo}</div>
            )}
            {!screenSm && !done && (
              <AnimatedLabel className="m-x-1" steps={steps} activeLabel={activeStep} />
            )}
          </>
        }
        rightContent={
          <div className="np-flow-header__right d-flex align-items-center justify-content-end order-2--lg">
            {newAvatar}
            {newAvatar && closeButton && <span className="m-x-1" />}
            {closeButton}
          </div>
        }
        bottomContent={
          !done &&
          (steps.length > 0 ? (
            <Stepper
              activeStep={activeStep}
              steps={steps}
              className={clsx('np-flow-navigation__stepper')}
            />
          ) : (
            <div className="np-flow-navigation__stepper" />
          ))
        }
        layout={!screenLg ? Layout.VERTICAL : Layout.HORIZONTAL}
      />
    </div>
  );
};

export default FlowNavigation;
