import React, { ReactElement } from 'react';
import css from '../../utils/css';

import { Wrapper, StepWrapper, StepLine, StepLabel } from './StyledSteps';
import StepIcon from './StepIcon';
import assert from '../../utils/assert';
import { CommonProps } from '../common';
import { fromUndefinedable, getOrElse, isSome, map } from '../../fp/Option';
import { invokeWith, pipe } from '../../fp/function';

export interface StepsProps extends CommonProps {
  /**
   * Current step. This is 1-based indexing.
   */
  current: number;
  /**
   * Set the handler to handle `click` event.
   */
  onClick?: (step: {
    id: string | number;
    status: 'complete' | 'incomplete';
    text: string;
  }) => void;
  /**
   * An array of steps to be rendered.
   */
  steps: {
    id: string | number;
    status: 'complete' | 'incomplete';
    text: string;
  }[];
}

const Steps = ({
  steps,
  current,
  onClick,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: StepsProps): ReactElement => {
  assert(
    current >= 1 && current <= steps.length,
    `[Steps] Current:${current} is not in range [1, ${steps.length}]`
  );
  const maybeOnClick = fromUndefinedable(onClick);
  const clickable = isSome(maybeOnClick);
  return (
    <Wrapper
      id={id}
      className={className}
      style={{ ...style, ...css(sx) }}
      data-test-id={dataTestId}
    >
      {steps.map((step, index) => {
        const { text, status } = step;
        const active = index === current - 1;
        const onClickStep = (): void =>
          pipe(
            maybeOnClick,
            map(invokeWith(step)),
            getOrElse(() => undefined)
          );

        return (
          <StepWrapper themeNumberOfSteps={steps.length} key={step.id}>
            <StepIcon
              clickable={clickable}
              onClick={onClickStep}
              active={active}
              status={status}
            />
            <StepLabel
              themeClickable={clickable}
              themeActive={active}
              themeStatus={status}
              onClick={onClickStep}
            >
              {text}
            </StepLabel>
            {index !== 0 && (
              <StepLine themeStatus={active === true ? 'complete' : status} />
            )}
          </StepWrapper>
        );
      })}
    </Wrapper>
  );
};

export default Steps;
