<script setup lang="ts">
import { Splide, SplideTrack } from '@splidejs/vue-splide'
import { getPaginationClass } from '#layers/utils/styleUtil'
import type { Splide as SplideType, ResponsiveOptions } from '@splidejs/splide'
import type { PageDataResourceGroups } from '#layers/types/api/pageData'

interface Props {
  type?: ResponsiveOptions['type']
  slideItemLength?: number
  gap?: number
  autoplay?: boolean
  interval?: number
  perPage?: number
  drag?: boolean
  arrows?: boolean
  arrowsData?: PageDataResourceGroups
  pagination?: boolean
  paginationData?: PageDataResourceGroups
  destroy?: boolean
  breakpoints?: ResponsiveOptions['breakpoints']
}

const props = withDefaults(defineProps<Props>(), {
  gap: 0,
  autoplay: false,
  interval: 5000,
  perPage: 1,
  drag: true,
  arrows: true,
  pagination: true,
  destroy: false,
})

const emit = defineEmits(['mounted', 'move'])

const splideIndex = defineModel<number>('index', { required: false })

const slideType = computed(() => {
  if (props.type) return props.type

  return (props.slideItemLength ?? 0) > 1 ? 'loop' : 'slide'
})

const options = computed((): ResponsiveOptions => {
  return {
    type: slideType.value,
    autoWidth: true,
    autoHeight: true,
    gap: props.gap,
    perPage: props.perPage,
    speed: 600,
    easing: 'ease-in-out',
    updateOnMove: true,
    autoplay: props.autoplay,
    interval: props.interval,
    drag: props.drag,
    arrows: props.arrows,
    pagination: props.pagination,
    destroy: props.destroy,
    flickPower: 300,
    classes: {
      pagination: 'splide-pagination-bullets',
      page: 'splide-pagination-bullet',
    },
    ...(props.breakpoints ? { breakpoints: props.breakpoints } : {}),
  }
})

const handleSplideMounted = (splide: SplideType) => {
  emit('mounted', splide)

  if (splideIndex.value !== undefined) {
    splideIndex.value = splide.index
  }
}

const handleMove = (
  splide: SplideType,
  newIndex: number,
  oldIndex: number,
  destIndex: number
) => {
  emit('move', splide, newIndex, oldIndex, destIndex)

  if (splideIndex.value !== undefined) {
    splideIndex.value = newIndex
  }
}
</script>

<template>
  <Splide
    :options="options"
    :has-track="false"
    :style="getPaginationClass(props?.paginationData)"
    @splide:mounted="handleSplideMounted"
    @splide:move="handleMove"
  >
    <SplideTrack>
      <slot />
    </SplideTrack>
    <BlocksButtonSlideArrows
      v-if="props.arrows"
      :arrows-data="props.arrowsData"
    />
  </Splide>
</template>
