import { jsx, jsxs } from "react/jsx-runtime";
import { useState, useRef, useCallback } from "react";
import { rem } from "../../../core/utils/units-converters/rem.mjs";
import { getSize, getRadius } from "../../../core/utils/get-size/get-size.mjs";
import { findClosestNumber } from "../../../core/utils/find-closest-number/find-closest-number.mjs";
import { createVarsResolver } from "../../../core/styles-api/create-vars-resolver/create-vars-resolver.mjs";
import "clsx";
import { getThemeColor } from "../../../core/MantineProvider/color-functions/get-theme-color/get-theme-color.mjs";
import { useProps } from "../../../core/MantineProvider/use-props/use-props.mjs";
import { useStyles } from "../../../core/styles-api/use-styles/use-styles.mjs";
import { factory } from "../../../core/factory/factory.mjs";
import { useDirection } from "../../../core/DirectionProvider/DirectionProvider.mjs";
import { SliderProvider } from "../Slider.context.mjs";
import { SliderRoot } from "../SliderRoot/SliderRoot.mjs";
import { Thumb } from "../Thumb/Thumb.mjs";
import { Track } from "../Track/Track.mjs";
import { getChangeValue } from "../utils/get-change-value/get-change-value.mjs";
import { getFloatingValue } from "../utils/get-floating-value/get-gloating-value.mjs";
import { getPosition } from "../utils/get-position/get-position.mjs";
import { getPrecision } from "../utils/get-precision/get-precision.mjs";
import { getLastMarkValue, getFirstMarkValue, getNextMarkValue, getPreviousMarkValue } from "../utils/get-step-mark-value/get-step-mark-value.mjs";
import classes from "../Slider.module.css.mjs";
import { useUncontrolled } from "../../../../../../../../@mantine_hooks@7.15.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-uncontrolled/use-uncontrolled.mjs";
import { clamp } from "../../../../../../../../@mantine_hooks@7.15.2_react@18.3.1/node_modules/@mantine/hooks/esm/utils/clamp/clamp.mjs";
import { useMove } from "../../../../../../../../@mantine_hooks@7.15.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-move/use-move.mjs";
import { useMergedRef } from "../../../../../../../../@mantine_hooks@7.15.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-merged-ref/use-merged-ref.mjs";
const defaultProps = {
  radius: "xl",
  min: 0,
  max: 100,
  step: 1,
  marks: [],
  label: (f) => f,
  labelTransitionProps: { transition: "fade", duration: 0 },
  labelAlwaysOn: false,
  thumbLabel: "",
  showLabelOnHover: true,
  disabled: false,
  scale: (v) => v
};
const varsResolver = createVarsResolver(
  (theme, { size, color, thumbSize, radius }) => ({
    root: {
      "--slider-size": getSize(size, "slider-size"),
      "--slider-color": color ? getThemeColor(color, theme) : void 0,
      "--slider-radius": radius === void 0 ? void 0 : getRadius(radius),
      "--slider-thumb-size": thumbSize !== void 0 ? rem(thumbSize) : "calc(var(--slider-size) * 2)"
    }
  })
);
const Slider = factory((_props, ref) => {
  const props = useProps("Slider", defaultProps, _props);
  const {
    classNames,
    styles,
    value,
    onChange,
    onChangeEnd,
    size,
    min,
    max,
    step,
    precision: _precision,
    defaultValue,
    name,
    marks,
    label,
    labelTransitionProps,
    labelAlwaysOn,
    thumbLabel,
    showLabelOnHover,
    thumbChildren,
    disabled,
    unstyled,
    scale,
    inverted,
    className,
    style,
    vars,
    hiddenInputProps,
    restrictToMarks,
    thumbProps,
    ...others
  } = props;
  const getStyles = useStyles({
    name: "Slider",
    props,
    classes,
    classNames,
    className,
    styles,
    style,
    vars,
    varsResolver,
    unstyled
  });
  const { dir } = useDirection();
  const [hovered, setHovered] = useState(false);
  const [_value, setValue] = useUncontrolled({
    value: typeof value === "number" ? clamp(value, min, max) : value,
    defaultValue: typeof defaultValue === "number" ? clamp(defaultValue, min, max) : defaultValue,
    finalValue: clamp(0, min, max),
    onChange
  });
  const valueRef = useRef(_value);
  const root = useRef(null);
  const thumb = useRef(null);
  const position = getPosition({ value: _value, min, max });
  const scaledValue = scale(_value);
  const _label = typeof label === "function" ? label(scaledValue) : label;
  const precision = _precision ?? getPrecision(step);
  const handleChange = useCallback(
    ({ x }) => {
      if (!disabled) {
        const nextValue = getChangeValue({
          value: x,
          min,
          max,
          step,
          precision
        });
        setValue(
          restrictToMarks && (marks == null ? void 0 : marks.length) ? findClosestNumber(
            nextValue,
            marks.map((mark) => mark.value)
          ) : nextValue
        );
        valueRef.current = nextValue;
      }
    },
    [disabled, min, max, step, precision, setValue, marks, restrictToMarks]
  );
  const { ref: container, active } = useMove(
    handleChange,
    {
      onScrubEnd: () => onChangeEnd == null ? void 0 : onChangeEnd(
        restrictToMarks && (marks == null ? void 0 : marks.length) ? findClosestNumber(
          valueRef.current,
          marks.map((mark) => mark.value)
        ) : valueRef.current
      )
    },
    dir
  );
  const handleTrackKeydownCapture = (event) => {
    var _a, _b, _c, _d, _e, _f;
    if (!disabled) {
      switch (event.key) {
        case "ArrowUp": {
          event.preventDefault();
          (_a = thumb.current) == null ? void 0 : _a.focus();
          if (restrictToMarks && marks) {
            const nextValue2 = getNextMarkValue(_value, marks);
            setValue(nextValue2);
            onChangeEnd == null ? void 0 : onChangeEnd(nextValue2);
            break;
          }
          const nextValue = getFloatingValue(
            Math.min(Math.max(_value + step, min), max),
            precision
          );
          setValue(nextValue);
          onChangeEnd == null ? void 0 : onChangeEnd(nextValue);
          break;
        }
        case "ArrowRight": {
          event.preventDefault();
          (_b = thumb.current) == null ? void 0 : _b.focus();
          if (restrictToMarks && marks) {
            const nextValue2 = dir === "rtl" ? getPreviousMarkValue(_value, marks) : getNextMarkValue(_value, marks);
            setValue(nextValue2);
            onChangeEnd == null ? void 0 : onChangeEnd(nextValue2);
            break;
          }
          const nextValue = getFloatingValue(
            Math.min(Math.max(dir === "rtl" ? _value - step : _value + step, min), max),
            precision
          );
          setValue(nextValue);
          onChangeEnd == null ? void 0 : onChangeEnd(nextValue);
          break;
        }
        case "ArrowDown": {
          event.preventDefault();
          (_c = thumb.current) == null ? void 0 : _c.focus();
          if (restrictToMarks && marks) {
            const nextValue2 = getPreviousMarkValue(_value, marks);
            setValue(nextValue2);
            onChangeEnd == null ? void 0 : onChangeEnd(nextValue2);
            break;
          }
          const nextValue = getFloatingValue(
            Math.min(Math.max(_value - step, min), max),
            precision
          );
          setValue(nextValue);
          onChangeEnd == null ? void 0 : onChangeEnd(nextValue);
          break;
        }
        case "ArrowLeft": {
          event.preventDefault();
          (_d = thumb.current) == null ? void 0 : _d.focus();
          if (restrictToMarks && marks) {
            const nextValue2 = dir === "rtl" ? getNextMarkValue(_value, marks) : getPreviousMarkValue(_value, marks);
            setValue(nextValue2);
            onChangeEnd == null ? void 0 : onChangeEnd(nextValue2);
            break;
          }
          const nextValue = getFloatingValue(
            Math.min(Math.max(dir === "rtl" ? _value + step : _value - step, min), max),
            precision
          );
          setValue(nextValue);
          onChangeEnd == null ? void 0 : onChangeEnd(nextValue);
          break;
        }
        case "Home": {
          event.preventDefault();
          (_e = thumb.current) == null ? void 0 : _e.focus();
          if (restrictToMarks && marks) {
            setValue(getFirstMarkValue(marks));
            onChangeEnd == null ? void 0 : onChangeEnd(getFirstMarkValue(marks));
            break;
          }
          setValue(min);
          onChangeEnd == null ? void 0 : onChangeEnd(min);
          break;
        }
        case "End": {
          event.preventDefault();
          (_f = thumb.current) == null ? void 0 : _f.focus();
          if (restrictToMarks && marks) {
            setValue(getLastMarkValue(marks));
            onChangeEnd == null ? void 0 : onChangeEnd(getLastMarkValue(marks));
            break;
          }
          setValue(max);
          onChangeEnd == null ? void 0 : onChangeEnd(max);
          break;
        }
      }
    }
  };
  return /* @__PURE__ */ jsx(SliderProvider, { value: { getStyles }, children: /* @__PURE__ */ jsxs(
    SliderRoot,
    {
      ...others,
      ref: useMergedRef(ref, root),
      onKeyDownCapture: handleTrackKeydownCapture,
      onMouseDownCapture: () => {
        var _a;
        return (_a = root.current) == null ? void 0 : _a.focus();
      },
      size,
      disabled,
      children: [
        /* @__PURE__ */ jsx(
          Track,
          {
            inverted,
            offset: 0,
            filled: position,
            marks,
            min,
            max,
            value: scaledValue,
            disabled,
            containerProps: {
              ref: container,
              onMouseEnter: showLabelOnHover ? () => setHovered(true) : void 0,
              onMouseLeave: showLabelOnHover ? () => setHovered(false) : void 0
            },
            children: /* @__PURE__ */ jsx(
              Thumb,
              {
                max,
                min,
                value: scaledValue,
                position,
                dragging: active,
                label: _label,
                ref: thumb,
                labelTransitionProps,
                labelAlwaysOn,
                thumbLabel,
                showLabelOnHover,
                isHovered: hovered,
                disabled,
                ...thumbProps,
                children: thumbChildren
              }
            )
          }
        ),
        /* @__PURE__ */ jsx("input", { type: "hidden", name, value: scaledValue, ...hiddenInputProps })
      ]
    }
  ) });
});
Slider.classes = classes;
Slider.displayName = "@mantine/core/Slider";
export {
  Slider
};
