<template>
  <div
    :style="sliderStyle"
    class="infinite-slider ticker flex justify-center w-full">
    <div class="barrier relative overflow-hidden transition-[all_0.3s_ease]">
      <div
        ref="lane"
        :class="{ reversed }"
        :style="[reversed ? 'animation-direction: reverse' : '']"
        class="lane flex h-full">
        <slot />
        <slot />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  props: {
    reversed: Boolean,
    animationDuration: {
      type: Number,
      default: 38,
    },
  },

  data: () => ({
    itemsCount: 0,
    itemWidth: 0,
  }),

  computed: {
    sliderStyle(): Record<string, string | number> {
      return {
        '--items-count': this.itemsCount,
        '--item-width': `${this.itemWidth}px`,
        '--translate-value': `${this.translateValue}px`,
      };
    },
    translateValue(): number {
      return -1 * this.itemWidth * (this.itemsCount / 2);
    },
  },

  mounted() {
    const observer = new ResizeObserver(this.resizeHandler);
    const lane = this.$refs.lane as HTMLElement;

    if (lane && lane.firstElementChild) {
      observer.observe(lane.firstElementChild);
    }
  },

  methods: {
    resizeHandler() {
      const lane = this.$refs.lane as HTMLElement;

      if (!lane || !lane.firstElementChild) {
        return;
      }

      this.itemsCount = lane.children.length;
      this.itemWidth = lane.firstElementChild.clientWidth;

      lane.style.animationName = 'ticker';
      lane.style.animationDuration = `${this.animationDuration}s`;
      lane.style.animationTimingFunction = 'linear';
      lane.style.animationIterationCount = 'infinite';
    },
  },
});
</script>
