import { defineComponent, ref, computed, watch, provide, createElementBlock, openBlock, normalizeClass, unref, createElementVNode, withDirectives, createCommentVNode, renderSlot, createVNode, normalizeStyle, nextTick } from "vue";
import { tabInjectKey } from "./provide.mjs";
import { IconChevronLeft, IconChevronRight, IconAdd } from "../_utils/icons.mjs";
import { tabProps } from "./types.mjs";
import { useScreen } from "../hooks/use-screen.mjs";
import { vOnResize } from "../directives/on-resize.mjs";
import { debounceRAF } from "../_utils/helper.mjs";
import { defaultSize } from "../_utils/global.mjs";
const _hoisted_1 = {
  key: 0,
  class: "o-tab-head-prefix"
};
const _hoisted_2 = { class: "o-tab-navs" };
const _hoisted_3 = {
  key: 1,
  class: "o-tab-head-suffix"
};
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "OTab",
  props: tabProps,
  emits: ["update:modelValue", "change", "delete", "add"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emits = __emit;
    const { isPhonePad } = useScreen();
    const activeKey = ref(props.modelValue);
    const anchorStyle = ref({});
    const navWrapRef = ref(null);
    const navsRef = ref(null);
    const bodyRef = ref(null);
    const valueSet = [];
    let activeNavEl = null;
    const isScroll = ref(false);
    const prevDisabled = ref(true);
    const nextDisabled = ref(true);
    const showArrow = computed(() => {
      return !isPhonePad.value && isScroll.value;
    });
    const scrollActiveNavIntoView = () => {
      var _a;
      if (isScroll.value && activeNavEl && navWrapRef.value) {
        const { offsetLeft } = activeNavEl;
        const { scrollLeft, clientWidth } = navWrapRef.value;
        const center = scrollLeft + clientWidth / 2;
        if (offsetLeft > center || offsetLeft < center) {
          (_a = navWrapRef.value) == null ? void 0 : _a.scrollTo({
            left: offsetLeft - clientWidth / 2,
            behavior: "smooth"
          });
        }
      }
    };
    const onWrapScroll = debounceRAF(() => {
      if (navWrapRef.value) {
        const { scrollLeft, scrollWidth, clientWidth } = navWrapRef.value;
        prevDisabled.value = scrollLeft === 0;
        nextDisabled.value = scrollLeft + 1 >= scrollWidth - clientWidth;
      }
    });
    const updateNavScroll = () => {
      if (navWrapRef.value && navsRef.value) {
        const { clientWidth: wrapWidth } = navWrapRef.value;
        const { clientWidth: width } = navsRef.value;
        isScroll.value = wrapWidth < width;
        if (isScroll.value) {
          nextTick(() => {
            onWrapScroll();
            scrollActiveNavIntoView();
          });
        }
      }
    };
    watch(
      () => props.modelValue,
      (v) => {
        activeKey.value = v;
      }
    );
    const updateAnchor = () => {
      if (!activeNavEl) {
        return;
      }
      const { clientWidth, offsetLeft } = activeNavEl;
      anchorStyle.value = {
        transform: `translate3d(${offsetLeft}px, 0px, 0px)`,
        width: `${clientWidth}px`
      };
    };
    watch(() => isScroll.value, updateAnchor);
    const updateValue = (value, navEl) => {
      emits("update:modelValue", value);
      activeNavEl = navEl;
      if (activeKey.value !== value) {
        emits("change", value, activeKey.value);
        activeKey.value = value;
      }
      if (navEl) {
        activeNavEl = navEl;
        updateAnchor();
        scrollActiveNavIntoView();
      }
    };
    const isAdding = ref(false);
    const initValue = (value, navEl) => {
      if (!valueSet.includes(value)) {
        valueSet.push(value);
      }
      if (activeKey.value === void 0 || isAdding.value) {
        updateValue(value, navEl);
        isAdding.value = false;
      }
      if (activeKey.value === value && navEl) {
        activeNavEl = navEl;
        updateAnchor();
      }
    };
    const onDeletePane = (value) => {
      emits("delete", value);
      const idx = valueSet.indexOf(value);
      if (activeKey.value === value) {
        activeKey.value = valueSet[idx > 0 ? idx - 1 : 0];
        emits("change", activeKey.value, value);
      }
      valueSet.splice(idx, 1);
    };
    const onAddNav = (e) => {
      emits("add", e);
      if (!props.addInactive) {
        isAdding.value = true;
      }
    };
    provide(tabInjectKey, {
      lazy: props.lazy,
      navsRef,
      bodyRef,
      activeValue: activeKey,
      updateValue,
      onDeletePane,
      initValue
    });
    const onHeadResize = debounceRAF(() => {
      updateAnchor();
      updateNavScroll();
      scrollActiveNavIntoView();
    });
    const navScroll = (to) => {
      if (!navWrapRef.value) {
        return;
      }
      const { clientWidth } = navWrapRef.value;
      const i = to === "prev" ? -1 : to === "next" ? 1 : 0;
      navWrapRef.value.scrollBy({ left: i * clientWidth, behavior: "smooth" });
    };
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock(
        "div",
        {
          class: normalizeClass(["o-tab", [`o-tab-${props.variant}`, `o-tab-${props.size || unref(defaultSize)}`]])
        },
        [
          createElementVNode(
            "div",
            {
              class: normalizeClass(["o-tab-head", [
                {
                  "with-act": _ctx.$slots.suffix || _ctx.$slots.prefix,
                  "show-line": props.line
                },
                props.headerClass
              ]])
            },
            [
              _ctx.$slots.prefix ? withDirectives((openBlock(), createElementBlock("div", _hoisted_1, [
                renderSlot(_ctx.$slots, "prefix")
              ])), [
                [unref(vOnResize), unref(onHeadResize)]
              ]) : createCommentVNode("v-if", true),
              createElementVNode("div", _hoisted_2, [
                createElementVNode(
                  "div",
                  {
                    class: normalizeClass([{ "o-tab-navs-scrollable": isScroll.value }, "o-tab-navs-container"])
                  },
                  [
                    showArrow.value ? (openBlock(), createElementBlock(
                      "div",
                      {
                        key: 0,
                        class: normalizeClass(["o-tab-nav-btn prev", { "o-tab-nav-btn-disabled": prevDisabled.value }]),
                        onClick: _cache[0] || (_cache[0] = ($event) => navScroll("prev"))
                      },
                      [
                        createVNode(unref(IconChevronLeft))
                      ],
                      2
                      /* CLASS */
                    )) : createCommentVNode("v-if", true),
                    createElementVNode(
                      "div",
                      {
                        ref_key: "navWrapRef",
                        ref: navWrapRef,
                        class: "o-tab-navs-wrap o-hide-scrollbar",
                        onScrollPassive: _cache[1] || (_cache[1] = //@ts-ignore
                        (...args) => unref(onWrapScroll) && unref(onWrapScroll)(...args))
                      },
                      [
                        withDirectives(createElementVNode(
                          "div",
                          {
                            class: "o-tab-nav-list",
                            ref_key: "navsRef",
                            ref: navsRef
                          },
                          null,
                          512
                          /* NEED_PATCH */
                        ), [
                          [unref(vOnResize), unref(onHeadResize)]
                        ]),
                        props.variant === "text" ? (openBlock(), createElementBlock(
                          "div",
                          {
                            key: 0,
                            class: "o-tab-nav-anchor",
                            style: normalizeStyle(anchorStyle.value)
                          },
                          [
                            renderSlot(_ctx.$slots, "anchor", {}, () => [
                              _cache[3] || (_cache[3] = createElementVNode(
                                "div",
                                { class: "o-tab-nav-anchor-line" },
                                null,
                                -1
                                /* HOISTED */
                              ))
                            ])
                          ],
                          4
                          /* STYLE */
                        )) : createCommentVNode("v-if", true)
                      ],
                      544
                      /* NEED_HYDRATION, NEED_PATCH */
                    ),
                    showArrow.value ? (openBlock(), createElementBlock(
                      "div",
                      {
                        key: 1,
                        class: normalizeClass(["o-tab-nav-btn next", { "o-tab-nav-btn-disabled": nextDisabled.value }]),
                        onClick: _cache[2] || (_cache[2] = ($event) => navScroll("next"))
                      },
                      [
                        createVNode(unref(IconChevronRight))
                      ],
                      2
                      /* CLASS */
                    )) : createCommentVNode("v-if", true)
                  ],
                  2
                  /* CLASS */
                ),
                props.addable ? (openBlock(), createElementBlock("div", {
                  key: 0,
                  class: "o-tab-nav-add",
                  onClick: onAddNav
                }, [
                  createVNode(unref(IconAdd))
                ])) : createCommentVNode("v-if", true)
              ]),
              _ctx.$slots.suffix ? withDirectives((openBlock(), createElementBlock("div", _hoisted_3, [
                renderSlot(_ctx.$slots, "suffix")
              ])), [
                [unref(vOnResize), unref(onHeadResize)]
              ]) : createCommentVNode("v-if", true)
            ],
            2
            /* CLASS */
          ),
          createElementVNode(
            "div",
            {
              ref_key: "bodyRef",
              ref: bodyRef,
              class: "o-tab-body"
            },
            [
              renderSlot(_ctx.$slots, "default")
            ],
            512
            /* NEED_PATCH */
          )
        ],
        2
        /* CLASS */
      );
    };
  }
});
export {
  _sfc_main as default
};
