var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
import React, { useContext, useMemo, useRef } from "react";
import classnames from "classnames";
import { addUnit, range, addNumber, getSizeStyle, stopPropagation } from "../utils";
import { useTouch } from "../hooks/use-touch";
import { getRect } from "../hooks/get-rect";
import usePassiveHandler from "../hooks/usePassiveHandler";
import ConfigProviderContext from "../config-provider/ConfigProviderContext";
const Slider = (props) => {
  const {
    prefixCls,
    createNamespace
  } = useContext(ConfigProviderContext);
  const [bem] = createNamespace("slider", prefixCls);
  const buttonRef1 = useRef(null);
  const buttonRef2 = useRef(null);
  const buttonIndex = useRef();
  const startValue = useRef();
  const currentValue = useRef(props.value);
  const root = useRef();
  const dragStatus = useRef();
  const touch = useTouch();
  const scope = useMemo(() => Number(props.max) - Number(props.min), [props.max, props.min]);
  const wrapperStyle = useMemo(() => {
    const crossAxis = props.vertical ? "width" : "height";
    return __spreadValues({
      background: props.inactiveColor,
      [crossAxis]: addUnit(props.barHeight)
    }, props.style);
  }, [props.vertical, props.barHeight, props.inactiveColor, props.style]);
  const isRange = (val) => props.range && Array.isArray(val);
  const calcMainAxis = () => {
    const {
      value,
      min
    } = props;
    if (isRange(value)) {
      return `${(value[1] - value[0]) * 100 / scope}%`;
    }
    return `${(+value - Number(min)) * 100 / scope}%`;
  };
  const calcOffset = () => {
    const {
      value,
      min
    } = props;
    if (isRange(value)) {
      return `${(value[0] - Number(min)) * 100 / scope}%`;
    }
    return "0%";
  };
  const barStyle = useMemo(() => {
    const mainAxis = props.vertical ? "height" : "width";
    const style = {
      [mainAxis]: calcMainAxis(),
      background: props.activeColor
    };
    if (dragStatus.current) {
      style.transition = "none";
    }
    const getPositionKey = () => {
      if (props.vertical) {
        return props.reverse ? "bottom" : "top";
      }
      return props.reverse ? "right" : "left";
    };
    style[getPositionKey()] = calcOffset();
    return style;
  }, [calcOffset]);
  const format = (value) => {
    const min = +props.min;
    const max = +props.max;
    const step = +props.step;
    value = range(value, min, max);
    const diff = Math.round((value - min) / step) * step;
    return addNumber(min, diff);
  };
  const isSameValue = (newValue, oldValue) => JSON.stringify(newValue) === JSON.stringify(oldValue);
  const handleRangeValue = (value) => {
    var _a, _b;
    const left = (_a = value[0]) != null ? _a : Number(props.min);
    const right = (_b = value[1]) != null ? _b : Number(props.max);
    return left > right ? [right, left] : [left, right];
  };
  const updateValue = (value, end) => {
    var _a, _b;
    if (isRange(value)) {
      value = handleRangeValue(value).map(format);
    } else {
      value = format(value);
    }
    if (!isSameValue(value, props.value)) {
      (_a = props.onChange) == null ? void 0 : _a.call(props, value);
    }
    if (end && !isSameValue(value, startValue.current)) {
      (_b = props.onChangeAfter) == null ? void 0 : _b.call(props, value);
    }
    return value;
  };
  const onClick = (event) => {
    event.stopPropagation();
    if (props.disabled || props.readonly) {
      return;
    }
    const {
      min,
      reverse,
      vertical,
      value: modelValue
    } = props;
    const rect = getRect(root.current);
    const getDelta = () => {
      if (vertical) {
        if (reverse) {
          return rect.bottom - event.clientY;
        }
        return event.clientY - rect.top;
      }
      if (reverse) {
        return rect.right - event.clientX;
      }
      return event.clientX - rect.left;
    };
    const total = vertical ? rect.height : rect.width;
    const value = Number(min) + getDelta() / total * scope;
    if (isRange(modelValue)) {
      const [left, right] = modelValue;
      const middle = (left + right) / 2;
      if (value <= middle) {
        updateValue([value, right], true);
      } else {
        updateValue([left, value], true);
      }
    } else {
      updateValue(value, true);
    }
  };
  const onTouchStart = (event) => {
    if (props.disabled || props.readonly) {
      return;
    }
    touch.start(event);
    currentValue.current = JSON.parse(JSON.stringify(props.value));
    if (isRange(currentValue.current)) {
      startValue.current = currentValue.current.map(format);
    } else {
      startValue.current = format(currentValue.current);
    }
    dragStatus.current = "start";
  };
  const onTouchMove = (event) => {
    var _a;
    if (props.disabled || props.readonly) {
      return;
    }
    if (dragStatus.current === "start") {
      (_a = props.onDragStart) == null ? void 0 : _a.call(props, event, startValue.current);
    }
    touch.move(event);
    dragStatus.current = "dragging";
    const rect = getRect(root.current);
    const delta = props.vertical ? touch.deltaY.current : touch.deltaX.current;
    const total = props.vertical ? rect.height : rect.width;
    let diff = delta / total * scope;
    if (props.reverse) {
      diff = -diff;
    }
    if (isRange(startValue.current)) {
      const index = props.reverse ? 1 - buttonIndex.current : buttonIndex.current;
      currentValue.current[index] = startValue.current[index] + diff;
    } else {
      currentValue.current = +startValue.current + diff;
    }
    updateValue(currentValue.current);
  };
  const onTouchEnd = (event) => {
    var _a;
    if (props.disabled || props.readonly) {
      return;
    }
    if (dragStatus.current === "dragging") {
      const value = updateValue(currentValue.current, true);
      (_a = props.onDragEnd) == null ? void 0 : _a.call(props, event, value);
    }
    dragStatus.current = "";
  };
  const getButtonClassName = (index) => {
    if (typeof index === "number") {
      const position = ["left", "right"];
      return bem("button-wrapper", position[index]);
    }
    return bem("button-wrapper", props.reverse ? "left" : "right");
  };
  const renderButtonContent = (value, index) => {
    if (typeof index === "number") {
      const slot = props[index === 0 ? "leftButton" : "rightButton"];
      if (slot) {
        return slot;
      }
    }
    if (typeof props.button === "function") {
      return props.button({
        value
      });
    }
    if (props.button) {
      return props.button;
    }
    return /* @__PURE__ */ React.createElement("div", {
      className: classnames(bem("button")),
      style: getSizeStyle(props.buttonSize)
    });
  };
  const renderButton = (buttounRef, index) => {
    const value = typeof index === "number" ? props.value[index] : props.value;
    return /* @__PURE__ */ React.createElement("div", {
      ref: buttounRef,
      key: index,
      role: "slider",
      className: classnames(getButtonClassName(index)),
      tabIndex: props.disabled || props.readonly ? -1 : 0,
      "aria-valuemin": props.min,
      "aria-valuenow": value,
      "aria-valuemax": props.max,
      "aria-orientation": props.vertical ? "vertical" : "horizontal",
      onTouchStart: (event) => {
        if (typeof index === "number") {
          buttonIndex.current = index;
        }
        onTouchStart(event);
      },
      onTouchMove,
      onTouchEnd,
      onTouchCancel: onTouchEnd,
      onClick: stopPropagation
    }, renderButtonContent(currentValue.current, index));
  };
  usePassiveHandler();
  return /* @__PURE__ */ React.createElement("div", {
    ref: root,
    style: wrapperStyle,
    className: classnames(props.className, bem({
      vertical: props.vertical,
      disabled: props.disabled
    })),
    onClick
  }, /* @__PURE__ */ React.createElement("div", {
    className: classnames(bem("bar")),
    style: barStyle
  }, props.range ? [renderButton(buttonRef1, 0), renderButton(buttonRef2, 1)] : renderButton(buttonRef1)));
};
Slider.defaultProps = {
  min: 0,
  max: 100,
  step: 1,
  range: false
};
var stdin_default = Slider;
export {
  stdin_default as default
};
