<template>
  <div
    ref="item"
    :style="itemStyle"
    :class="{
      'in-stage': isInStage,
      active: index === current,
    }"
    class="mm-carousel-item"
    @transitionend="transitionEnd">
    <slot></slot>
  </div>
</template>

<script>
const CARD_SCALE = 0.83

export default {
  name: "mm-carousel-item",
  data() {
    return {
      parentWidth: 0,
      addTransition: false,
    }
  },
  inject: {
    carousel: {
      from: "mm-carousel",
      default: null,
    },
  },
  computed: {
    total() {
      return this.carousel.itemList.length
    },
    index() {
      return this.carousel.itemList.indexOf(this)
    },
    isCard() {
      return this.carousel.type === "card"
    },
    width() {
      const ratio = this.isCard ? 2 : 1
      return this.parentWidth / ratio
    },
    last() {
      return this.carousel.last
    },
    current() {
      return this.carousel.current
    },
    easing() {
      return this.carousel.easing
    },
    adaptiveWidth() {
      return this.carousel.adaptiveWidth
    },
    isLast() {
      return this.total > 2 && this.current === 0 && this.index === this.total - 1
    },
    isFirst() {
      return this.total > 2 && this.current === this.total - 1 && this.index === 0
    },
    isInStage() {
      return (
        this.index === this.current - 1 ||
        this.index === this.current + 1 ||
        this.isFirst ||
        this.isLast
      )
    },
    itemStyle() {
      const {
        index,
        current,
        isCard,
        width,
        easing,
        parentWidth,
        total,
        last,
        adaptiveWidth,
        addTransition,
      } = this
      const duration = this.carousel.easingTime
      const scale = isCard && current !== index ? ` scale(${CARD_SCALE})` : ""
      let translate = this.calculateTranslate(index, current, total, parentWidth, isCard)

      let style = {
        width: width + "px",
        transform: `translateX(${translate}px)${scale}`,
      }
      if ((current === index || last === index || isCard) && (!adaptiveWidth || addTransition)) {
        style.transition = `transform ${duration}s ${easing}`
      }

      return style
    },
  },
  watch: {
    current() {
      this.addTransition = true
    },
  },
  created() {
    this.carousel.register(this)
  },
  beforeDestroy() {
    this.carousel.unregister(this)
  },
  mounted() {
    this.$nextTick(() => {
      this.computedWidth()
    })
  },
  methods: {
    computedWidth() {
      this.parentWidth = this.carousel.$el.offsetWidth
    },
    transitionEnd() {
      this.addTransition = false
    },
    calculateTranslate(index, current, total, parentWidth, isCard) {
      let translate = 0
      let left = isCard ? (this.isInStage ? -parentWidth / 8 : -parentWidth / 2) : -parentWidth
      let right = isCard ? (this.isInStage ? (parentWidth * 5) / 8 : parentWidth) : parentWidth
      let center = isCard ? parentWidth / 4 : 0

      translate = current === index ? center : current > index ? left : right

      if (this.isFirst) {
        translate = right
      }

      if (this.isLast) {
        translate = left
      }

      return translate
    },
  },
}
</script>
