<template>
  <div class="wrapper overflow-hidden relative">
    <Transition>
      <button
        v-show="!isTightlyConnectedToLeft"
        @click="goToLeft"
        class="leftArrow cursor-default absolute left-0 z-10 top-1/2 -translate-y-1/2 flex items-center"
      >
        <Icon
          icon-name="iconshouqi"
          style="font-size: 19px"
          class="-rotate-90 cursor-pointer"
        ></Icon>
      </button>
    </Transition>

    <Transition>
      <button
        v-show="!isTightlyConnectedToRight"
        class="rightArrow cursor-default absolute right-0 z-10 top-1/2 -translate-y-1/2 flex items-center justify-end"
      >
        <Icon
          @click="goToRight"
          icon-name="iconshouqi"
          style="font-size: 19px"
          class="rotate-90 cursor-pointer"
        ></Icon>
      </button>
    </Transition>
    <div
      class="w-full overflow-hidden scroll-smooth transition-all"
      ref="containerRef"
      :class="{}"
    >
      <slot></slot>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, Ref, ref, watch } from "vue";
import Icon from "../Icon/index.vue";
import {
  MaybeElement,
  MaybeElementRef,
  MaybeRef,
  useMutationObserver,
  useScroll,
} from "@vueuse/core";

const isTightlyConnectedToLeft = ref(false);
const isTightlyConnectedToRight = ref(false);
const containerRef = ref<Element | null>(null);

useMutationObserver(
  containerRef as MaybeElementRef<MaybeElement>,
  () => {
    nextTick(() => {
      setArrowStatus();
    });
  },
  {
    attributes: true,
    subtree: true,
    childList: true,
  }
);

onMounted(() => {
  nextTick(() => {
    setArrowStatus();
  });
});

const emit = defineEmits(["toAlmostEnd"]);

const setArrowStatus = () => {
  if (!containerRef.value) return;
  isTightlyConnectedToLeft.value = containerRef.value?.scrollLeft <= 10;

  isTightlyConnectedToRight.value =
    containerRef.value?.scrollWidth -
      (containerRef.value?.scrollLeft + containerRef.value?.clientWidth) <=
    10;
};

const { isScrolling } = useScroll(containerRef as MaybeRef<HTMLElement>);

watch(isScrolling, () => {
  if (isScrolling.value === false) {
    setArrowStatus();
  }
});

const goToLeft = () => {
  containerRef.value!.scrollLeft -= containerRef.value?.clientWidth! / 3;
};
const goToRight = () => {
  containerRef.value!.scrollLeft += containerRef.value?.clientWidth! / 3;
  if (
    containerRef.value!.scrollWidth -
      (containerRef.value!.scrollLeft + containerRef.value!.clientWidth) <=
    (containerRef.value?.clientWidth! / 3) * 2
  )
    emit("toAlmostEnd");
};

const goToEnd = () => {
  containerRef.value!.scrollLeft =
    containerRef.value!.scrollWidth - containerRef.value!.clientWidth;
};

defineExpose({
  goToEnd,
});
</script>
<style scoped lang="scss">
.wrapper {
  .leftArrow {
    width: 70px;
    height: 40px;
    background: linear-gradient(90deg, #ffffff 0%, rgba(255, 255, 255, 0) 100%);
  }
  .rightArrow {
    width: 70px;
    height: 40px;
    background: linear-gradient(
      270deg,
      #ffffff 0%,
      rgba(255, 255, 255, 0) 100%
    );
  }
}
</style>
