<template>
  <div v-show="showSwiper" class="relative" :class="rootClasses">
    <swiper
      loop-add-blank-slides
      :class="sliderClasses"
      :direction="direction"
      :breakpoints="{
        450: { slidesPerView: 1.2, spaceBetween: 20 },
        500: { slidesPerView: 1.5, spaceBetween: 20 },
        600: { slidesPerView: 1.5, spaceBetween: 20 },
        770: { slidesPerView: 1, spaceBetween: 20 },
        800: { slidesPerView: 1, spaceBetween: 20 },
        1000: { slidesPerView: 1.2, spaceBetween: 20 },
        1200: { slidesPerView: 1.5, spaceBetween: 20 },
        1600: { slidesPerView: 2, spaceBetween: 40 },
        2000: { slidesPerView: 2.5, spaceBetween: 40 },
      }"
      :space-between="50"
      @swiper="onSwiper"
      @slide-change="onSlideChange"
    >
      <swiper-slide
        v-for="item in items"
        :key="item.title"
        class="hover:cursor-pointer"
      >
        <slot :item="item" />
      </swiper-slide>
    </swiper>
    <div>
      <div :class="counterClasses">
        <div :class="progressClass"
          :style="`width: ${progerssBar}%`"
        ></div>
        <div class="flex justify-between my-4">
          <button
            :disabled="isPrevDisabled"
            class="px-4 py-2 disabled:text-gray-400 cursor-pointer"
            @click="
              useRipple($event, true);
              goPrev();
            "
          >
            <ArrowLeftIcon class="size-5" />
          </button>
          <button
            :disabled="isNextDisabled"
            class="px-4 py-2 disabled:text-gray-400 cursor-pointer"
            @click="
              useRipple($event, true);
              goNext();
            "
          >
            <ArrowRightIcon class="size-5" />
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps, withDefaults } from "vue";
import { Swiper, SwiperSlide } from "swiper/vue";
import type { Swiper as swiper } from "swiper/types";
import "swiper/css";
import { twMerge } from "tailwind-merge";
import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/vue/24/solid";
import type { PTAttribs, SliderProps } from "./types";

const showSwiper = ref(false);
const progerssBar = ref(0);
const prevDisabled = ref(true);
const nextDisabled = ref(true);

let swiperInstance: swiper;

const onSwiper = (swiper: swiper) => {
  progerssBar.value = Math.ceil(
    ((swiper.realIndex + (swiper.params.slidesPerView as number)) /
      swiper.el.querySelectorAll(".swiper-slide").length) *
      100
  );
  swiperInstance = swiper;
  showSwiper.value = true;
  prevDisabled.value = !swiper.params.loop && swiper.realIndex == 0;
  nextDisabled.value = swiperInstance.isEnd;
};

const onSlideChange = (swiper: swiper) => {
  progerssBar.value = Math.ceil(
    ((swiper.realIndex + (swiper.params.slidesPerView as number)) /
      swiper.slides.length) *
      100
  );
  prevDisabled.value = !swiper.params.loop && swiper.realIndex == 0;
  nextDisabled.value = swiper.isEnd;
};

const isPrevDisabled = computed(() => prevDisabled.value);
const isNextDisabled = computed(() => nextDisabled.value);

function goNext() {
  swiperInstance.slideNext();
}

function goPrev() {
  swiperInstance.slidePrev();
}

const props = withDefaults(defineProps<SliderProps>(), {
  items: [],
});

const classes = ref({
  root: {
    class: ``,
  },
  slider: {
    class: ``,
  },
  counter: {
    class: ``,
  },
  progress: {
    class: "",
  },
} as unknown as PTAttribs);

const rootClasses = computed(() =>
  twMerge(classes.value.root?.class, props.pt?.root?.class)
);
const sliderClasses = computed(() =>
  twMerge(classes.value.slider?.class, props.pt?.slider?.class)
);
const counterClasses = computed(() =>
  twMerge(classes.value.counter?.class, props.pt?.counter?.class)
);
const progressClass = computed(() =>
  twMerge(classes.value.progress?.class, props.pt?.progress?.class)
);

const items = props.items;
</script>
