<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";

const props = defineProps({
  items: {
    required: true,
  },
  height: {
    type: String,
    default: "h-96",
  },
  class: {
    type: String,
    default: "",
  },
});
const items = props.items;

const activeIndex = ref(0);
const downStartX = ref(0);
const isDragging = ref(false);
const touchStartX = ref(0);
const carouselWrapper = ref(null);

const handleMouseDown = (e) => {
  isDragging.value = true;
  downStartX.value = e.pageX;
};

const handleMouseMove = (e) => {
  if (!isDragging.value) return;

  const movePx = e.pageX;
  const diff = downStartX.value - movePx;
  const threshold = 50;

  if (diff > threshold) {
    slideNext();
    isDragging.value = false;
  } else if (diff < -threshold) {
    slidePrev();
    isDragging.value = false;
  }
};

const handleMouseUp = () => {
  isDragging.value = false;
};

const handleTouchStart = (e) => {
  touchStartX.value = e.changedTouches[0].screenX;
};

const handleTouchEnd = (e) => {
  const touchEndX = e.changedTouches[0].screenX;
  const diff = touchStartX.value - touchEndX;
  const threshold = 50;

  if (diff > threshold) slideNext();
  else if (diff < -threshold) slidePrev();
};

const goToSlide = (index) => {
  if (!carouselWrapper.value) return;

  activeIndex.value = index;

  const buttons = carouselWrapper.value?.querySelectorAll(
    "[data-carousel-slide-to]",
  );

  buttons?.[index]?.click();
};

const slideNext = () => {
  const nextIndex = (activeIndex.value + 1) % items.length;

  goToSlide(nextIndex);
};

const slidePrev = () => {
  const prevIndex = (activeIndex.value - 1 + items.length) % items.length;

  goToSlide(prevIndex);
};

onMounted(() => {
  if (!carouselWrapper.value) return;

  carouselWrapper.value.addEventListener("mousedown", handleMouseDown);
  carouselWrapper.value.addEventListener("mousemove", handleMouseMove);
  window.addEventListener("mouseup", handleMouseUp);
  carouselWrapper.value.addEventListener("touchstart", handleTouchStart, {
    passive: true,
  });
  carouselWrapper.value.addEventListener("touchend", handleTouchEnd);
});

onBeforeUnmount(() => {
  if (!carouselWrapper.value) return;

  carouselWrapper.value.removeEventListener("mousedown", handleMouseDown);
  carouselWrapper.value.removeEventListener("mousemove", handleMouseMove);
  window.removeEventListener("mouseup", handleMouseUp);
  carouselWrapper.value.removeEventListener("touchstart", handleTouchStart);
  carouselWrapper.value.removeEventListener("touchend", handleTouchEnd);
});
</script>
<template>
  <div
    ref="carouselWrapper"
    id="default-carousel"
    :class="`relative w-full ${height}`"
    data-carousel="slide"
  >
    <!-- Carousel wrapper -->
    <div :class="`relative z-0 ${height} overflow-hidden ${props.class}`">
      <template v-for="(item, index) in items" :key="index">
        <!-- Item 1 -->
        <a
          class="hidden duration-3000 cursor-pointer ease-in-out"
          data-carousel-item
          v-if="item.href"
          :href="item.href"
          target="_blank"
        >
          <img
            :src="item.image"
            :class="`absolute block w-full -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2 h-full object-cover sm:object-contain`"
            alt="..."
          />
        </a>
        <div class="hidden duration-3000 ease-in-out" data-carousel-item v-else>
          <img
            :src="item.image"
            :class="`absolute block w-full -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2 h-full object-cover sm:object-contain pointer-events-none`"
            alt="..."
          />
        </div>
      </template>
      <div
        class="absolute z-30 flex -translate-x-1/2 bottom-4 sm:bottom-12 lg:bottom-11 xl:bottom-10 2xl:bottom-6 left-1/2 space-x-3 rtl:space-x-reverse"
      >
        <button
          v-for="(item, index) in items"
          :key="index"
          type="button"
          class="w-3 h-3 lg:w-2 lg:h-2 xl:w-3 xl:h-3 rounded-full transition-opacity"
          :aria-current="activeIndex === index"
          :aria-label="'Slide ' + (index + 1)"
          :data-carousel-slide-to="index"
          @click="goToSlide(index)"
        ></button>
      </div>
    </div>
  </div>
</template>
