"use strict";

function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _framerMotion = require("framer-motion");
var _DropdownBubble = _interopRequireWildcard(require("../../Atoms/DropdownBubble"));
var _Typography = _interopRequireDefault(require("../../Atoms/Typography"));
var _utils = require("./utils");
var _SliderKnob = require("./SliderKnob");
var _SliderTrack = require("./SliderTrack");
var _SliderTrackHighlight = require("./SliderTrackHighlight");
var _utils2 = require("../../common/utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var clamp = function clamp(val, min, max) {
  if (val < min) {
    return min;
  }
  if (val > max) {
    return max;
  }
  return val;
};
var getDecimalPrecision = function getDecimalPrecision(num) {
  if (Math.abs(num) < 1) {
    var parts = num.toExponential().split('e-');
    var matissaDecimalPart = parts[0].split('.')[1];
    return (matissaDecimalPart ? matissaDecimalPart.length : 0) + parseInt(parts[1], 10);
  }
  var decimalPart = num.toString().split('.')[1];
  return decimalPart ? decimalPart.length : 0;
};
var roundValueToStep = function roundValueToStep(value, step, min) {
  var nearest = Math.round((value - min) / step) * step + min;
  return Number(nearest.toFixed(getDecimalPrecision(step)));
};
var percentToValue = function percentToValue(percent, min, max) {
  return (max - min) * percent + min;
};
var valueToPercent = function valueToPercent(value, min, max) {
  var percent = (value - min) * 100 / (max - min);
  if (percent < 0) {
    return 0;
  }
  if (percent > 100) {
    return 100;
  }
  return percent;
};
var getNewValue = function getNewValue(clickPosition, track, props) {
  if (!track || !clickPosition) {
    return null;
  }
  var min = props.min,
    max = props.max,
    step = props.step;
  var _track$getBoundingCli = track.getBoundingClientRect(),
    left = _track$getBoundingCli.left,
    width = _track$getBoundingCli.width;
  var diff = clickPosition - left;
  var percent = diff / width;
  var newValue = percentToValue(percent, min, max);
  var newValueRounded = roundValueToStep(newValue, step, min);
  return clamp(newValueRounded, min, max);
};
var Container = _styledComponents.default.div.withConfig({
  displayName: "Slider__Container",
  componentId: "sc-1eqxzz-0"
})(["display:flex;align-items:center;height:", ";margin:0 ", ";"], function (p) {
  return "".concat((0, _utils.getKnobSize)(p.$variant), "px");
}, function (p) {
  return "".concat((0, _utils.getKnobSize)(p.$variant) / 2, "px");
});
var StyledDropdownBubble = (0, _styledComponents.default)(_DropdownBubble.default).withConfig({
  displayName: "Slider__StyledDropdownBubble",
  componentId: "sc-1eqxzz-1"
})(["transform:", ";padding:6px 8px;border-radius:", ";"], function (p) {
  return "translate(-50%, calc(-100% - ".concat((0, _utils.getKnobSize)(p.$variant) / 2 + _DropdownBubble.TRIANGLE_SIZE + (0, _utils.getHeight)(p.$variant) / 2, "px))");
}, function (_ref) {
  var theme = _ref.theme;
  return theme.borderRadius2;
});
var Slider = function Slider(_ref2) {
  var defaultValue = _ref2.defaultValue,
    disabled = _ref2.disabled,
    _ref2$formatter = _ref2.formatter,
    formatter = _ref2$formatter === void 0 ? function (value) {
      return value.toString();
    } : _ref2$formatter,
    max = _ref2.max,
    min = _ref2.min,
    onChange = _ref2.onChange,
    readOnly = _ref2.readOnly,
    showTooltip = _ref2.showTooltip,
    sliderColor = _ref2.sliderColor,
    step = _ref2.step,
    controlledValue = _ref2.value,
    _ref2$variant = _ref2.variant,
    variant = _ref2$variant === void 0 ? 'big' : _ref2$variant;
  var trackRef = (0, _react.useRef)(null);
  var handleRef = (0, _react.useRef)(null);
  var isControlled = (0, _utils2.isNumber)(controlledValue);
  var _useState = (0, _react.useState)(null),
    _useState2 = _slicedToArray(_useState, 2),
    hoverPosition = _useState2[0],
    setHoverPosition = _useState2[1];
  var _useState3 = (0, _react.useState)(false),
    _useState4 = _slicedToArray(_useState3, 2),
    hoverVisible = _useState4[0],
    setHoverVisible = _useState4[1];
  var _useState5 = (0, _react.useState)(defaultValue || min),
    _useState6 = _slicedToArray(_useState5, 2),
    valueInternal = _useState6[0],
    setValueInternal = _useState6[1];
  var value = isControlled ? controlledValue : valueInternal;
  var trackPercent = valueToPercent(value, min, max);
  var handlePosition = "calc(".concat(trackPercent, "% - ").concat((0, _utils.getKnobSize)(variant) / 2, "px)");
  var updateValue = function updateValue(newValue) {
    if (!isControlled) {
      setValueInternal(newValue);
    }
    if ((0, _utils2.isFunction)(onChange)) {
      onChange(newValue);
    }
  };
  var handleChange = function handleChange(clickPosition) {
    if (!disabled && !readOnly) {
      var newValue = getNewValue(clickPosition, trackRef.current, {
        min: min,
        max: max,
        step: step
      });
      if (newValue !== null) {
        updateValue(newValue);
      }
    }
  };
  var handleHover = function handleHover(pos) {
    if (!disabled && !readOnly) {
      var newValue = getNewValue(pos, trackRef.current, {
        min: min,
        max: max,
        step: step
      });
      if (newValue) {
        setHoverPosition(newValue);
      }
      if (!hoverVisible) {
        setHoverVisible(true);
      }
    }
  };
  var handleMouseMove = function handleMouseMove(event) {
    event.stopPropagation();
    event.preventDefault();
    var pointerPosition = event.clientX;
    handleChange(pointerPosition);
  };
  var handleMouseHover = function handleMouseHover(event) {
    var pointerPosition = event.clientX;
    handleHover(pointerPosition);
  };
  var handleMouseLeave = function handleMouseLeave() {
    setHoverVisible(false);
  };
  var handleMouseUp = function handleMouseUp() {
    document.removeEventListener('mouseup', handleMouseUp);
    document.removeEventListener('mousemove', handleMouseMove);
  };
  var handleMouseDown = function handleMouseDown() {
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  };
  var handleTouchMove = function handleTouchMove(event) {
    event.stopPropagation();
    event.preventDefault();
    var touchPosition = event.touches[0].clientX;
    handleHover(touchPosition);
    handleChange(touchPosition);
  };
  var handleTouchEnd = function handleTouchEnd() {
    document.removeEventListener('touchend', handleTouchEnd);
    document.removeEventListener('touchmove', handleTouchMove);
    setHoverVisible(false);
  };
  var handleTouchStart = function handleTouchStart() {
    document.addEventListener('touchmove', handleTouchMove);
    document.addEventListener('touchend', handleTouchEnd);
  };
  var handleKnobClick = function handleKnobClick(event) {
    event.stopPropagation();
  };
  var handleTrackClick = function handleTrackClick(event) {
    var _handleRef$current;
    var pointerPosition = event.clientX;
    (_handleRef$current = handleRef.current) === null || _handleRef$current === void 0 || _handleRef$current.focus();
    handleChange(pointerPosition);
  };
  var handleKeyDown = function handleKeyDown(event) {
    if (!disabled) {
      var increase = event.key && ['ArrowRight', 'ArrowUp'].includes(event.key);
      var decrease = event.key && ['ArrowLeft', 'ArrowDown'].includes(event.key);
      var newValue = value;
      if (increase) {
        newValue = value + step;
      }
      if (decrease) {
        newValue = value - step;
      }
      updateValue(clamp(newValue, min, max));
    }
  };
  return _react.default.createElement(Container, {
    $disabled: disabled,
    $sliderColor: sliderColor,
    $variant: variant,
    onClick: handleTrackClick,
    ref: trackRef,
    tabIndex: -1
  }, _react.default.createElement(_SliderTrack.SliderTrack, {
    disabled: disabled,
    onMouseDown: handleMouseDown,
    onMouseLeave: handleMouseLeave,
    onMouseMove: handleMouseHover,
    onMouseUp: handleMouseUp,
    onTouchStart: handleTouchStart,
    readOnly: readOnly,
    sliderColor: sliderColor,
    variant: variant
  }, _react.default.createElement(_SliderTrackHighlight.SliderTrackHighlight, {
    disabled: disabled,
    sliderColor: sliderColor,
    value: trackPercent,
    variant: variant
  }), !readOnly && _react.default.createElement(_framerMotion.AnimatePresence, null, showTooltip && hoverVisible && _react.default.createElement(_framerMotion.motion.div, {
    key: "tooltip",
    initial: {
      opacity: 0
    },
    animate: {
      opacity: 1
    },
    exit: {
      opacity: 0
    },
    transition: {
      opacity: {
        ease: 'easeInOut',
        duration: 0.16
      }
    }
  }, _react.default.createElement(StyledDropdownBubble, {
    $variant: variant,
    position: "center",
    placement: "top",
    invertedColors: true,
    triangle: true,
    style: _objectSpread({
      position: 'absolute'
    }, hoverPosition && {
      marginLeft: "".concat(valueToPercent(hoverPosition, min, max), "% ")
    })
  }, hoverPosition && _react.default.createElement(_Typography.default, {
    type: "tertiary",
    color: function color(t) {
      return t.color.textLight;
    }
  }, formatter(hoverPosition)))), _react.default.createElement(_SliderKnob.SliderKnob, {
    disabled: disabled,
    max: max,
    min: min,
    onClick: handleKnobClick,
    onKeyDown: handleKeyDown,
    onMouseDown: handleMouseDown,
    onMouseUp: handleMouseUp,
    onTouchStart: handleTouchStart,
    ref: handleRef,
    sliderColor: sliderColor,
    style: {
      left: handlePosition
    },
    value: value,
    variant: variant
  }))));
};
var _default = exports.default = Slider;