<script setup lang="ts">
import { ChevronUpIcon } from '@lucide/vue'
import type { HTMLAttributes } from 'vue'
import { onBeforeUnmount, ref, watchEffect } from 'vue'
import { cn } from '@/lib/utils'

const props = defineProps<{ viewport: HTMLElement | null, class?: HTMLAttributes['class'] }>()

const visible = ref(false)
let scrollInterval: ReturnType<typeof setInterval> | undefined

function updateVisibility() {
  visible.value = !!props.viewport && props.viewport.scrollTop > 0
}

watchEffect((onCleanup) => {
  const viewport = props.viewport
  if (!viewport) return
  updateVisibility()
  viewport.addEventListener('scroll', updateVisibility)
  onCleanup(() => viewport.removeEventListener('scroll', updateVisibility))
})

function startScroll() {
  stopScroll()
  scrollInterval = setInterval(() => {
    if (props.viewport) props.viewport.scrollTop -= 8
  }, 16)
}
function stopScroll() {
  if (scrollInterval) clearInterval(scrollInterval)
  scrollInterval = undefined
}
onBeforeUnmount(stopScroll)
</script>

<template>
  <div
    v-if="visible"
    data-slot="select-scroll-up-button"
    :class="cn('bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*=size-])]:size-4', props.class)"
    @pointerdown="startScroll"
    @pointerup="stopScroll"
    @pointerleave="stopScroll"
  >
    <slot>
      <ChevronUpIcon />
    </slot>
  </div>
</template>
