"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const event = require("../../../../constants/event.js");
const types = require("../../../../utils/types.js");
const raf = require("../../../../utils/raf.js");
const style = require("../../../../utils/dom/style.js");
const index = require("../../../../hooks/use-namespace/index.js");
const index$2 = require("../../../icon/index.js");
const index$1 = require("../../../scrollbar/index.js");
const constants = require("../constants.js");
const utils = require("../utils.js");
const useTimePicker = require("../composables/use-time-picker.js");
const index$4 = require("../../../../directives/repeat-click/index.js");
const basicTimeSpinner = require("../props/basic-time-spinner.js");
const index$3 = require("../../../../../../@element-plus/icons-vue/dist/index.js");
const Vue = require("vue");
const debounce = require("../../../../../../lodash-es/debounce.js");
const _hoisted_1 = ["onClick"];
const _hoisted_2 = ["onMouseenter"];
var basic_time_spinner_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ Vue.defineComponent({
  __name: "basic-time-spinner",
  props: basicTimeSpinner.basicTimeSpinnerProps,
  emits: [
    event.CHANGE_EVENT,
    "select-range",
    "set-option"
  ],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const { isRange, format, saveOnBlur } = Vue.inject(constants.PICKER_BASE_INJECTION_KEY).props;
    const emit = __emit;
    const ns = index.useNamespace("time");
    const { getHoursList, getMinutesList, getSecondsList } = useTimePicker.getTimeLists(props.disabledHours, props.disabledMinutes, props.disabledSeconds);
    let isScrolling = false;
    const ignoreScroll = {
      hours: false,
      minutes: false,
      seconds: false
    };
    const currentScrollbar = Vue.ref();
    const listRefsMap = {
      hours: Vue.ref(),
      minutes: Vue.ref(),
      seconds: Vue.ref()
    };
    const spinnerItems = Vue.computed(() => {
      return props.showSeconds ? constants.timeUnits : constants.timeUnits.slice(0, 2);
    });
    const timePartials = Vue.computed(() => {
      const { spinnerDate } = props;
      return {
        hours: spinnerDate.hour(),
        minutes: spinnerDate.minute(),
        seconds: spinnerDate.second()
      };
    });
    const timeList = Vue.computed(() => {
      const { hours, minutes } = Vue.unref(timePartials);
      const { role, spinnerDate } = props;
      const compare = !isRange ? spinnerDate : void 0;
      return {
        hours: getHoursList(role, compare),
        minutes: getMinutesList(hours, role, compare),
        seconds: getSecondsList(hours, minutes, role, compare)
      };
    });
    const arrowControlTimeList = Vue.computed(() => {
      const { hours, minutes, seconds } = Vue.unref(timePartials);
      return {
        hours: utils.buildTimeList(hours, 23),
        minutes: utils.buildTimeList(minutes, 59),
        seconds: utils.buildTimeList(seconds, 59)
      };
    });
    const debouncedResetScroll = debounce.default((type) => {
      isScrolling = false;
      adjustCurrentSpinner(type);
    }, 200);
    const getAmPmFlag = (hour) => {
      if (!!!props.amPmMode) return "";
      const isCapital = props.amPmMode === "A";
      let content = hour < 12 ? " am" : " pm";
      if (isCapital) content = content.toUpperCase();
      return content;
    };
    const emitSelectRange = (type) => {
      let range = [0, 0];
      const actualFormat = format || constants.DEFAULT_FORMATS_TIME;
      const hourIndex = actualFormat.indexOf("HH");
      const minuteIndex = actualFormat.indexOf("mm");
      const secondIndex = actualFormat.indexOf("ss");
      switch (type) {
        case "hours":
          if (hourIndex !== -1) range = [hourIndex, hourIndex + 2];
          break;
        case "minutes":
          if (minuteIndex !== -1) range = [minuteIndex, minuteIndex + 2];
          break;
        case "seconds":
          if (secondIndex !== -1) range = [secondIndex, secondIndex + 2];
          break;
      }
      const [left, right] = range;
      emit("select-range", left, right);
      currentScrollbar.value = type;
    };
    const adjustCurrentSpinner = (type) => {
      adjustSpinner(type, Vue.unref(timePartials)[type]);
    };
    const adjustSpinners = () => {
      adjustCurrentSpinner("hours");
      adjustCurrentSpinner("minutes");
      adjustCurrentSpinner("seconds");
    };
    const getScrollbarElement = (el) => el.querySelector(`.${ns.namespace.value}-scrollbar__wrap`);
    const adjustSpinner = (type, value) => {
      if (props.arrowControl) return;
      const scrollbar = Vue.unref(listRefsMap[type]);
      if (scrollbar && scrollbar.$el) {
        if (!saveOnBlur) {
          ignoreScroll[type] = true;
          raf.rAF(() => {
            ignoreScroll[type] = false;
          });
        }
        getScrollbarElement(scrollbar.$el).scrollTop = Math.max(0, value * typeItemHeight(type));
      }
    };
    const typeItemHeight = (type) => {
      var _a;
      const listItem = (_a = Vue.unref(listRefsMap[type])) == null ? void 0 : _a.$el.querySelector("li");
      if (listItem) return Number.parseFloat(style.getStyle(listItem, "height")) || 0;
      return 0;
    };
    const onIncrement = () => {
      scrollDown(1);
    };
    const onDecrement = () => {
      scrollDown(-1);
    };
    const scrollDown = (step) => {
      if (!currentScrollbar.value) emitSelectRange("hours");
      const label = currentScrollbar.value;
      const now = Vue.unref(timePartials)[label];
      const next = findNextUnDisabled(label, now, step, currentScrollbar.value === "hours" ? 24 : 60);
      modifyDateField(label, next);
      adjustSpinner(label, next);
      Vue.nextTick(() => emitSelectRange(label));
    };
    const findNextUnDisabled = (type, now, step, total) => {
      let next = (now + step + total) % total;
      const list = Vue.unref(timeList)[type];
      while (list[next] && next !== now) next = (next + step + total) % total;
      return next;
    };
    const modifyDateField = (type, value) => {
      if (Vue.unref(timeList)[type][value]) return;
      const { hours, minutes, seconds } = Vue.unref(timePartials);
      let changeTo;
      switch (type) {
        case "hours":
          changeTo = props.spinnerDate.hour(value).minute(minutes).second(seconds);
          break;
        case "minutes":
          changeTo = props.spinnerDate.hour(hours).minute(value).second(seconds);
          break;
        case "seconds":
          changeTo = props.spinnerDate.hour(hours).minute(minutes).second(value);
          break;
      }
      emit(event.CHANGE_EVENT, changeTo);
    };
    const handleClick = (type, { value, disabled }) => {
      if (!disabled) {
        modifyDateField(type, value);
        emitSelectRange(type);
        adjustSpinner(type, value);
      }
    };
    const handleScroll = (type) => {
      if (!saveOnBlur && ignoreScroll[type]) return;
      const scrollbar = Vue.unref(listRefsMap[type]);
      if (!scrollbar) return;
      isScrolling = true;
      debouncedResetScroll(type);
      modifyDateField(type, Math.min(Math.round((getScrollbarElement(scrollbar.$el).scrollTop - (scrollBarHeight(type) * 0.5 - 10) / typeItemHeight(type) + 3) / typeItemHeight(type)), type === "hours" ? 23 : 59));
    };
    const scrollBarHeight = (type) => {
      return Vue.unref(listRefsMap[type]).$el.offsetHeight;
    };
    const bindScrollEvent = () => {
      const bindFunction = (type) => {
        const scrollbar = Vue.unref(listRefsMap[type]);
        if (scrollbar && scrollbar.$el) getScrollbarElement(scrollbar.$el).onscroll = () => {
          handleScroll(type);
        };
      };
      bindFunction("hours");
      bindFunction("minutes");
      bindFunction("seconds");
    };
    Vue.onMounted(() => {
      Vue.nextTick(() => {
        !props.arrowControl && bindScrollEvent();
        adjustSpinners();
        if (props.role === "start") emitSelectRange("hours");
      });
    });
    const setRef = (scrollbar, type) => {
      listRefsMap[type].value = scrollbar ?? void 0;
    };
    emit("set-option", [`${props.role}_scrollDown`, scrollDown]);
    emit("set-option", [`${props.role}_emitSelectRange`, emitSelectRange]);
    Vue.watch(() => props.spinnerDate, () => {
      if (isScrolling) return;
      adjustSpinners();
    });
    return (_ctx, _cache) => {
      return Vue.openBlock(), Vue.createElementBlock("div", { class: Vue.normalizeClass([Vue.unref(ns).b("spinner"), { "has-seconds": _ctx.showSeconds }]) }, [!_ctx.arrowControl ? (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, { key: 0 }, Vue.renderList(spinnerItems.value, (item) => {
        return Vue.openBlock(), Vue.createBlock(Vue.unref(index$1.ElScrollbar), {
          key: item,
          ref_for: true,
          ref: (scrollbar) => setRef(scrollbar, item),
          class: Vue.normalizeClass(Vue.unref(ns).be("spinner", "wrapper")),
          "wrap-style": "max-height: inherit;",
          "view-class": Vue.unref(ns).be("spinner", "list"),
          noresize: "",
          tag: "ul",
          onMouseenter: ($event) => emitSelectRange(item),
          onMousemove: ($event) => adjustCurrentSpinner(item)
        }, {
          default: Vue.withCtx(() => [(Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(timeList.value[item], (disabled, key) => {
            return Vue.openBlock(), Vue.createElementBlock("li", {
              key,
              class: Vue.normalizeClass([
                Vue.unref(ns).be("spinner", "item"),
                Vue.unref(ns).is("active", key === timePartials.value[item]),
                Vue.unref(ns).is("disabled", disabled)
              ]),
              onClick: ($event) => handleClick(item, {
                value: key,
                disabled
              })
            }, [item === "hours" ? (Vue.openBlock(), Vue.createElementBlock(Vue.Fragment, { key: 0 }, [Vue.createTextVNode(Vue.toDisplayString(("0" + (_ctx.amPmMode ? key % 12 || 12 : key)).slice(-2)) + Vue.toDisplayString(getAmPmFlag(key)), 1)], 64)) : (Vue.openBlock(), Vue.createElementBlock(Vue.Fragment, { key: 1 }, [Vue.createTextVNode(Vue.toDisplayString(("0" + key).slice(-2)), 1)], 64))], 10, _hoisted_1);
          }), 128))]),
          _: 2
        }, 1032, [
          "class",
          "view-class",
          "onMouseenter",
          "onMousemove"
        ]);
      }), 128)) : Vue.createCommentVNode("v-if", true), _ctx.arrowControl ? (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, { key: 1 }, Vue.renderList(spinnerItems.value, (item) => {
        return Vue.openBlock(), Vue.createElementBlock("div", {
          key: item,
          class: Vue.normalizeClass([Vue.unref(ns).be("spinner", "wrapper"), Vue.unref(ns).is("arrow")]),
          onMouseenter: ($event) => emitSelectRange(item)
        }, [
          Vue.withDirectives((Vue.openBlock(), Vue.createBlock(Vue.unref(index$2.ElIcon), { class: Vue.normalizeClass(["arrow-up", Vue.unref(ns).be("spinner", "arrow")]) }, {
            default: Vue.withCtx(() => [Vue.createVNode(Vue.unref(index$3.ArrowUp))]),
            _: 1
          }, 8, ["class"])), [[Vue.unref(index$4.vRepeatClick), onDecrement]]),
          Vue.withDirectives((Vue.openBlock(), Vue.createBlock(Vue.unref(index$2.ElIcon), { class: Vue.normalizeClass(["arrow-down", Vue.unref(ns).be("spinner", "arrow")]) }, {
            default: Vue.withCtx(() => [Vue.createVNode(Vue.unref(index$3.ArrowDown))]),
            _: 1
          }, 8, ["class"])), [[Vue.unref(index$4.vRepeatClick), onIncrement]]),
          Vue.createElementVNode("ul", { class: Vue.normalizeClass(Vue.unref(ns).be("spinner", "list")) }, [(Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(arrowControlTimeList.value[item], (time, key) => {
            return Vue.openBlock(), Vue.createElementBlock("li", {
              key,
              class: Vue.normalizeClass([
                Vue.unref(ns).be("spinner", "item"),
                Vue.unref(ns).is("active", time === timePartials.value[item]),
                Vue.unref(ns).is("disabled", timeList.value[item][time])
              ])
            }, [Vue.unref(types.isNumber)(time) ? (Vue.openBlock(), Vue.createElementBlock(Vue.Fragment, { key: 0 }, [item === "hours" ? (Vue.openBlock(), Vue.createElementBlock(Vue.Fragment, { key: 0 }, [Vue.createTextVNode(Vue.toDisplayString(("0" + (_ctx.amPmMode ? time % 12 || 12 : time)).slice(-2)) + Vue.toDisplayString(getAmPmFlag(time)), 1)], 64)) : (Vue.openBlock(), Vue.createElementBlock(Vue.Fragment, { key: 1 }, [Vue.createTextVNode(Vue.toDisplayString(("0" + time).slice(-2)), 1)], 64))], 64)) : Vue.createCommentVNode("v-if", true)], 2);
          }), 128))], 2)
        ], 42, _hoisted_2);
      }), 128)) : Vue.createCommentVNode("v-if", true)], 2);
    };
  }
});
exports.default = basic_time_spinner_vue_vue_type_script_setup_true_lang_default;
