<template>
  <view :class="stepperClass" :style="stepperStyle">
    <view
      :class="
        classNames(
          bem.e('button'),
          bem.em('button', 'disabled', isDisabled || isMin),
          bem.em('button', 'readonly', isReadonly),
          bem.em('button', 'decrease'),
        )
      "
      @click="onButtonClick(-1, isMin)"
      @touchstart="onTouchStart(-1)"
      @touchend="onTouchEnd"
      @touchcancel="onTouchEnd"
      @mousedown="onMouseDown(-1)"
    >
      <sar-icon name="minus" />
    </view>
    <input
      :class="bem.e('input')"
      :type="inputType"
      :placeholder="placeholder"
      :placeholder-class="bem.e('placeholder')"
      :value="inputValue"
      :disabled="isDisabled || isReadonly"
      :stype="inputStyle"
      @input="onInput"
      @blur="onBlur"
      @focus="onFocus"
    />
    <view
      :class="
        classNames(
          bem.e('button'),
          bem.em('button', 'disabled', isDisabled || isMax),
          bem.em('button', 'readonly', isReadonly),
          bem.em('button', 'increase'),
        )
      "
      @click="onButtonClick(1, isMax)"
      @touchstart="onTouchStart(1)"
      @touchend="onTouchEnd"
      @touchcancel="onTouchEnd"
      @mousedown="onMouseDown(1)"
    >
      <sar-icon name="plus" />
    </view>
  </view>
</template>

<script lang="ts">
import { defineComponent as _defineComponent } from "vue";
import { computed, ref, watch } from "vue";
import {
  classNames,
  stringifyStyle,
  createBem,
  isNullish,
  minmax
} from "../utils";
import SarIcon from "../icon/icon.vue";
import { useFormContext, useFormItemContext } from "../form/common";
import { stepperProps } from "./common";
const __default__ = {
  options: {
    virtualHost: true,
    styleIsolation: "shared"
  }
};
export default /* @__PURE__ */ _defineComponent({
  ...__default__,
  __name: "stepper",
  props: stepperProps,
  emits: ["update:model-value", "focus", "blur"],
  setup(__props, { expose: __expose, emit: __emit }) {
    __expose();
    const props = __props;
    const emit = __emit;
    const bem = createBem("stepper");
    const formContext = useFormContext();
    const formItemContext = useFormItemContext();
    const isDisabled = computed(() => {
      return formContext?.disabled ?? props.disabled;
    });
    const isReadonly = computed(() => {
      return formContext?.readonly ?? props.readonly;
    });
    const innerValue = ref(props.modelValue);
    const inputValue = ref(props.modelValue);
    watch(
      () => props.modelValue,
      () => {
        innerValue.value = props.modelValue;
        inputValue.value = props.modelValue;
        if (props.validateEvent) {
          formItemContext?.onChange();
        }
      }
    );
    const setInnerValue = (value) => {
      innerValue.value = value;
      emit("update:model-value", value);
    };
    const setValueEnsureSafe = (value) => {
      setInnerValue(value);
      inputValue.value = value;
    };
    const normalizedValue = (value) => {
      value = minmax(value, props.min, props.max);
      if (props.precision !== void 0) {
        value = +value.toFixed(props.precision);
      }
      return value;
    };
    const getValueOnClear = () => {
      return props.valueOnClear === "min" ? props.min : props.valueOnClear === "max" ? props.max : props.valueOnClear;
    };
    const onInput = (event) => {
      const value = event.detail.value;
      inputValue.value = value;
      if (value === "") {
        setInnerValue(getValueOnClear());
      }
    };
    const onBlur = (event) => {
      if (inputValue.value !== "") {
        const nextValue = Number(inputValue.value);
        if (isNaN(nextValue)) {
          inputValue.value = "";
          setInnerValue(getValueOnClear());
        } else {
          setValueEnsureSafe(normalizedValue(nextValue));
        }
      }
      emit("blur", event);
    };
    const onFocus = (event) => {
      emit("focus", event);
    };
    const isMin = computed(() => {
      return !isNullish(innerValue.value) && Number(innerValue.value) <= props.min;
    });
    const isMax = computed(() => {
      return !isNullish(innerValue.value) && Number(innerValue.value) >= props.max;
    });
    const setByStep = (delta) => {
      setValueEnsureSafe(
        normalizedValue((Number(innerValue.value) || 0) + props.step * delta)
      );
    };
    const onButtonClick = (delta, arrived) => {
      if (!isDisabled.value && !isReadonly.value && !arrived) {
        setByStep(delta);
      }
    };
    let pressTimer;
    let isPressing = false;
    const onLongPress = (delta) => {
      if (isPressing) {
        setByStep(delta);
        setTimeout(() => {
          onLongPress(delta);
        }, props.interval);
      }
    };
    const onTouchStart = (delta) => {
      if (!props.press || isDisabled.value || isReadonly.value || delta === -1 && isMin.value || delta === 1 && isMax.value) {
        return;
      }
      clearTimeout(pressTimer);
      isPressing = false;
      pressTimer = setTimeout(() => {
        isPressing = true;
        onLongPress(delta);
      }, props.pressTime);
    };
    const onTouchEnd = () => {
      clearTimeout(pressTimer);
      isPressing = false;
    };
    const onMouseDown = (delta) => {
      onTouchStart(delta);
      const upHandler = () => {
        onTouchEnd();
        document.removeEventListener("mouseup", upHandler);
      };
      document.addEventListener("mouseup", upHandler);
    };
    const stepperClass = computed(() => {
      return classNames(
        bem.b(),
        bem.m("disabled", isDisabled.value),
        bem.m("readonly", isReadonly.value),
        props.rootClass
      );
    });
    const stepperStyle = computed(() => {
      return stringifyStyle(props.rootStyle);
    });
    const __returned__ = { props, emit, bem, formContext, formItemContext, isDisabled, isReadonly, innerValue, inputValue, setInnerValue, setValueEnsureSafe, normalizedValue, getValueOnClear, onInput, onBlur, onFocus, isMin, isMax, setByStep, onButtonClick, get pressTimer() {
      return pressTimer;
    }, set pressTimer(v) {
      pressTimer = v;
    }, get isPressing() {
      return isPressing;
    }, set isPressing(v) {
      isPressing = v;
    }, onLongPress, onTouchStart, onTouchEnd, onMouseDown, stepperClass, stepperStyle, get classNames() {
      return classNames;
    }, SarIcon };
    return __returned__;
  }
});
</script>

<style lang="scss">
@use './index.scss';
</style>