<template>
  <div class="fullpage-container" @wheel.prevent="handleWheel" @touchstart="handleTouchStart"
    @touchend="handleTouchEnd">
    <div class="fullpage-wrapper" :style="wrapperStyle">
      <slot />
    </div>
    <div class="fullpage-dots">
      <span v-for="i in pageCount" :key="i" class="dot" :class="{ active: currentIndex === i - 1 }"
        @click="goTo(i - 1)" />
    </div>
  </div>
</template>

<script setup>
import { ref, computed, useSlots } from 'vue'

const slots = useSlots()
const pageCount = computed(() => {
  const defaultSlot = slots.default?.()
  return defaultSlot ? defaultSlot.length : 0
})

const currentIndex = ref(0)
const isAnimating = ref(false)
const touchStartY = ref(0)

const wrapperStyle = computed(() => ({
  transform: `translateY(-${currentIndex.value * 100}vh)`,
  transition: isAnimating.value ? 'transform 0.8s cubic-bezier(0.65, 0, 0.35, 1)' : 'none',
}))

function goTo(index) {
  if (isAnimating.value || index === currentIndex.value) return
  if (index < 0 || index >= pageCount.value) return
  isAnimating.value = true
  currentIndex.value = index
  setTimeout(() => {
    isAnimating.value = false
  }, 800)
}

function handleWheel(e) {
  if (isAnimating.value) return
  if (e.deltaY > 0) {
    goTo(currentIndex.value + 1)
  } else if (e.deltaY < 0) {
    goTo(currentIndex.value - 1)
  }
}

function handleTouchStart(e) {
  touchStartY.value = e.touches[0].clientY
}

function handleTouchEnd(e) {
  const deltaY = touchStartY.value - e.changedTouches[0].clientY
  if (Math.abs(deltaY) > 50) {
    if (deltaY > 0) {
      goTo(currentIndex.value + 1)
    } else {
      goTo(currentIndex.value - 1)
    }
  }
}

defineExpose({ currentIndex, goTo })
</script>

<style scoped>
.fullpage-container {
  width: 100%;
  height: 100vh;
  overflow: hidden;
  position: relative;
}

.fullpage-wrapper {
  width: 100%;
  will-change: transform;
}

.fullpage-dots {
  position: fixed;
  right: 30px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  z-index: 100;
}

@media (max-width: 768px) {
  .fullpage-dots {
    right: unset;
    top: unset;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    flex-direction: row;
  }
}

.dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.3s ease;
}

.dot.active {
  background: #00BFA5;
  border-color: #00BFA5;
  transform: scale(1.3);
  box-shadow: 0 0 8px rgba(0, 191, 165, 0.4);
}
</style>
