"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const aria = require("../../../../constants/aria.js");
const event = require("../../../../constants/event.js");
const event$1 = require("../../../../utils/dom/event.js");
const types = require("../../../../utils/types.js");
const constants = require("../constants.js");
const index = require("../../../../../node_modules/@vueuse/core/index.js");
const vue = require("vue");
const debounce = require("../../../../../../lodash-es/debounce.js");
const clamp = require("../../../../../../lodash-es/clamp.js");
const useTooltip = (props, formatTooltip, showTooltip) => {
  const tooltip = vue.ref();
  const tooltipVisible = vue.ref(false);
  const enableFormat = vue.computed(() => {
    return formatTooltip.value instanceof Function;
  });
  return {
    tooltip,
    tooltipVisible,
    formatValue: vue.computed(() => {
      return enableFormat.value && formatTooltip.value(props.modelValue) || props.modelValue;
    }),
    displayTooltip: debounce.default(() => {
      showTooltip.value && (tooltipVisible.value = true);
    }, 50),
    hideTooltip: debounce.default(() => {
      showTooltip.value && (tooltipVisible.value = false);
    }, 50)
  };
};
const useSliderButton = (props, initData, emit) => {
  const { disabled, min, max, step, showTooltip, persistent, precision, sliderSize, formatTooltip, emitChange, resetSize, updateDragging, markList } = vue.inject(constants.sliderContextKey);
  const { tooltip, tooltipVisible, formatValue, displayTooltip, hideTooltip } = useTooltip(props, formatTooltip, showTooltip);
  const button = vue.ref();
  const currentPosition = vue.computed(() => {
    return `${(props.modelValue - min.value) / (max.value - min.value) * 100}%`;
  });
  const wrapperStyle = vue.computed(() => {
    return props.vertical ? { bottom: currentPosition.value } : { left: currentPosition.value };
  });
  const shouldMoveToMark = vue.computed(() => {
    return step.value === "mark" && markList.value.length > 0;
  });
  const handleMouseEnter = () => {
    initData.hovering = true;
    displayTooltip();
  };
  const handleMouseLeave = () => {
    initData.hovering = false;
    if (!initData.dragging) hideTooltip();
  };
  const onButtonDown = (event2) => {
    if (disabled.value) return;
    event2.preventDefault();
    onDragStart(event2);
    window.addEventListener("mousemove", onDragging);
    window.addEventListener("touchmove", onDragging);
    window.addEventListener("mouseup", onDragEnd);
    window.addEventListener("touchend", onDragEnd);
    window.addEventListener("contextmenu", onDragEnd);
    button.value.focus();
  };
  const incrementPosition = (amount) => {
    if (disabled.value) return;
    initData.newPosition = Number.parseFloat(currentPosition.value) + amount / (max.value - min.value) * 100;
    setPosition(initData.newPosition);
    emitChange();
  };
  const moveToMark = (amount) => {
    if (disabled.value || !markList.value.length) return;
    const current = props.modelValue;
    const epsilon = Number.EPSILON;
    const stride = Math.abs(amount);
    let target;
    if (amount > 0) {
      const startIndex = markList.value.findIndex((m) => m.point > current + epsilon);
      if (startIndex !== -1) {
        const targetIndex = Math.min(startIndex + stride - 1, markList.value.length - 1);
        target = markList.value[targetIndex].point;
      }
    } else {
      let startIndex = -1;
      for (let i = markList.value.length - 1; i >= 0; i--) if (markList.value[i].point < current - epsilon) {
        startIndex = i;
        break;
      }
      if (startIndex !== -1) {
        const targetIndex = Math.max(startIndex - (stride - 1), 0);
        target = markList.value[targetIndex].point;
      }
    }
    if (target !== void 0 && target !== current) {
      setPosition((target - min.value) / (max.value - min.value) * 100);
      emitChange();
    }
  };
  const onLeftKeyDown = () => {
    if (shouldMoveToMark.value) moveToMark(-1);
    else if (types.isNumber(step.value)) incrementPosition(-step.value);
  };
  const onRightKeyDown = () => {
    if (shouldMoveToMark.value) moveToMark(1);
    else if (types.isNumber(step.value)) incrementPosition(step.value);
  };
  const onPageDownKeyDown = () => {
    if (shouldMoveToMark.value) moveToMark(-4);
    else if (types.isNumber(step.value)) incrementPosition(-step.value * 4);
  };
  const onPageUpKeyDown = () => {
    if (shouldMoveToMark.value) moveToMark(4);
    else if (types.isNumber(step.value)) incrementPosition(step.value * 4);
  };
  const onHomeKeyDown = () => {
    if (disabled.value) return;
    setPosition(0);
    emitChange();
  };
  const onEndKeyDown = () => {
    if (disabled.value) return;
    setPosition(100);
    emitChange();
  };
  const onKeyDown = (event2) => {
    const code = event$1.getEventCode(event2);
    let isPreventDefault = true;
    switch (code) {
      case aria.EVENT_CODE.left:
      case aria.EVENT_CODE.down:
        onLeftKeyDown();
        break;
      case aria.EVENT_CODE.right:
      case aria.EVENT_CODE.up:
        onRightKeyDown();
        break;
      case aria.EVENT_CODE.home:
        onHomeKeyDown();
        break;
      case aria.EVENT_CODE.end:
        onEndKeyDown();
        break;
      case aria.EVENT_CODE.pageDown:
        onPageDownKeyDown();
        break;
      case aria.EVENT_CODE.pageUp:
        onPageUpKeyDown();
        break;
      default:
        isPreventDefault = false;
        break;
    }
    isPreventDefault && event2.preventDefault();
  };
  const getClientXY = (event2) => {
    let clientX;
    let clientY;
    if (event2.type.startsWith("touch")) {
      clientY = event2.touches[0].clientY;
      clientX = event2.touches[0].clientX;
    } else {
      clientY = event2.clientY;
      clientX = event2.clientX;
    }
    return {
      clientX,
      clientY
    };
  };
  const onDragStart = (event2) => {
    initData.dragging = true;
    initData.isClick = true;
    const { clientX, clientY } = getClientXY(event2);
    if (props.vertical) initData.startY = clientY;
    else initData.startX = clientX;
    initData.startPosition = Number.parseFloat(currentPosition.value);
    initData.newPosition = initData.startPosition;
  };
  const onDragging = (event2) => {
    if (initData.dragging) {
      initData.isClick = false;
      displayTooltip();
      resetSize();
      let diff;
      const { clientX, clientY } = getClientXY(event2);
      if (props.vertical) {
        initData.currentY = clientY;
        diff = (initData.startY - initData.currentY) / sliderSize.value * 100;
      } else {
        initData.currentX = clientX;
        diff = (initData.currentX - initData.startX) / sliderSize.value * 100;
      }
      initData.newPosition = initData.startPosition + diff;
      setPosition(initData.newPosition);
    }
  };
  const onDragEnd = () => {
    if (initData.dragging) {
      setTimeout(() => {
        initData.dragging = false;
        if (!initData.hovering) hideTooltip();
        if (!initData.isClick) setPosition(initData.newPosition);
        emitChange();
      }, 0);
      window.removeEventListener("mousemove", onDragging);
      window.removeEventListener("touchmove", onDragging);
      window.removeEventListener("mouseup", onDragEnd);
      window.removeEventListener("touchend", onDragEnd);
      window.removeEventListener("contextmenu", onDragEnd);
    }
  };
  const setPosition = async (newPosition) => {
    if (newPosition === null || Number.isNaN(+newPosition)) return;
    newPosition = clamp.default(newPosition, 0, 100);
    let value;
    if (step.value === "mark") if (markList.value.length === 0) value = newPosition <= 50 ? min.value : max.value;
    else value = markList.value.reduce((prev, curr) => {
      return Math.abs(curr.position - newPosition) < Math.abs(prev.position - newPosition) ? curr : prev;
    }).point;
    else {
      const fullSteps = Math.floor((max.value - min.value) / step.value);
      const fullRangePercentage = fullSteps * step.value / (max.value - min.value) * 100;
      const threshold = fullRangePercentage + (100 - fullRangePercentage) / 2;
      if (newPosition < fullRangePercentage) {
        const valueBetween = fullRangePercentage / fullSteps;
        const steps = Math.round(newPosition / valueBetween);
        value = min.value + steps * step.value;
      } else if (newPosition < threshold) value = min.value + fullSteps * step.value;
      else value = max.value;
      value = Number.parseFloat(value.toFixed(precision.value));
    }
    if (value !== props.modelValue) emit(event.UPDATE_MODEL_EVENT, value);
    if (!initData.dragging && props.modelValue !== initData.oldValue) initData.oldValue = props.modelValue;
    await vue.nextTick();
    initData.dragging && displayTooltip();
    tooltip.value.updatePopper();
  };
  vue.watch(() => initData.dragging, (val) => {
    updateDragging(val);
  });
  index.useEventListener(button, "touchstart", onButtonDown, { passive: false });
  return {
    disabled,
    button,
    tooltip,
    tooltipVisible,
    showTooltip,
    persistent,
    wrapperStyle,
    formatValue,
    handleMouseEnter,
    handleMouseLeave,
    onButtonDown,
    onKeyDown,
    setPosition
  };
};
exports.useSliderButton = useSliderButton;
