import { jsx, jsxs } from "react/jsx-runtime";
import { useState, useRef, useEffect } from "react";
import { rem } from "../../../core/utils/units-converters/rem.mjs";
import { getSize, getRadius } from "../../../core/utils/get-size/get-size.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 { getClientPosition } from "../utils/get-client-position/get-client-position.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 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 { useMove } from "../../../../../../../../@mantine_hooks@7.15.2_react@18.3.1/node_modules/@mantine/hooks/esm/use-move/use-move.mjs";
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 defaultProps = {
  min: 0,
  max: 100,
  minRange: 10,
  step: 1,
  marks: [],
  label: (f) => f,
  labelTransitionProps: { transition: "fade", duration: 0 },
  labelAlwaysOn: false,
  showLabelOnHover: true,
  disabled: false,
  scale: (v) => v
};
const RangeSlider = factory((_props, ref) => {
  const props = useProps("RangeSlider", defaultProps, _props);
  const {
    classNames,
    styles,
    value,
    onChange,
    onChangeEnd,
    size,
    min,
    max,
    minRange,
    maxRange,
    step,
    precision: _precision,
    defaultValue,
    name,
    marks,
    label,
    labelTransitionProps,
    labelAlwaysOn,
    thumbFromLabel,
    thumbToLabel,
    showLabelOnHover,
    thumbChildren,
    disabled,
    unstyled,
    scale,
    inverted,
    className,
    style,
    vars,
    hiddenInputProps,
    thumbProps,
    ...others
  } = props;
  const getStyles = useStyles({
    name: "Slider",
    props,
    classes,
    classNames,
    className,
    styles,
    style,
    vars,
    varsResolver,
    unstyled
  });
  const { dir } = useDirection();
  const [focused, setFocused] = useState(-1);
  const [hovered, setHovered] = useState(false);
  const [_value, setValue] = useUncontrolled({
    value,
    defaultValue,
    finalValue: [min, max],
    onChange
  });
  const valueRef = useRef(_value);
  const thumbs = useRef([]);
  const thumbIndex = useRef(void 0);
  const positions = [
    getPosition({ value: _value[0], min, max }),
    getPosition({ value: _value[1], min, max })
  ];
  const precision = _precision ?? getPrecision(step);
  const _setValue = (val) => {
    setValue(val);
    valueRef.current = val;
  };
  useEffect(
    () => {
      if (Array.isArray(value)) {
        valueRef.current = value;
      }
    },
    Array.isArray(value) ? [value[0], value[1]] : [null, null]
  );
  const setRangedValue = (val, index, triggerChangeEnd) => {
    const clone = [...valueRef.current];
    clone[index] = val;
    if (index === 0) {
      if (val > clone[1] - (minRange - 1e-9)) {
        clone[1] = Math.min(val + minRange, max);
      }
      if (val > (max - (minRange - 1e-9) || min)) {
        clone[index] = valueRef.current[index];
      }
      if (clone[1] - val > maxRange) {
        clone[1] = val + maxRange;
      }
    }
    if (index === 1) {
      if (val < clone[0] + minRange) {
        clone[0] = Math.max(val - minRange, min);
      }
      if (val < clone[0] + minRange) {
        clone[index] = valueRef.current[index];
      }
      if (val - clone[0] > maxRange) {
        clone[0] = val - maxRange;
      }
    }
    clone[0] = getFloatingValue(clone[0], precision);
    clone[1] = getFloatingValue(clone[1], precision);
    _setValue(clone);
    if (triggerChangeEnd) {
      onChangeEnd == null ? void 0 : onChangeEnd(valueRef.current);
    }
  };
  const handleChange = (val) => {
    if (!disabled) {
      const nextValue = getChangeValue({
        value: val,
        min,
        max,
        step,
        precision
      });
      setRangedValue(nextValue, thumbIndex.current, false);
    }
  };
  const { ref: container, active } = useMove(
    ({ x }) => handleChange(x),
    { onScrubEnd: () => onChangeEnd == null ? void 0 : onChangeEnd(valueRef.current) },
    dir
  );
  function handleThumbMouseDown(index) {
    thumbIndex.current = index;
  }
  const handleTrackMouseDownCapture = (event) => {
    container.current.focus();
    const rect = container.current.getBoundingClientRect();
    const changePosition = getClientPosition(event.nativeEvent);
    const changeValue = getChangeValue({
      value: changePosition - rect.left,
      max,
      min,
      step,
      containerWidth: rect.width
    });
    const nearestHandle = Math.abs(_value[0] - changeValue) > Math.abs(_value[1] - changeValue) ? 1 : 0;
    const _nearestHandle = dir === "ltr" ? nearestHandle : nearestHandle === 1 ? 0 : 1;
    thumbIndex.current = _nearestHandle;
  };
  const getFocusedThumbIndex = () => {
    if (focused !== 1 && focused !== 0) {
      setFocused(0);
      return 0;
    }
    return focused;
  };
  const handleTrackKeydownCapture = (event) => {
    if (!disabled) {
      switch (event.key) {
        case "ArrowUp": {
          event.preventDefault();
          const focusedIndex = getFocusedThumbIndex();
          thumbs.current[focusedIndex].focus();
          setRangedValue(
            getFloatingValue(
              Math.min(Math.max(valueRef.current[focusedIndex] + step, min), max),
              precision
            ),
            focusedIndex,
            true
          );
          break;
        }
        case "ArrowRight": {
          event.preventDefault();
          const focusedIndex = getFocusedThumbIndex();
          thumbs.current[focusedIndex].focus();
          setRangedValue(
            getFloatingValue(
              Math.min(
                Math.max(
                  dir === "rtl" ? valueRef.current[focusedIndex] - step : valueRef.current[focusedIndex] + step,
                  min
                ),
                max
              ),
              precision
            ),
            focusedIndex,
            true
          );
          break;
        }
        case "ArrowDown": {
          event.preventDefault();
          const focusedIndex = getFocusedThumbIndex();
          thumbs.current[focusedIndex].focus();
          setRangedValue(
            getFloatingValue(
              Math.min(Math.max(valueRef.current[focusedIndex] - step, min), max),
              precision
            ),
            focusedIndex,
            true
          );
          break;
        }
        case "ArrowLeft": {
          event.preventDefault();
          const focusedIndex = getFocusedThumbIndex();
          thumbs.current[focusedIndex].focus();
          setRangedValue(
            getFloatingValue(
              Math.min(
                Math.max(
                  dir === "rtl" ? valueRef.current[focusedIndex] + step : valueRef.current[focusedIndex] - step,
                  min
                ),
                max
              ),
              precision
            ),
            focusedIndex,
            true
          );
          break;
        }
      }
    }
  };
  const sharedThumbProps = {
    max,
    min,
    size,
    labelTransitionProps,
    labelAlwaysOn,
    onBlur: () => setFocused(-1)
  };
  const hasArrayThumbChildren = Array.isArray(thumbChildren);
  return /* @__PURE__ */ jsx(SliderProvider, { value: { getStyles }, children: /* @__PURE__ */ jsxs(SliderRoot, { ...others, size, ref, disabled, children: [
    /* @__PURE__ */ jsxs(
      Track,
      {
        offset: positions[0],
        marksOffset: _value[0],
        filled: positions[1] - positions[0],
        marks,
        inverted,
        min,
        max,
        value: _value[1],
        disabled,
        containerProps: {
          ref: container,
          onMouseEnter: showLabelOnHover ? () => setHovered(true) : void 0,
          onMouseLeave: showLabelOnHover ? () => setHovered(false) : void 0,
          onTouchStartCapture: handleTrackMouseDownCapture,
          onTouchEndCapture: () => {
            thumbIndex.current = -1;
          },
          onMouseDownCapture: handleTrackMouseDownCapture,
          onMouseUpCapture: () => {
            thumbIndex.current = -1;
          },
          onKeyDownCapture: handleTrackKeydownCapture
        },
        children: [
          /* @__PURE__ */ jsx(
            Thumb,
            {
              ...sharedThumbProps,
              value: scale(_value[0]),
              position: positions[0],
              dragging: active,
              label: typeof label === "function" ? label(getFloatingValue(scale(_value[0]), precision)) : label,
              ref: (node) => {
                thumbs.current[0] = node;
              },
              thumbLabel: thumbFromLabel,
              onMouseDown: () => handleThumbMouseDown(0),
              onFocus: () => setFocused(0),
              showLabelOnHover,
              isHovered: hovered,
              disabled,
              ...thumbProps == null ? void 0 : thumbProps(0),
              children: hasArrayThumbChildren ? thumbChildren[0] : thumbChildren
            }
          ),
          /* @__PURE__ */ jsx(
            Thumb,
            {
              ...sharedThumbProps,
              thumbLabel: thumbToLabel,
              value: scale(_value[1]),
              position: positions[1],
              dragging: active,
              label: typeof label === "function" ? label(getFloatingValue(scale(_value[1]), precision)) : label,
              ref: (node) => {
                thumbs.current[1] = node;
              },
              onMouseDown: () => handleThumbMouseDown(1),
              onFocus: () => setFocused(1),
              showLabelOnHover,
              isHovered: hovered,
              disabled,
              ...thumbProps == null ? void 0 : thumbProps(1),
              children: hasArrayThumbChildren ? thumbChildren[1] : thumbChildren
            }
          )
        ]
      }
    ),
    /* @__PURE__ */ jsx("input", { type: "hidden", name: `${name}_from`, value: _value[0], ...hiddenInputProps }),
    /* @__PURE__ */ jsx("input", { type: "hidden", name: `${name}_to`, value: _value[1], ...hiddenInputProps })
  ] }) });
});
RangeSlider.classes = classes;
RangeSlider.displayName = "@mantine/core/RangeSlider";
export {
  RangeSlider
};
