<template>
  <view :class="tabsClass" :style="tabsStyle">
    <scroll-view
      :id="scrollId"
      :class="bem.e('scroll')"
      :scroll-x="scrollable"
      :scroll-left="scrollLeft"
      :scroll-with-animation="scrollInitialized"
    >
      <view :class="bem.e('container')">
        <view :id="wrapperId" :class="bem.e('wrapper')">
          <slot>
            <sar-tab
              v-for="(item, index) in list"
              :key="index"
              :title="item.title"
              :name="item.name ?? index"
              :disabled="item.disabled"
              :root-style="item.rootStyle"
              :root-class="item.rootClass"
            />
          </slot>
          <view
            v-if="type === 'line'"
            :class="bem.e('line')"
            :style="lineStyle"
          />
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script lang="ts">
import { defineComponent as _defineComponent } from "vue";
import {
  computed,
  ref,
  provide,
  watch,
  getCurrentInstance,
  reactive
} from "vue";
import {
  classNames,
  stringifyStyle,
  createBem,
  uniqid,
  getBoundingClientRect
} from "../utils";
import { tabContextSymbol, tabsProps } from "./common";
import SarTab from "../tab/tab.vue";
import { usePopupEnter } from "../popup/common";
const __default__ = {
  options: {
    virtualHost: true,
    styleIsolation: "shared"
  }
};
export default /* @__PURE__ */ _defineComponent({
  ...__default__,
  __name: "tabs",
  props: tabsProps,
  emits: ["update:current"],
  setup(__props, { expose: __expose, emit: __emit }) {
    __expose();
    const props = __props;
    const emit = __emit;
    const bem = createBem("tabs");
    const scrollToTab = async (name) => {
      if (!needScrollToTab.value || !tabMap[name]) {
        return;
      }
      const [scrollRect, wrapperRect, tabRect] = await Promise.all([
        getBoundingClientRect(`#${scrollId}`, instance),
        getBoundingClientRect(`#${wrapperId}`, instance),
        tabMap[name].getRect()
      ]);
      scrollLeft.value = tabRect.left - wrapperRect.left - (scrollRect.width - tabRect.width) / 2;
      if (props.type === "line") {
        lineLeft.value = tabRect.left - wrapperRect.left + tabRect.width / 2;
      }
      if (!scrollInitialized.value) {
        setTimeout(() => {
          scrollInitialized.value = true;
        }, 30);
      }
    };
    const scrollToTabQueue = ref();
    watch(scrollToTabQueue, () => {
      setTimeout(() => {
        if (scrollToTabQueue.value !== void 0) {
          scrollToTab(scrollToTabQueue.value);
          scrollToTabQueue.value = void 0;
        }
      }, 30);
    });
    const innerCurrent = ref(props.current);
    const instance = getCurrentInstance();
    const scrollId = uniqid();
    const wrapperId = uniqid();
    const lineLeft = ref(0);
    const scrollLeft = ref(0);
    const scrollInitialized = ref(false);
    const tabMap = {};
    const needScrollToTab = computed(() => {
      return props.type === "line" || props.type === "pill" && props.scrollable;
    });
    watch(
      () => props.current,
      () => {
        if (props.current !== innerCurrent.value) {
          innerCurrent.value = props.current;
          scrollToTabQueue.value = innerCurrent.value;
        }
      }
    );
    watch(
      () => props.list,
      () => {
        scrollToTabQueue.value = innerCurrent.value;
      }
    );
    usePopupEnter(() => {
      scrollToTabQueue.value = innerCurrent.value;
    });
    provide(
      tabContextSymbol,
      reactive({
        current: innerCurrent,
        register(name, expose) {
          tabMap[name] = expose;
        },
        unregister(name) {
          delete tabMap[name];
        },
        select(name) {
          innerCurrent.value = name;
          emit("update:current", name);
          scrollToTabQueue.value = name;
        }
      })
    );
    const tabsClass = computed(() => {
      return classNames(
        bem.b(),
        bem.m(props.type),
        bem.m("scrollable", props.scrollable),
        props.rootClass
      );
    });
    const tabsStyle = computed(() => {
      return stringifyStyle(props.rootStyle);
    });
    const lineStyle = computed(() => {
      return stringifyStyle({
        left: lineLeft.value + "px",
        transitionDuration: scrollInitialized.value ? null : "0s",
        opacity: scrollInitialized.value ? null : 0
      });
    });
    const __returned__ = { props, emit, bem, scrollToTab, scrollToTabQueue, innerCurrent, instance, scrollId, wrapperId, lineLeft, scrollLeft, scrollInitialized, tabMap, needScrollToTab, tabsClass, tabsStyle, lineStyle, SarTab };
    return __returned__;
  }
});
</script>

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