import { jsx, jsxs } from "react/jsx-runtime";
import assert from "assert";
import clsx from "clsx";
import { createContext, useReducer, useRef, useContext, useEffect } from "react";
import { Box } from "../Box/Box.mjs";
import { Stack } from "../Stack/Stack.mjs";
import { Text } from "../Accordion/AccordionItem.mjs";
import { Hidden } from "../Hidden/Hidden.mjs";
import { FieldOverlay } from "../Button/Button.mjs";
import { normalizeKey } from "../Autosuggest/Autosuggest.mjs";
import { step, tone, progressTrack, progressTrackCentered, progressLine, progressUnfilled, indicatorContainer, focusOverlay, indicator, highlight, complete, active, inner, tick } from "./Stepper.css.mjs";
const StepContext = createContext({
  stepNumber: 0,
  isLast: false
});
const NAV_RIGHT = 0;
const NAV_DOWN = 1;
const NAV_LEFT = 2;
const NAV_UP = 3;
const NAV_HOME = 4;
const NAV_END = 5;
const NAV_TAB = 6;
const NAV_CLICKED = 7;
const NAV_FOCUSED = 8;
const NAV_BLURRED = 9;
const StepperContext = createContext(null);
const getNextStep = (moveAmount, current, maxStep) => {
  if (current === null) {
    return moveAmount > 0 ? 1 : maxStep;
  }
  const nextStep = moveAmount + current;
  if (nextStep > maxStep) {
    return 1;
  }
  if (nextStep < 1) {
    return maxStep;
  }
  return nextStep;
};
const StepperContextProvider = ({
  children,
  activeStep,
  stepCount: stepCountProp,
  progress,
  isLinear,
  align,
  tone: tone2 = "formAccent",
  onStepClick
}) => {
  const stepCount = isLinear ? progress : stepCountProp;
  const [stepperState, dispatch] = useReducer(
    (state, action) => {
      switch (action.type) {
        case NAV_UP:
        case NAV_LEFT: {
          return {
            ...state,
            focusedStep: getNextStep(-1, state.focusedStep, stepCount)
          };
        }
        case NAV_DOWN:
        case NAV_RIGHT: {
          return {
            ...state,
            focusedStep: getNextStep(1, state.focusedStep, stepCount)
          };
        }
        case NAV_HOME: {
          return {
            ...state,
            focusedStep: 1
          };
        }
        case NAV_END: {
          return {
            ...state,
            focusedStep: stepCount
          };
        }
        case NAV_BLURRED:
        case NAV_TAB: {
          return {
            ...state,
            focusedStep: null
          };
        }
        case NAV_CLICKED: {
          return {
            ...state,
            focusedStep: action.value
          };
        }
        case NAV_FOCUSED: {
          return {
            ...state,
            focusedStep: state.focusedStep === null ? activeStep : state.focusedStep
          };
        }
        default:
          return state;
      }
    },
    {
      focusedStep: null,
      activeStep,
      isLinear,
      tone: tone2,
      align,
      progress,
      onStepClick
    }
  );
  const onKeyUp = (event) => {
    const targetKey = normalizeKey(event);
    if (targetKey === "Tab") {
      return;
    }
    const action = {
      ArrowRight: { type: NAV_RIGHT },
      ArrowLeft: { type: NAV_LEFT },
      ArrowUp: { type: NAV_UP },
      ArrowDown: { type: NAV_DOWN },
      Home: { type: NAV_HOME },
      End: { type: NAV_END }
    };
    if (action[targetKey]) {
      dispatch(action[targetKey]);
    }
  };
  const onKeyDown = (event) => {
    const targetKey = normalizeKey(event);
    if (targetKey === "Tab") {
      dispatch({ type: NAV_TAB });
      return;
    }
    const isNavigationKeyPress = targetKey.indexOf("Arrow") === 0 || ["Home", "End"].includes(targetKey);
    if (isNavigationKeyPress) {
      event.preventDefault();
    }
  };
  const onFocus = () => dispatch({
    type: NAV_FOCUSED
  });
  const onBlur = () => dispatch({
    type: NAV_BLURRED
  });
  const onClick = (index) => dispatch({
    type: NAV_CLICKED,
    value: index
  });
  return /* @__PURE__ */ jsx(
    StepperContext.Provider,
    {
      value: {
        ...stepperState,
        activeStep,
        isLinear,
        align,
        tone: tone2,
        progress,
        onStepClick,
        ...typeof onStepClick === "function" ? {
          onKeyUp,
          onKeyDown,
          onClick,
          onFocus,
          onBlur
        } : {}
      },
      children
    }
  );
};
const StepIndicator = ({ complete: complete$1, started, active: active$1 }) => /* @__PURE__ */ jsxs(
  "svg",
  {
    xmlns: "http://www.w3.org/2000/svg",
    xmlSpace: "preserve",
    focusable: "false",
    viewBox: "0 0 24 24",
    className: clsx(
      indicator,
      complete$1 || active$1 || started ? highlight : void 0,
      complete$1 && !active$1 ? complete : void 0,
      active$1 ? active : void 0
    ),
    children: [
      /* @__PURE__ */ jsx(
        "circle",
        {
          fill: "none",
          stroke: "currentColor",
          strokeWidth: 4,
          cx: 12,
          cy: 12,
          r: 10
        }
      ),
      /* @__PURE__ */ jsx("circle", { cx: 12, cy: 12, r: 5, className: inner }),
      /* @__PURE__ */ jsx(
        "path",
        {
          d: "M 18.26 7.64 C 17.94 7.32 17.46 7.32 17.14 7.64 L 9.7 15.08 L 7.06 12.44 C 6.74 12.12 6.26 12.12 5.94 12.44 S 5.62 13.24 5.94 13.56 L 9.14 16.76 C 9.3 16.92 9.46 17 9.7 17 S 10.1 16.92 10.26 16.76 L 18.26 8.76 C 18.58 8.44 18.58 7.96 18.26 7.64 Z",
          className: tick
        }
      )
    ]
  }
);
const Step = ({ complete: complete2 = false, id, children }) => {
  const stepRef = useRef(null);
  const { stepNumber, isLast } = useContext(StepContext);
  const stepperContext = useContext(StepperContext);
  assert(
    stepperContext !== null,
    "A Step must be rendered as a child of a Stepper. See the documentation for correct usage: https://seek-oss.github.io/braid-design-system/components/Stepper"
  );
  const {
    focusedStep,
    activeStep,
    tone: tone$1,
    align,
    progress,
    isLinear,
    onKeyUp,
    onKeyDown,
    onClick,
    onFocus,
    onBlur,
    onStepClick
  } = stepperContext;
  const active2 = activeStep === stepNumber;
  const focused = focusedStep === stepNumber;
  const linearStepBeforeProgress = isLinear && stepNumber < progress;
  const completed = complete2 || linearStepBeforeProgress;
  const started = active2 || complete2 || isLinear && stepNumber <= progress;
  const keyboardAccessible = focused || active2 && focusedStep === null;
  const interactable = typeof onStepClick === "function" && !active2 && (!isLinear || stepNumber <= progress);
  useEffect(() => {
    if (stepRef.current && focused) {
      stepRef.current.focus();
    }
  }, [focused]);
  return /* @__PURE__ */ jsxs(
    Box,
    {
      component: "button",
      ref: stepRef,
      position: "relative",
      outline: "none",
      display: "flex",
      justifyContent: { tablet: align === "center" ? "center" : void 0 },
      width: "full",
      cursor: interactable ? "pointer" : void 0,
      pointerEvents: !interactable && !active2 ? "none" : void 0,
      "aria-current": active2 ? "step" : void 0,
      className: [step, tone[tone$1]],
      onClick: interactable ? () => {
        if (onClick) {
          onClick(stepNumber);
        }
        if (onStepClick) {
          onStepClick({ id, stepNumber });
        }
      } : void 0,
      onKeyUp,
      onKeyDown,
      onFocus,
      onBlur: keyboardAccessible ? onBlur : void 0,
      tabIndex: keyboardAccessible ? 0 : -1,
      children: [
        !isLast ? /* @__PURE__ */ jsx(
          Box,
          {
            component: "span",
            position: "absolute",
            overflow: "hidden",
            borderRadius: "full",
            className: [
              progressTrack,
              align === "center" ? progressTrackCentered : void 0
            ],
            children: /* @__PURE__ */ jsx(
              Box,
              {
                component: "span",
                position: "absolute",
                top: 0,
                bottom: 0,
                left: 0,
                width: "full",
                className: [
                  progressLine,
                  !linearStepBeforeProgress ? progressUnfilled : void 0
                ]
              }
            )
          }
        ) : null,
        /* @__PURE__ */ jsxs(
          Stack,
          {
            component: "span",
            space: "medium",
            align: {
              mobile: "left",
              tablet: align === "center" ? "center" : void 0
            },
            children: [
              /* @__PURE__ */ jsxs(
                Box,
                {
                  component: "span",
                  display: "block",
                  position: "relative",
                  transition: "fast",
                  className: indicatorContainer,
                  "aria-hidden": true,
                  children: [
                    /* @__PURE__ */ jsx(
                      FieldOverlay,
                      {
                        variant: "focus",
                        borderRadius: "full",
                        onlyVisibleForKeyboardNavigation: true,
                        className: focusOverlay
                      }
                    ),
                    /* @__PURE__ */ jsx(
                      StepIndicator,
                      {
                        complete: completed,
                        active: active2,
                        started
                      }
                    )
                  ]
                }
              ),
              /* @__PURE__ */ jsx(Hidden, { component: "span", below: "tablet", children: /* @__PURE__ */ jsx(
                Box,
                {
                  component: "span",
                  display: "block",
                  paddingX: align === "center" ? "xsmall" : void 0,
                  paddingRight: align === "left" && !isLast ? "xsmall" : void 0,
                  userSelect: "none",
                  children: /* @__PURE__ */ jsx(
                    Text,
                    {
                      align: align === "center" ? "center" : void 0,
                      weight: started ? "strong" : void 0,
                      tone: !started ? "secondary" : void 0,
                      children
                    }
                  )
                }
              ) })
            ]
          }
        )
      ]
    }
  );
};
Step.__isStep__ = true;
export {
  Step,
  StepContext,
  StepperContextProvider
};
