import { defineComponent, getCurrentInstance, ref, inject, reactive, onMounted, onUnmounted, withDirectives, createVNode, vShow, computed } from 'vue';
import { useTheme } from '../_theme/useTheme';
import { CAROUSEL_ITEM_NAME, provideKey, CAROUSEL_NAME, CARD_SCALE } from './const';
import { carouselItemProps } from './interface';

const useItemStyle = direction => {
  const itemStyleState = reactive({
    translate: 0,
    scale: 1
  });
  const itemStyle = computed(() => {
    const translateType = direction.value === 'vertical' ? 'translateY' : 'translateX';
    const value = `${translateType}(${itemStyleState.translate}px) scale(${itemStyleState.scale}, ${itemStyleState.scale})`;
    const style = {
      transform: value
    };
    return style;
  });
  const setItemStyle = (translate, scale) => {
    itemStyleState.translate = translate;
    if (scale) {
      itemStyleState.scale = scale;
    }
  };
  return {
    itemStyle,
    setItemStyle
  };
};
var carouselItem = defineComponent({
  name: CAROUSEL_ITEM_NAME,
  props: carouselItemProps,
  setup(props, _ref) {
    let {
      slots
    } = _ref;
    useTheme();
    const instance = getCurrentInstance();
    const slideRef = ref(null);
    const {
      prefixCls,
      direction,
      wrapperRef,
      rootProps,
      slideChildren,
      setActiveItem,
      addItem,
      removeItem
    } = inject(provideKey);
    const {
      itemStyle,
      setItemStyle
    } = useItemStyle(direction);
    function processIndex(index, activeIndex, length) {
      if (activeIndex === 0 && index === length - 1) {
        return -1;
      }
      if (activeIndex === length - 1 && index === 0) {
        return length;
      }
      if (index < activeIndex - 1 && activeIndex - index >= length / 2) {
        return length + 1;
      }
      if (index > activeIndex + 1 && index - activeIndex >= length / 2) {
        return -2;
      }
      return index;
    }
    const itemStatus = reactive({
      hover: false,
      active: false,
      inStage: false,
      animating: false
    });
    function calcCardTranslate(index, activeIndex) {
      var _wrapperRef$value;
      const parentWidth = ((_wrapperRef$value = wrapperRef.value) === null || _wrapperRef$value === void 0 ? void 0 : _wrapperRef$value.offsetWidth) || 0;
      if (itemStatus.inStage) {
        return parentWidth * ((2 - CARD_SCALE) * (index - activeIndex) + 1) / 4;
      }
      if (index < activeIndex) {
        return -(1 + CARD_SCALE) * parentWidth / 4;
      }
      return (3 + CARD_SCALE) * parentWidth / 4;
    }
    function calcTranslate(index, activeIndex, isVertical) {
      var _wrapperRef$value2, _wrapperRef$value3;
      const distance = (isVertical ? (_wrapperRef$value2 = wrapperRef.value) === null || _wrapperRef$value2 === void 0 ? void 0 : _wrapperRef$value2.offsetHeight : (_wrapperRef$value3 = wrapperRef.value) === null || _wrapperRef$value3 === void 0 ? void 0 : _wrapperRef$value3.offsetWidth) || 0;
      return distance * (index - activeIndex);
    }
    const itemReady = ref(false);
    const translateItem = (index, activeIndex, oldIndex) => {
      const length = slideChildren.value.length;
      if (rootProps.type !== 'card' && oldIndex !== undefined) {
        itemStatus.animating = index === activeIndex || index === oldIndex;
      }
      if (index !== activeIndex && length > 2 && rootProps.loop) {
        index = processIndex(index, activeIndex, length);
      }
      if (rootProps.type === 'card') {
        if (direction.value === 'vertical') {
          console.warn(`[${CAROUSEL_ITEM_NAME}]: ${CAROUSEL_NAME} vertical direction is not supported in card mode.`);
        }
        itemStatus.inStage = Math.round(Math.abs(index - activeIndex)) <= 1;
        itemStatus.active = index === activeIndex;
        setItemStyle(calcCardTranslate(index, activeIndex), itemStatus.active ? 1 : CARD_SCALE);
      } else {
        itemStatus.active = index === activeIndex;
        const isVertical = direction.value === 'vertical';
        setItemStyle(calcTranslate(index, activeIndex, isVertical));
      }
      itemReady.value = true;
    };
    const onClickSlide = () => {
      if (rootProps.type === 'card') {
        const index = slideChildren.value.map(item => item.uid).indexOf(instance.uid);
        setActiveItem(index);
      }
    };
    onMounted(() => {
      addItem({
        uid: instance.uid,
        itemkey: props.itemkey,
        states: itemStatus,
        translateItem
      });
    });
    onUnmounted(() => {
      removeItem(instance.uid);
    });
    return () => {
      var _slots$default;
      return withDirectives(createVNode("div", {
        "ref": slideRef,
        "class": {
          [`${prefixCls}-item`]: true,
          [`${prefixCls}-item-card`]: rootProps.type === 'card',
          'is-in-stage': itemStatus.inStage,
          'is-hover': itemStatus.hover,
          'is-active': itemStatus.active,
          'is-animating': itemStatus.animating
        },
        "style": itemStyle.value,
        "onClick": onClickSlide
      }, [rootProps.type === 'card' && withDirectives(createVNode("div", {
        "class": `${prefixCls}-item-mask`
      }, null), [[vShow, !itemStatus.active]]), (_slots$default = slots.default) === null || _slots$default === void 0 ? void 0 : _slots$default.call(slots)]), [[vShow, itemReady.value]]);
    };
  }
});

export { carouselItem as default };
