<!--
 * @description: 
 * @param: 
 * @return: 
-->
<template>
  <div
    v-show="ready"
    class="el-carousel__item"
    :class="{
      'is-active': active,
      'el-carousel__item--card': $parent.type === 'card',
      'is-in-stage': inStage,
      'is-hover': hover,
      'is-animate': animate,
      'is-fade': fade,
      'is-gray': !active,
      'is-canimate': this.$parent.type === 'card' && this.$parent.loop && animate,
      'is-prev': this.$parent.type === 'card' && this.$parent.loop && isPrev,
      'is-next': this.$parent.type === 'card' && this.$parent.loop && isNext,
      'is-current': this.$parent.type === 'card' && this.$parent.loop && active
    }"
    @click="handleItemClick"
    :style="itemStyle"
  >
    <div
      v-if="$parent.type === 'card'"
      v-show="!active"
      class="el-carousel__mask"
    ></div>
    <slot></slot>
  </div>
</template>

<script>
import { autoprefixer } from "modesign-ui/src/utils/util";
const CARD_SCALE = 0.8;
export default {
  name: "ElCarouselItem",

  inject: ["ElCarousel"],

  props: {
    name: String,
    label: {
      type: [String, Number],
      default: "",
    },
    animation: {
      type: String,
      default: "",
      validator(val) {
        return ["fade", ""].indexOf(val) !== -1;
      },
    },
  },

  data() {
    return {
      isPrev: false,
      isNext: false,
      hover: false,
      translate: 0,
      scale: 1,
      active: false,
      ready: false,
      inStage: false,
      animate: false,
      fade: false,
      opacity: 1,
    };
  },

  methods: {
    getValidIndex(i, length) {
      const indexNumber = +i;
      return typeof indexNumber === 'number' && !Number.isNaN(indexNumber)
        ? (indexNumber + length) % length
        : i;
    },
    processIndex(index, activeIndex, length) {
      if (activeIndex === 0 && index === length - 1) {
        return -1;
      } else if (activeIndex === length - 1 && index === 0) {
        return length;
      } else if (index < activeIndex - 1 && activeIndex - index >= length / 2) {
        return length + 1;
      } else if (index > activeIndex + 1 && index - activeIndex >= length / 2) {
        return -2;
      }
      return index;
    },

    calcCardTranslate(index, activeIndex) {
      const parentWidth = this.$parent.$el.offsetWidth;
      if (this.inStage) {
        return (
          (parentWidth * ((2 - CARD_SCALE) * (index - activeIndex) + 1)) / 4
        );
      } else if (index < activeIndex) {
        return (-(1 + CARD_SCALE) * parentWidth) / 4;
      } else {
        return ((3 + CARD_SCALE) * parentWidth) / 4;
      }
    },

    calcTranslate(index, activeIndex, isVertical) {
      const distance =
        this.$parent.$el[isVertical ? "offsetHeight" : "offsetWidth"];
      return distance * (index - activeIndex);
    },

    translateItem(index, activeIndex, oldIndex) {
      const parentType = this.$parent.type;
      const parentDirection = this.parentDirection;
      const length = this.$parent.items.length;
      if (parentType !== "card" && oldIndex !== undefined) {
        //#region 原始写法
        // this.animate = index === activeIndex || index === oldIndex;
        //#endregion

        // 如果是滑动的动画，那么透明度设置为1，是否淡入淡出的class不添加
        // 如果是淡入淡出的动画，那么滑动的class不添加，当当前的为激活状态时透明度为1，否则为0
        if (this.animateType == "slide") {
          this.animate = index === activeIndex || index === oldIndex;
          this.fade = false;
          this.opacity = 1;
        } else {
          this.fade = index === activeIndex;
          this.animate = false;
          if (this.fade) {
            this.opacity = 1;
          } else {
            this.opacity = 0;
          }
        }
      }
      if (index !== activeIndex && length > 2 && this.$parent.loop) {
        index = this.processIndex(index, activeIndex, length);
      }
      if (parentType === "card") {
        this.isPrev = index === activeIndex - 1
        this.isNext = index === activeIndex + 1
        if (
          parentDirection === "vertical" ||
          parentDirection === "verticalLeft"
        ) {
          console.warn(
            "[Scrm Warn][Carousel]vertical direction is not supported in card mode"
          );
        }
        this.inStage = Math.round(Math.abs(index - activeIndex)) <= 1;
        this.active = index === activeIndex;
        this.translate = this.calcCardTranslate(index, activeIndex);
        this.scale = this.active ? 1 : CARD_SCALE;
      } else {
        this.active = index === activeIndex;
        const isVertical =
          parentDirection === "vertical" || parentDirection === "verticalLeft";
        this.translate = this.calcTranslate(index, activeIndex, isVertical);
        this.scale = 1;
      }
      this.ready = true;
    },

    handleItemClick() {
      const parent = this.$parent;
      if (parent && parent.type === "card") {
        const index = parent.items.indexOf(this);
        parent.setActiveItem(index);
      }
    },
  },

  computed: {
    parentDirection() {
      return this.$parent.direction;
    },

    itemStyle() {
      const translateType =
        this.$parent.type === 'card' ? "translateX" :
        this.parentDirection === "vertical" ||
        this.parentDirection === "verticalLeft"
          ? "translateY"
          : "translateX";
      const value = `${translateType}(${this.translate}px) scale(${this.scale})`;
      let style = {
        transform: value,
      };
      const parentType = this.$parent.type;
      if (parentType === 'card' && this.$parent.loop) {
        // style = {}
        if (!this.inStage) {
          style = {
            transform: 'translate(50%)scale(0.8)',
            opacity: 0
          }
        }
      }
      if (parentType !== "card") {
        style.opacity = 1;
      }
      if (this.animateType == "fade" && parentType !== "card") {
        style.opacity = this.opacity;
        style.transition = "opacity .5s ease";
      } else {
        style.transition = "";
      }
      return autoprefixer(style);
    },

    animateType() {
      return (this.ElCarousel || {}).animateType;
    },
  },

  watch: {
    animateType: {
      handler: function (val) {
        this.animate = val == "slide" ? true : false;
        this.fade = val == "fade" ? true : false;
      },
      immediate: true,
    },
  },

  created() {
    this.$parent && this.$parent.updateItems();
  },

  destroyed() {
    this.$parent && this.$parent.updateItems();
  },
};
</script>
