import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { createBEM } from '@zarm-design/bem';
import { useDrag } from '@use-gesture/react';
import isPlainObject from 'lodash/isPlainObject';
import Events from '../utils/events';
import Tooltip from '../tooltip';
import ensureValuePrecision from './utils/ensureValuePrecision';
import getValue from './utils/getValue';
import { ConfigContext } from '../config-provider';
var Slider = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var _React$useContext = React.useContext(ConfigContext),
      prefixCls = _React$useContext.prefixCls;

  var bem = createBEM('slider', {
    prefixCls: prefixCls
  });
  var className = props.className,
      disabled = props.disabled,
      min = props.min,
      max = props.max,
      vertical = props.vertical,
      showMark = props.showMark,
      value = props.value,
      marks = props.marks,
      onChange = props.onChange,
      onSlideChange = props.onSlideChange,
      defaultValue = props.defaultValue,
      style = props.style;

  var _useState = useState(false),
      _useState2 = _slicedToArray(_useState, 2),
      tooltip = _useState2[0],
      setTooltip = _useState2[1];

  var _React$useState = React.useState(getValue(props, 0)),
      _React$useState2 = _slicedToArray(_React$useState, 2),
      currentValue = _React$useState2[0],
      setCurrentValue = _React$useState2[1];

  var lineRef = React.useRef(null);

  var getMaxOffset = function getMaxOffset() {
    var _lineRef$current;

    var divRect = lineRef === null || lineRef === void 0 ? void 0 : (_lineRef$current = lineRef.current) === null || _lineRef$current === void 0 ? void 0 : _lineRef$current.getBoundingClientRect();
    return (vertical ? divRect === null || divRect === void 0 ? void 0 : divRect.height : divRect === null || divRect === void 0 ? void 0 : divRect.width) || 0;
  };

  var getOffsetByValue = function getOffsetByValue(val) {
    var maxOffset = getMaxOffset();
    var range = max - min;
    return vertical ? maxOffset * ((max - val) / range) : maxOffset * ((val - min) / range);
  };

  var getValueByOffset = function getValueByOffset(offset) {
    var maxOffset = getMaxOffset();
    var percent = offset / maxOffset;
    var val = vertical ? (1 - percent) * (max - min) + min : Math.round(min + (max - min) * percent);
    return ensureValuePrecision(val, props);
  };

  var offsetStart = useRef(0);
  useEffect(function () {
    var val = getValue({
      defaultValue: defaultValue,
      value: value
    }, 0);
    setCurrentValue(val);
  }, [defaultValue, value]);
  var trackClick = useCallback(function (event) {
    event.stopPropagation();
    if (disabled) return;
    var line = lineRef.current;
    if (!line) return;

    var _line$getBoundingClie = line.getBoundingClientRect(),
        left = _line$getBoundingClie.left,
        top = _line$getBoundingClie.top;

    var offset = vertical ? event.clientY - top : event.clientX - left;
    var current = getValueByOffset(offset);
    current = Math.min(max, Math.max(min, current));
    setCurrentValue(current);

    if (typeof onChange === 'function') {
      onChange(current);
    }
  }, [onChange, max, min]);
  var bind = useDrag(function (state) {
    var offsetX = state.xy[0] - state.initial[0],
        offsetY = state.xy[1] - state.initial[1];
    state.event.stopPropagation();

    if (state.first) {
      offsetStart.current = getOffsetByValue(currentValue);
      setTooltip(true);
    }

    var offset = vertical ? offsetY : offsetX;
    offset += offsetStart.current;
    var maxOffset = getMaxOffset();
    offset = Math.min(maxOffset, Math.max(offset, 0));
    var current = getValueByOffset(offset);
    setCurrentValue(current);

    if (state.dragging && !state.first) {
      onSlideChange === null || onSlideChange === void 0 ? void 0 : onSlideChange(current);
    }

    if (state.last) {
      setTooltip(false);
      onChange === null || onChange === void 0 ? void 0 : onChange(currentValue);
    }
  }, {
    enabled: !props.disabled,
    axis: vertical ? 'y' : 'x',
    pointer: {
      touch: true
    },
    preventDefault: !Events.supportsPassiveEvents
  });

  var renderMark = function renderMark() {
    var isEmptyMarks = !isPlainObject(marks) || JSON.stringify(marks) === '{}';

    if (showMark && isEmptyMarks) {
      console.error('请输入有效的 marks');
      return null;
    } // 判断是否为空对象


    if (isEmptyMarks) {
      return null;
    }

    var markKeys = Object.keys(marks || {});
    var lineDot = markKeys.map(function (item) {
      var dotStyle = bem('dot', [{
        active: currentValue >= +item
      }]);

      var markStyle = _defineProperty({}, "".concat(vertical ? 'bottom' : 'left'), "".concat(item, "%"));

      return /*#__PURE__*/React.createElement("span", {
        key: item,
        className: dotStyle,
        style: markStyle
      });
    });

    if (!showMark) {
      return lineDot;
    }

    var marksElement = markKeys.map(function (item) {
      var markStyle = _defineProperty({}, "".concat(vertical ? 'bottom' : 'left'), "".concat(item, "%"));

      return /*#__PURE__*/React.createElement("span", {
        key: item,
        className: bem('mark'),
        style: markStyle
      }, marks === null || marks === void 0 ? void 0 : marks[+item]);
    });
    return /*#__PURE__*/React.createElement(React.Fragment, null, lineDot, /*#__PURE__*/React.createElement("div", {
      className: bem('marks')
    }, marksElement));
  };

  var cls = bem([{
    disabled: disabled,
    vertical: vertical,
    marked: showMark
  }, className]);
  var ratio = (currentValue - min) / (max - min);
  var offset = "".concat(ratio * 100, "%");

  var knobStyle = _defineProperty({}, "".concat(vertical ? 'bottom' : 'left'), offset || 0);

  var lineBg = _defineProperty({}, "".concat(vertical ? 'height' : 'width'), offset || 0);

  return /*#__PURE__*/React.createElement("div", {
    className: cls,
    ref: ref,
    style: style
  }, /*#__PURE__*/React.createElement("div", {
    className: bem('content')
  }, /*#__PURE__*/React.createElement("div", {
    className: bem('line'),
    ref: lineRef,
    onClick: trackClick
  }, /*#__PURE__*/React.createElement("div", {
    className: bem('line__bg'),
    style: lineBg
  }), renderMark()), /*#__PURE__*/React.createElement("div", _extends({
    className: bem('knob'),
    role: "slider",
    "aria-valuemin": min,
    "aria-valuemax": max,
    "aria-valuenow": value,
    "aria-orientation": vertical ? 'vertical' : 'horizontal',
    style: knobStyle
  }, bind()), /*#__PURE__*/React.createElement(Tooltip, {
    trigger: "manual",
    arrowPointAtCenter: true,
    visible: tooltip,
    content: currentValue
  }, /*#__PURE__*/React.createElement("div", {
    className: bem('knob__shadow')
  })))));
});
Slider.displayName = 'Slider';
Slider.defaultProps = {
  disabled: false,
  showMark: false,
  vertical: false,
  step: 1,
  min: 0,
  max: 100,
  marks: {}
};
export default Slider;