import {
  computed, defineComponent, onBeforeUnmount, onMounted, type PropType, type Ref, ref,
} from 'vue'
import './scrollbar.scss'

export default defineComponent({
  name: 'ScrollBar',
  props: {
    onScroll: {
      type: Function as PropType<(position: number) => void>,
      required: true,
    },
    scroll: {
      type: Number,
      required: true,
    },
    type: {
      type: String as PropType<'vertical'|'horizontal'>,
      required: true,
    },
  },
  setup(props) {
    const rootElement: Ref<HTMLElement|undefined> = ref(undefined)
    const switchElement: Ref<HTMLElement|undefined> = ref(undefined)
    const isDragging = ref(false)

    const getSwitchOffset = () => Number(props.type === 'horizontal' ? switchElement.value?.offsetLeft : switchElement.value?.offsetTop)

    const clickHandler = (e: any) => {
      const offset = e.target.className === 'ark-ui-scrollbar-switch' ? getSwitchOffset() : 0
      const clickPosition = props.type === 'horizontal' ? e.layerX : e.layerY
      const scrollbarLength = Number(props.type === 'horizontal' ? rootElement.value?.clientWidth : rootElement.value?.clientHeight)
      let result = ((offset + clickPosition) / scrollbarLength) * 100
      if (result < 0) result = 0
      if (result > 100) result = 100

      if (props.onScroll) props.onScroll(result)
    }

    const mouseHandler = (e: any) => {
      if (!isDragging.value) return
      clickHandler(e)
    }

    const startDrag = (e: any) => {
      isDragging.value = true
      document.addEventListener('mousemove', mouseHandler)
    }

    const stopDrag = () => {
      isDragging.value = false
      document.addEventListener('mousemove', mouseHandler)
    }

    const switchStyle = computed(() => {
      const position = props.type === 'horizontal'
        ? ((Number(rootElement.value?.clientWidth) - Number(switchElement.value?.clientWidth)) * props.scroll) / 100
        : ((Number(rootElement.value?.clientHeight) - Number(switchElement.value?.clientHeight)) * props.scroll) / 100
      return props.type === 'vertical' ? `top: ${position}px;` : `left: ${position}px;`
    })

    onMounted(() => {
      document.addEventListener('mouseup', stopDrag)
    })

    onBeforeUnmount(() => {
      document.removeEventListener('mouseup', stopDrag)
    })

    return () => (
      <div
        class={`ark-ui-scrollbar ${props.type}`}
        onClick={clickHandler}
        ref={rootElement}
      >
        <div class="ark-ui-scrollbar-active"/>
        <div
          class="ark-ui-scrollbar-switch"
          style={switchStyle.value}
          ref={switchElement}
          onMousedown={startDrag}
        />
      </div>
    )
  },
})
