/* eslint-disable max-lines-per-function */
import { forwardRef, memo } from "react";

import { pxToRem } from "../../utils";
import {
  StyledStepsList,
  StyledRoot,
  StyledStepIndicator,
  StyledStep,
  StyledStepLabel,
} from "./progress-bar.styled";
import { useProgressBar } from "./use-progress-bar";

type Step = {
  label: string;
  value: string | number;
};

interface Props {
  /**
   * The Steps of the ProgressBar
   */
  steps: Array<Step>;
  /**
   * Sets the currently selected step
   */
  value: string | number;
  /**
   * Aria label applied to the steps list
   */
  ariaLabel?: string;
}

/**
 * Use this component to give the user an overview of steps in a flow.
 */
const ProgressBarComponent = forwardRef<HTMLDivElement, Props>(
  ({ steps, value, ariaLabel }, ref) => {
    const { currentStep, dotXpositions, shouldOverrideScrollbars, firstStepRef, isResizing } =
      useProgressBar({
        steps,
        value,
      });

    return (
      <StyledRoot
        ref={ref}
        animate={!isResizing}
        css={{
          "&::before": {
            left: pxToRem(dotXpositions[0]),

            width: pxToRem(dotXpositions[dotXpositions.length - 1]! - dotXpositions[0]!),
          },
          "&::after": {
            left: pxToRem(dotXpositions[0]),

            width: currentStep > 0 ? pxToRem(dotXpositions[currentStep]! - dotXpositions[0]!) : 0,
          },
        }}
        data-show-scrollbars={String(shouldOverrideScrollbars)}
      >
        <StyledStepIndicator
          css={{
            left: pxToRem(dotXpositions[currentStep]),
            visibility: dotXpositions.length > 1 ? "visible" : "hidden",
          }}
          animate={!isResizing}
        />
        <StyledStepsList aria-label={ariaLabel}>
          {steps.map((step, i) => {
            const props = i ? {} : { ref: firstStepRef };

            return (
              <StyledStep key={step.value} {...props}>
                <StyledStepLabel
                  variant="body4"
                  complete={i === 0 || i <= currentStep}
                  {...(currentStep === i && { "aria-current": "step" })}
                >
                  {step.label}
                </StyledStepLabel>
              </StyledStep>
            );
          })}
        </StyledStepsList>
      </StyledRoot>
    );
  }
);

ProgressBarComponent.displayName = "ProgressBar";

export const ProgressBar = memo(ProgressBarComponent);
