<template>
  <div class="app-scrollbar_wrapper">
    <div
      class="app-scrollbar_scroller"
      :style="{ maxWidth: `${width}px`, maxHeight: `${height}px` }"
      ref="scroller"
      @scroll="matchScroll"
    >
      <div class="app-scrollbar_content" ref="content">
        <slot></slot>
      </div>
    </div>
    <div
      class="app-scrollbar_thumb__placeholder"
      :style="{
        height: thumb.height,
        top: thumb.top
      }"
      ref="thumb"
    >
      <div
        class="app-scrollbar_thumb"
        @mouseout="matchEndDrop"
        @mousedown="matchStartDrop"
        @mouseup="matchEndDrop"
        @mousemove="thumbDrop"
      ></div>
    </div>
  </div>
</template>

<script>
export default {
  name: "app-scrollbar",
  props: {
    width: {
      type: Number,
      default: 0,
    },
    height: {
      type: Number,
      default: 0,
    },
    changeContent: [String, Number, Boolean]
  },
  data() {
    return {
      thumb: {
        height: 0,
        top: 0,
        start: null,
        pressed: false
      },
      heightScroller: 0,
      heightContent: 0,
      ratio: 1
    };
  },
  methods: {
    matchHeight() {
      this.heightScroller = this.$refs.scroller.clientHeight
      this.heightContent = this.$refs.content.clientHeight
      this.ratio = this.heightScroller / this.heightContent

      let calc_heigth = this.ratio * this.heightScroller
      this.thumb.height = (this.heightScroller < this.heightContent)
        ? `${(calc_heigth > 12) ? (calc_heigth - 6) : 6}px`
        : 0
    },
    matchScroll() {
      this.thumb.top = `${this.ratio * this.$refs.scroller.scrollTop}px`
    },
    matchStartDrop(e) {
      this.thumb.start = e.clientY;
      this.thumb.pressed = true;
    },
    matchEndDrop() {
      this.thumb.pressed = false;
    },
    thumbDrop(e) {
      e.preventDefault()
      if (this.thumb.pressed === false) return
      let shiftThumb = this.thumb.start - e.clientY
      this.thumb.top = (this.$refs.thumb.offsetTop + this.$refs.scroller.offsetTop - shiftThumb) + 'px';
      const totalheightScroller = Number.parseInt(this.thumb.height) + Number.parseInt(this.thumb.top) + 3
      const maxOffsetScroller = this.heightScroller - Number.parseInt(this.thumb.height) - 6

      if (this.$refs.thumb.offsetTop - shiftThumb < 0) this.thumb.top = '0px';

      if (totalheightScroller >= this.heightScroller) this.thumb.top = maxOffsetScroller + 'px';

      let shiftContent = (this.$refs.thumb.offsetTop + this.$refs.scroller.offsetTop) / this.ratio;
      this.$refs.scroller.scrollTo(0, shiftContent);
      this.thumb.start = e.clientY
    },
  },
  mounted() {
    this.matchHeight();
  },
  watch: {
    changeContent: function () {
      setTimeout(this.matchHeight, 100)
    },
  },
};
</script>

<style lang="sass" scoped>

@import "../../assets/_vars"

.app-scrollbar
  &_wrapper
    position: relative
    height: fit-content
    width: 100%
    &:hover
      .app-scrollbar_thumb__placeholder
        opacity: 1
        // min-height: 10px
  &_scroller
    overflow: auto
    scrollbar-width: none
    -ms-overflow-style: none
    scroll-behavior: auto !important
    -ms-overflow-style: none
    scrollbar-width: none
    min-width: 100%
    &::-webkit-scrollbar
      width: 0px
      height: 0
      background: transparent

  &_content
    display: block
  &_thumb
    width: 66.667%
    height: 100%
    background-color: $gray1
    transition: opacity 275ms ease, transform 0.2s ease
    contain: strict
    border-radius: 8px
    &__placeholder
      position: absolute
      display: inline-flex
      justify-content: center
      align-items: center
      user-select: none
      cursor: pointer
      contain: strict
      transition: opacity 275ms ease
      right: 2px
      width: 8px
      transform: translate3d(0px, 3px, 0px)
      opacity: 0
</style>
