<template>
  <view
    :class="navClass"
    :style="navStyle"
    :id="navId"
    @touchstart="onTouchStart"
    @touchmove.stop.prevent="onTouchMove"
    @touchend="onTouchEnd"
    @touchcancel="onTouchEnd"
    @mousedown="onMouseDown"
  >
    <view
      v-for="(name, i) in anchors"
      :key="i"
      :class="
        classNames(
          bem.e('nav-item'),
          bem.em('nav-item', 'active', name === current),
        )
      "
    >
      {{ name }}
    </view>
    <view
      v-if="realVisible"
      :class="classNames(bem.e('hint'), transitionClass)"
      :style="
        stringifyStyle({
          top: hintTop,
        })
      "
      @transitionend="onTransitionEnd"
    >
      <view :class="bem.e('hint-text')">
        {{ current }}
      </view>
    </view>
  </view>
</template>

<script lang="ts">
import { defineComponent as _defineComponent } from "vue";
import { computed, ref, getCurrentInstance, reactive } from "vue";
import {
  classNames,
  stringifyStyle,
  createBem,
  uniqid,
  getBoundingClientRect,
  minmax,
  toTouchEvent
} from "../utils";
import { useTransition } from "../use";
import { indexesNavProps } from "../indexes/common";
import { defaultConfig } from "../config";
const __default__ = {
  options: {
    virtualHost: true,
    styleIsolation: "shared"
  }
};
export default /* @__PURE__ */ _defineComponent({
  ...__default__,
  __name: "indexes-nav",
  props: indexesNavProps,
  emits: ["select"],
  setup(__props, { expose: __expose, emit: __emit }) {
    __expose();
    const props = __props;
    const emit = __emit;
    const bem = createBem("indexes");
    const instance = getCurrentInstance();
    const itemSize = 20;
    const navId = uniqid();
    const navRect = ref();
    const hintVisible = ref(false);
    let currentItemIndex = null;
    let moved = false;
    const getNavRect = async () => {
      navRect.value = await getBoundingClientRect(`#${navId}`, instance);
    };
    const { realVisible, transitionClass, onTransitionEnd } = useTransition(
      reactive({
        visible: hintVisible,
        duration: defaultConfig.indexes.hintDuration,
        prefix: bem.em("hint", "")
      })
    );
    const hintTop = computed(() => {
      let index = props.current !== void 0 ? props.anchors.indexOf(props.current) : -1;
      if (index < 0) {
        index = 0;
      }
      return index * itemSize + itemSize / 2 + "px";
    });
    const update = (touch) => {
      if (!navRect.value) {
        return;
      }
      const offsetY = touch.clientY - navRect.value.top;
      const itemIndex = minmax(
        Math.floor(offsetY / itemSize),
        0,
        props.anchors.length - 1
      );
      if (itemIndex !== currentItemIndex) {
        currentItemIndex = itemIndex;
        emit("select", props.anchors[itemIndex]);
      }
    };
    const onTouchStart = async (event) => {
      hintVisible.value = true;
      await getNavRect();
      if (!moved) {
        update(event.touches[0]);
      }
    };
    const onTouchMove = (event) => {
      moved = true;
      if (!navRect.value) {
        return;
      }
      update(event.touches[0]);
    };
    const onTouchEnd = () => {
      hintVisible.value = false;
      moved = false;
      navRect.value = void 0;
      currentItemIndex = null;
    };
    const onMouseDown = (event) => {
      const info = uni.getSystemInfoSync();
      onTouchStart(toTouchEvent(event, info.windowTop));
      const moveHandler = (event2) => {
        event2.preventDefault();
        onTouchMove(toTouchEvent(event2, info.windowTop));
      };
      const upHandler = () => {
        onTouchEnd();
        document.removeEventListener("mouseup", upHandler);
        document.removeEventListener("mousemove", moveHandler);
      };
      document.addEventListener("mousemove", moveHandler);
      document.addEventListener("mouseup", upHandler);
    };
    const navClass = computed(() => {
      return classNames(bem.e("nav"));
    });
    const navStyle = computed(() => {
      return stringifyStyle({
        "--sar-indexes-nav-item-size": `${itemSize}px`
      });
    });
    const __returned__ = { props, emit, bem, instance, itemSize, navId, navRect, hintVisible, get currentItemIndex() {
      return currentItemIndex;
    }, set currentItemIndex(v) {
      currentItemIndex = v;
    }, get moved() {
      return moved;
    }, set moved(v) {
      moved = v;
    }, getNavRect, realVisible, transitionClass, onTransitionEnd, hintTop, update, onTouchStart, onTouchMove, onTouchEnd, onMouseDown, navClass, navStyle, get classNames() {
      return classNames;
    }, get stringifyStyle() {
      return stringifyStyle;
    } };
    return __returned__;
  }
});
</script>

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