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

interface Props {
  thumbnailData: PageDataResourceGroup[]
  paginationData: PageDataResourceGroups
  analyticsSarea: string
  drag?: boolean
  arrows?: boolean
  arrowsData?: PageDataResourceGroups
  variant?: 'default' | 'media'
}

const props = withDefaults(defineProps<Props>(), {
  drag: true,
  arrows: true,
  variant: 'default',
})

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

const { locale } = useI18n()
const { sendLog } = useAnalytics()

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

let mainInst: SplideType | null = null
let thumbsInst: SplideType | null = null
let removeArrowListeners: (() => void) | null = null

defineExpose({
  mainInst: computed(() => mainInst),
  thumbsInst: computed(() => thumbsInst),
})

const mainRef = ref<InstanceType<typeof Splide> | null>(null)
const thumbsRef = ref<InstanceType<typeof Splide> | null>(null)

const mainOptions = computed<Options>(() => ({
  type: 'fade',
  rewind: true,
  perPage: 1,
  perMove: 1,
  speed: 600,
  easing: 'ease-in-out',
  arrows: false,
  pagination: false,
  drag: props.drag,
  updateOnMove: true,
  lazyLoad: 'nearby',
}))

const thumbOptions = computed<Options>(() => ({
  type: 'slide',
  rewind: true,
  autoWidth: true,
  perMove: 1,
  arrows: props.arrows,
  pagination: false,
  isNavigation: true,
  updateOnMove: true,
  flickPower: 300,
  breakpoints: {
    [BREAKPOINTS.md - 1]: {
      padding: {
        left: 40,
        right: 40,
      },
    },
    [BREAKPOINTS.sm - 1]: {
      padding: {
        left: 20,
        right: 20,
      },
    },
  },
}))

const getThumbnailSrc = (item: PageDataResourceGroup) => {
  if (isTypeVideo(item?.resource_type)) {
    return getYouTubeThumbnail(item?.display?.text, 'medium')
  }

  return getResourceSrc(item)
}

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
  }
}

const handleThumbnailClick = (title: string) => {
  const paginationAnalytics = {
    action_type: 'click',
    click_item: title,
    click_sarea: props.analyticsSarea,
  }

  sendLog(locale.value, paginationAnalytics)
}

onMounted(() => {
  mainInst = mainRef.value?.splide ?? null
  thumbsInst = thumbsRef.value?.splide ?? null

  if (mainInst && thumbsInst) {
    mainInst.sync(thumbsInst)
  }
})

onBeforeUnmount(() => {
  // 이벤트 리스너 제거
  if (removeArrowListeners) {
    removeArrowListeners()
    removeArrowListeners = null
  }

  // Splide 인스턴스 정리
  mainInst?.destroy?.()
  thumbsInst?.destroy?.()
  mainInst = null
  thumbsInst = null
})
</script>

<template>
  <div :class="['thumbnail-carousel', $attrs?.class, `thumbnail-${variant}`]">
    <!-- 메인 슬라이드 -->
    <Splide
      ref="mainRef"
      :options="mainOptions"
      class="main-splide"
      @splide:mounted="handleSplideMounted"
      @splide:move="handleMove"
    >
      <slot />
    </Splide>
    <!-- 썸네일 슬라이드 -->
    <Splide
      v-if="props.thumbnailData.length > 1"
      ref="thumbsRef"
      :options="thumbOptions"
      :arrows-data="props.arrowsData"
      :has-track="false"
      class="thumbnail-splide"
      :style="getPaginationClass(paginationData)"
    >
      <SplideTrack>
        <SplideSlide
          v-for="(item, index) in props.thumbnailData"
          :key="index"
          class="thumbnail-slide"
          @click="handleThumbnailClick(item?.group_label ?? `${index + 1}`)"
        >
          <AtomsImg
            :src="getThumbnailSrc(item)"
            alt="thumbnail image"
            class="slide-image"
          />
        </SplideSlide>
      </SplideTrack>
      <BlocksButtonSlideArrows
        v-if="props.arrows"
        :arrows-data="props.arrowsData"
      />
    </Splide>
  </div>
</template>

<style scoped>
.thumbnail-carousel:deep(img) {
  @apply w-full h-full object-cover;
}
.thumbnail-splide {
  @apply overflow-hidden flex justify-center;
}
.thumbnail-splide:deep(.splide__track) {
  @apply md:w-[calc(100%-16px)];
}
.thumbnail-slide {
  @apply overflow-hidden relative mr-[12px] !border-none rounded-[4px] bg-[var(--pagination-disabled)] md:mr-[16px] transition-all duration-200 ease-in-out
  after:content-[''] after:absolute after:top-0 after:left-0 after:w-full after:h-full after:border after:rounded-[4px] after:transition-all after:duration-200 after:ease-in-out;
}
.thumbnail-slide:hover,
.thumbnail-slide.is-active {
  @apply bg-[var(--pagination-active)];
}
.thumbnail-slide::after {
  @apply border-[var(--pagination-disabled)];
}
.thumbnail-slide:hover::after,
.thumbnail-slide.is-active::after {
  @apply border-[var(--pagination-active)];
}
.thumbnail-slide:hover picture,
.thumbnail-slide:hover img,
.thumbnail-slide.is-active picture,
.thumbnail-slide.is-active img {
  @apply opacity-100;
}
.thumbnail-slide picture,
.thumbnail-slide img {
  @apply opacity-50 transition-opacity duration-200 ease-in-out;
}

/* 기본 버전 스타일 */
.thumbnail-carousel.thumbnail-default,
.thumbnail-carousel.thumbnail-default .main-splide,
.thumbnail-carousel.thumbnail-default .main-splide:deep(.splide__track) {
  @apply h-full;
}
.thumbnail-carousel.thumbnail-default .thumbnail-splide {
  @apply absolute bottom-[32px] left-1/2 -translate-x-1/2 max-w-[100%] md:bottom-[48px] md:max-w-[896px] md:px-[64px];
}
.thumbnail-carousel.thumbnail-default:deep(.splide__arrow--prev) {
  @apply left-0;
}
.thumbnail-carousel.thumbnail-default:deep(.splide__arrow--next) {
  @apply right-0;
}
.thumbnail-carousel.thumbnail-default .thumbnail-slide {
  @apply aspect-[1/1] w-[8px] md:w-[80px] backdrop-blur-[15px]
  after:hidden md:after:block;
}
.thumbnail-carousel.thumbnail-default .thumbnail-slide:hover picture,
.thumbnail-carousel.thumbnail-default .thumbnail-slide.is-active picture {
  @apply md:grayscale-0;
}
.thumbnail-carousel.thumbnail-default .thumbnail-slide picture {
  @apply hidden md:block md:grayscale;
}

/* 미디어 버전 스타일 */
.thumbnail-carousel.thumbnail-media {
  @apply flex flex-col items-center;
}
.thumbnail-carousel.thumbnail-media .thumbnail-splide {
  @apply max-w-[calc(100%+40px)] mt-[20px] mx-[-20px] 
  sm:max-w-[calc(100%+80px)] sm:mx-[-40px] 
  md:max-w-[100%] md:mt-[28px] md:mx-auto md:px-[64px];
}
.thumbnail-carousel.thumbnail-media:deep(.splide__arrow--prev) {
  @apply left-[0];
}
.thumbnail-carousel.thumbnail-media:deep(.splide__arrow--next) {
  @apply right-[0];
}
.thumbnail-carousel.thumbnail-media .thumbnail-slide {
  @apply aspect-[16/9] w-[92px] md:w-[128px];
}
</style>
