"use strict";

require("core-js/modules/es.object.define-property.js");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.FcrSlider = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
require("core-js/modules/es.error.cause.js");
require("core-js/modules/es.error.to-string.js");
require("core-js/modules/es.date.to-string.js");
require("core-js/modules/es.number.constructor.js");
require("core-js/modules/es.number.epsilon.js");
require("core-js/modules/es.number.to-fixed.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.regexp.to-string.js");
var _classnames = _interopRequireDefault(require("classnames"));
var _react = require("react");
var _useNamespace = require("../../utilities/use-namespace");
require("./index.css");
var _jsxRuntime = require("react/jsx-runtime");
var isMultiple = function isMultiple(a, b) {
  if (b === 0) {
    throw new Error('The divisor cannot be 0');
  }
  var absA = Math.abs(a);
  var absB = Math.abs(b);
  var quotient = absA / absB;
  return Math.abs(quotient - Math.round(quotient)) < Number.EPSILON;
};
var FcrSlider = exports.FcrSlider = function FcrSlider(_ref) {
  var value = _ref.value,
    _ref$defaultValue = _ref.defaultValue,
    defaultValue = _ref$defaultValue === void 0 ? 0 : _ref$defaultValue,
    _ref$step = _ref.step,
    step = _ref$step === void 0 ? 1 : _ref$step,
    _ref$min = _ref.min,
    min = _ref$min === void 0 ? 0 : _ref$min,
    _ref$max = _ref.max,
    max = _ref$max === void 0 ? 100 : _ref$max,
    onChange = _ref.onChange,
    draggableDom = _ref.draggableDom,
    _ref$disabled = _ref.disabled,
    disabled = _ref$disabled === void 0 ? false : _ref$disabled;
  if (step <= 0) {
    throw new Error('Step must be greater than 0!');
  }
  if (!isMultiple(max - min, step) || !isMultiple(defaultValue - min, step)) {
    throw new Error('Step must be divisible by max or defaultValue!');
  }
  draggableDom = draggableDom || document;
  var ns = (0, _useNamespace.useNamespace)('slider');
  var sliderRef = (0, _react.useRef)(null);
  var thumbRef = (0, _react.useRef)(null);
  var diff = (0, _react.useRef)(0);
  var _useState = (0, _react.useState)(false),
    _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
    isActive = _useState2[0],
    setIsActive = _useState2[1];

  // 获取 step 的小数位数，以处理计算过程中的小数精度问题
  var stepDecimalPlaces = (0, _react.useMemo)(function () {
    return (step.toString().split('.')[1] || []).length;
  }, [step]);
  var getValueByPercentage = (0, _react.useCallback)(function (percentage) {
    // 将所有数转为整数，避免计算精度问题
    var power = Math.pow(10, stepDecimalPlaces);
    var intMin = min * power;
    var intMax = max * power;
    var intStep = step * power;
    var initialValue = intMin + (intMax - intMin) * percentage / 100;
    return (intMin + Math.round((initialValue - intMin) / intStep) * intStep) / power;
  }, [max, min, step, stepDecimalPlaces]);
  var getWidthPercentByValue = (0, _react.useCallback)(function (value) {
    var _value = Math.max(Math.min(value, max), min);
    return Number((Math.round((_value - min) / step) * step * 100 / (max - min)).toFixed(2));
  }, [max, min, step]);
  var handleMouseDown = function handleMouseDown(event) {
    diff.current = event.clientX - thumbRef.current.getBoundingClientRect().left;
    setIsActive(true);
    draggableDom.addEventListener('mousemove', handleMouseMove);
    draggableDom.addEventListener('mouseup', handleMouseUp);
    draggableDom.addEventListener('mouseleave', handleMouseLeave);
  };
  var handleMouseLeave = function handleMouseLeave() {
    cleanupListeners();
  };
  var cleanupListeners = function cleanupListeners() {
    setIsActive(false);
    draggableDom.removeEventListener('mousemove', handleMouseMove);
    draggableDom.removeEventListener('mouseup', handleMouseUp);
    draggableDom.removeEventListener('mouseleave', handleMouseLeave);
  };
  var handleMouseMove = (0, _react.useCallback)(function (event) {
    if (!sliderRef.current) {
      return;
    }

    // 检查鼠标是否在 draggableDom 内
    if (draggableDom instanceof HTMLElement) {
      var rect = draggableDom.getBoundingClientRect();
      var isInDraggableDom = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom;
      if (!isInDraggableDom) {
        handleMouseLeave();
        return;
      }
    }
    var newX = event.clientX - diff.current - sliderRef.current.getBoundingClientRect().left;
    var end = sliderRef.current.offsetWidth - thumbRef.current.offsetWidth;
    var start = 0;
    if (newX < start) {
      newX = 0;
    } else if (newX > end) {
      newX = end;
    }
    var newPercentage = newX * 100 / end;
    var newValue = getValueByPercentage(newPercentage);
    if (value === undefined) {
      setWidthPercent(getWidthPercentByValue(newValue));
    }
    onChange && onChange(newValue);
  }, [isActive]);
  var handleMouseUp = function handleMouseUp() {
    cleanupListeners();
  };
  var _useState3 = (0, _react.useState)(getWidthPercentByValue(defaultValue)),
    _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
    widthPercent = _useState4[0],
    setWidthPercent = _useState4[1];
  (0, _react.useEffect)(function () {
    if (value !== undefined) {
      setWidthPercent(getWidthPercentByValue(value));
    }
  }, [getWidthPercentByValue, value]);
  (0, _react.useEffect)(function () {
    var _thumbRef$current;
    if (disabled) {
      return;
    }
    if (!thumbRef.current) return;
    (_thumbRef$current = thumbRef.current) === null || _thumbRef$current === void 0 || _thumbRef$current.addEventListener('mousedown', handleMouseDown);
    return function () {
      var _thumbRef$current2;
      setIsActive(false);
      (_thumbRef$current2 = thumbRef.current) === null || _thumbRef$current2 === void 0 || _thumbRef$current2.removeEventListener('mousedown', handleMouseDown);
      draggableDom.removeEventListener('mousemove', handleMouseMove);
      draggableDom.removeEventListener('mouseup', handleMouseUp);
    };
  }, [getValueByPercentage, getWidthPercentByValue, draggableDom, disabled]);
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
    className: (0, _classnames["default"])(ns.b(), ns.is('disabled', disabled), ns.is('active', isActive)),
    ref: sliderRef,
    children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: ns.e('track'),
      style: {
        width: "".concat(widthPercent, "%")
      }
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
      className: ns.e('thumb'),
      ref: thumbRef,
      style: {
        left: "calc(".concat(widthPercent, "% - 7px)")
      }
    })]
  });
};