import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import { createVNode as _createVNode } from "vue";
import _extends from "@babel/runtime/helpers/esm/extends";
import { cloneVNode, computed, defineComponent, onBeforeUnmount, onMounted, ref } from 'vue';
import VcSlider, { sliderProps as vcSliderProps } from '../ng-slider';
import { withInstall } from '../_util/type';
import abstractTooltipProps from '../tooltip/abstractTooltipProps';
import { useInjectSliderInternal } from './Context';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style';
import { useInjectDisabled } from '../config-provider/DisabledContext';
import useRafLock from './useRafLock';
import classnames from '../_util/classNames';
import raf from '../_util/raf';
import SliderTooltip from './SliderTooltip';
export const sliderProps = () => _extends(_extends({}, vcSliderProps()), {
  classNames: Object,
  styles: Object
});
export const sliderTooltipProps = () => _extends(_extends({}, abstractTooltipProps()), {
  prefixCls: String,
  open: {
    type: Boolean,
    default: undefined
  },
  placement: String,
  getPopupContainer: Function,
  formatter: Function,
  autoAdjustOverflow: {
    type: Boolean,
    default: undefined
  }
});
export const sliderBaseProps = () => ({
  prefixCls: String,
  reverse: Boolean,
  min: Number,
  max: Number,
  step: Number,
  marks: Object,
  dots: Boolean,
  included: {
    type: Boolean,
    default: true
  },
  disabled: Boolean,
  keyboard: {
    type: Boolean,
    default: true
  },
  vertical: Boolean,
  className: String,
  rootClassName: String,
  id: String,
  style: Object,
  tooltip: {
    type: Object
  },
  autoFocus: Boolean,
  styles: Object,
  classNames: Object,
  onFocus: Function,
  onBlur: Function,
  /** @deprecated `tooltipPrefixCls` is deprecated. Please use `tooltip.prefixCls` instead. */
  tooltipPrefixCls: String,
  /** @deprecated `tipFormatter` is deprecated. Please use `tooltip.formatter` instead. */
  tipFormatter: Function,
  /** @deprecated `tooltipVisible` is deprecated. Please use `tooltip.open` instead. */
  tooltipVisible: {
    type: Boolean,
    default: undefined
  },
  /**
   * @deprecated `getTooltipPopupContainer` is deprecated. Please use `tooltip.getPopupContainer`
   *   instead.
   */
  getTooltipPopupContainer: Function,
  /** @deprecated `tooltipPlacement` is deprecated. Please use `tooltip.placement` instead. */
  tooltipPlacement: String,
  // Accessibility
  tabIndex: [Number, Array],
  ariaLabelForHandle: [String, Array],
  ariaLabelledByForHandle: [String, Array],
  ariaRequired: {
    type: Boolean,
    default: undefined
  },
  ariaValueTextFormatterForHandle: [Function, Array]
});
export const sliderSingleProps = () => _extends(_extends({}, sliderBaseProps()), {
  range: Boolean,
  value: Number,
  defaultValue: Number,
  onChange: Function,
  'onUpdate:value': Function,
  /** @deprecated Please use `onChangeComplete` instead */
  onAfterChange: Function,
  onChangeComplete: Function,
  /** @deprecated Please use `styles.handle` instead */
  handleStyle: Object,
  /** @deprecated Please use `styles.track` instead */
  trackStyle: Object,
  /** @deprecated Please use `styles.rail` instead */
  railStyle: Object
});
export const sliderRangeProps = () => _extends(_extends({}, sliderBaseProps()), {
  range: [Boolean, Object],
  value: Array,
  defaultValue: Array,
  onChange: Function,
  'onUpdate:value': Function,
  /** @deprecated Please use `onChangeComplete` instead */
  onAfterChange: Function,
  onChangeComplete: Function,
  /** @deprecated Please use `styles.handle` instead */
  handleStyle: Array,
  /** @deprecated Please use `styles.track` instead */
  trackStyle: Array,
  /** @deprecated Please use `styles.rail` instead */
  railStyle: Object
});
const finalSliderProps = () => _extends(_extends({}, sliderBaseProps()), {
  range: {
    type: [Boolean, Object],
    default: false
  },
  value: [Number, Array],
  defaultValue: [Number, Array],
  onChange: Function,
  'onUpdate:value': Function,
  onAfterChange: Function,
  onChangeComplete: Function,
  handleStyle: [Object, Array],
  trackStyle: [Object, Array]
});
function getTipFormatter(tipFormatter, legacyTipFormatter) {
  if (tipFormatter || tipFormatter === null) {
    return tipFormatter;
  }
  if (legacyTipFormatter || legacyTipFormatter === null) {
    return legacyTipFormatter;
  }
  return val => typeof val === 'number' ? val.toString() : '';
}
const Slider = defineComponent({
  name: 'ASlider',
  props: _extends({}, finalSliderProps()),
  setup(props, {
    expose
  }) {
    const {
      prefixCls,
      direction,
      getPopupContainer,
      configProvider
    } = useConfigInject('slider', props);
    const disabled = useInjectDisabled();
    const sliderRef = ref();
    expose({
      focus: () => {
        var _a;
        return (_a = sliderRef.value) === null || _a === void 0 ? void 0 : _a.focus();
      },
      blur: () => {
        var _a;
        return (_a = sliderRef.value) === null || _a === void 0 ? void 0 : _a.blur();
      }
    });
    const mergedDisabled = computed(() => {
      var _a;
      return (_a = props.disabled) !== null && _a !== void 0 ? _a : disabled.value;
    });
    // ============================= Context ==============================
    const {
      handleRender: contextHandleRender,
      direction: internalContextDirection
    } = useInjectSliderInternal();
    const mergedDirection = computed(() => (internalContextDirection === null || internalContextDirection === void 0 ? void 0 : internalContextDirection.value) || direction.value);
    const isRTL = computed(() => mergedDirection.value === 'rtl');
    // =============================== Open ===============================
    const [hoverOpen, setHoverOpen] = useRafLock();
    const [focusOpen, setFocusOpen] = useRafLock();
    const tooltipProps = computed(() => _extends({}, props.tooltip));
    const lockOpen = computed(() => {
      var _a;
      return (_a = tooltipProps.value.open) !== null && _a !== void 0 ? _a : props.tooltipVisible;
    });
    const activeOpen = computed(() => (hoverOpen.value || focusOpen.value) && lockOpen.value !== false);
    const mergedTipFormatter = getTipFormatter(tooltipProps.value.formatter, props.tipFormatter);
    // ============================= Change ==============================
    const [dragging, setDragging] = useRafLock();
    const onInternalChangeComplete = nextValues => {
      var _a;
      (_a = props.onChangeComplete) === null || _a === void 0 ? void 0 : _a.call(props, nextValues);
      setDragging(false);
    };
    // ============================ Placement ============================
    const getTooltipPlacement = (placement, vert) => {
      if (placement) {
        return placement;
      }
      if (!vert) {
        return 'top';
      }
      return isRTL.value ? 'left' : 'right';
    };
    // ============================== Style ===============================
    const [wrapSSR, hashId] = useStyle(prefixCls);
    const rootClassNames = computed(() => {
      var _a;
      return classnames(props.className, (_a = props.classNames) === null || _a === void 0 ? void 0 : _a.root, props.rootClassName, {
        [`${prefixCls.value}-rtl`]: isRTL.value,
        [`${prefixCls.value}-lock`]: dragging.value
      }, hashId.value);
    });
    const reverse = computed(() => isRTL.value && props.vertical ? !props.reverse : props.reverse);
    // ============================== Handle ==============================
    onMounted(() => {
      const onMouseUp = () => {
        raf(() => {
          setFocusOpen(false);
        }, 1);
      };
      document.addEventListener('mouseup', onMouseUp);
      onBeforeUnmount(() => {
        document.removeEventListener('mouseup', onMouseUp);
      });
    });
    const useActiveTooltipHandle = computed(() => props.range && !lockOpen.value);
    const handleRender = contextHandleRender || ((node, info) => {
      var _a, _b;
      const {
        index
      } = info;
      const nodeProps = node.props;
      function proxyEvent(eventName, event, triggerRestPropsEvent) {
        var _a, _b, _c, _d;
        if (triggerRestPropsEvent) {
          (_b = (_a = props)[eventName]) === null || _b === void 0 ? void 0 : _b.call(_a, event);
        }
        (_d = (_c = nodeProps)[eventName]) === null || _d === void 0 ? void 0 : _d.call(_c, event);
      }
      const passedProps = _extends(_extends({}, nodeProps), {
        onMouseenter: e => {
          setHoverOpen(true);
          proxyEvent('onMouseenter', e);
        },
        onMouseleave: e => {
          setHoverOpen(false);
          proxyEvent('onMouseleave', e);
        },
        onMousedown: e => {
          setFocusOpen(true);
          setDragging(true);
          proxyEvent('onMousedown', e);
        },
        onFocus: e => {
          var _a;
          setFocusOpen(true);
          (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
          proxyEvent('onFocus', e, true);
        },
        onBlur: e => {
          var _a;
          setFocusOpen(false);
          (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
          proxyEvent('onBlur', e, true);
        }
      });
      const cloneNode = cloneVNode(node, _extends({}, passedProps));
      const open = (!!lockOpen.value || activeOpen.value) && mergedTipFormatter !== null;
      if (!useActiveTooltipHandle.value) {
        return _createVNode(SliderTooltip, _objectSpread(_objectSpread({}, tooltipProps.value), {}, {
          "prefixCls": configProvider.getPrefixCls('tooltip', (_a = tooltipProps.value.prefixCls) !== null && _a !== void 0 ? _a : props.tooltipPrefixCls),
          "title": mergedTipFormatter ? mergedTipFormatter(info.value) : '',
          "value": info.value,
          "open": open,
          "placement": getTooltipPlacement((_b = tooltipProps.value.placement) !== null && _b !== void 0 ? _b : props.tooltipPlacement, props.vertical),
          "key": index,
          "overlayClassName": `${prefixCls.value}-tooltip`,
          "getPopupContainer": tooltipProps.value.getPopupContainer || props.getTooltipPopupContainer || getPopupContainer.value
        }), {
          default: () => [cloneNode]
        });
      }
      return cloneNode;
    });
    // ========================== Active Handle ===========================
    const activeHandleRender = useActiveTooltipHandle.value ? (handle, info) => {
      var _a, _b;
      const cloneNode = cloneVNode(handle, {
        style: _extends(_extends({}, handle.props.style), {
          visibility: 'hidden'
        })
      }, true);
      return _createVNode(SliderTooltip, _objectSpread(_objectSpread({}, tooltipProps.value), {}, {
        "prefixCls": configProvider.getPrefixCls('tooltip', (_a = tooltipProps.value.prefixCls) !== null && _a !== void 0 ? _a : props.tooltipPrefixCls),
        "title": mergedTipFormatter ? mergedTipFormatter(info.value) : '',
        "open": mergedTipFormatter !== null && activeOpen.value,
        "placement": getTooltipPlacement((_b = tooltipProps.value.placement) !== null && _b !== void 0 ? _b : props.tooltipPlacement, props.vertical),
        "key": "tooltip",
        "class": `${prefixCls.value}-tooltip`,
        "getPopupContainer": tooltipProps.value.getPopupContainer || props.getTooltipPopupContainer || getPopupContainer.value,
        "draggingDelete": info.draggingDelete
      }), {
        default: () => [cloneNode]
      });
    } : undefined;
    // ============================== Render ==============================
    return () => {
      var _a, _b, _c, _d, _e;
      const rootStyle = _extends(_extends({}, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root), props.style);
      const mergedTracksClassNames = (_b = props.classNames) === null || _b === void 0 ? void 0 : _b.tracks;
      return wrapSSR(_createVNode(VcSlider, _objectSpread(_objectSpread({}, props), {}, {
        "classNames": {
          handle: (_c = props.classNames) === null || _c === void 0 ? void 0 : _c.handle,
          rail: (_d = props.classNames) === null || _d === void 0 ? void 0 : _d.rail,
          track: (_e = props.classNames) === null || _e === void 0 ? void 0 : _e.track,
          tracks: mergedTracksClassNames
        },
        "styles": props.styles,
        "reverse": reverse.value,
        "step": props.step,
        "range": props.range,
        "className": rootClassNames.value,
        "style": rootStyle,
        "disabled": mergedDisabled.value,
        "ref": sliderRef,
        "prefixCls": prefixCls.value,
        "handleRender": handleRender,
        "activeHandleRender": activeHandleRender,
        "onChangeComplete": onInternalChangeComplete
      }), null));
    };
  }
});
export default withInstall(Slider);