import isValid from "../_util/isValid";
import { defineComponent, Transition, h } from "vue";

function get(num, origin) {
  let size = typeof num === 'function' ? num(origin) : num;
  return size + 'px';
}

const ExpandTransition = defineComponent({
  name: 'x-expand-transition',
  props: {
    height: {
      type: [Number, Function],
      default: 0
    },
    width: [Number, Function]
  },

  setup(props, {
    slots
  }) {
    function onEnter(el) {
      const height = el.scrollHeight,
            width = el.scrollWidth;
      el.style.transition = `none`;
      if (isValid(props.height)) el.style.maxHeight = get(props.height, height);
      if (isValid(props.width)) el.style.maxWidth = get(props.width, width);
      void el.offsetWidth;
      el.style.transition = ``;
      if (isValid(props.height)) el.style.maxHeight = `${height}px`;
      if (isValid(props.width)) el.style.maxWidth = `${width}px`;
      void el.offsetWidth;
    }

    function onAfterEnter(el) {
      el.style.maxHeight = ``;
      el.style.maxWidth = ``;
    }

    function onBeforeLeave(el) {
      if (isValid(props.height)) el.style.maxHeight = `${el.scrollHeight}px`;
      if (isValid(props.width)) el.style.maxWidth = `${el.scrollWidth}px`;
      void el.offsetWidth;
    }

    function onLeave(el) {
      const height = el.scrollHeight,
            width = el.scrollWidth;
      if (isValid(props.height)) el.style.maxHeight = get(props.height, height);
      if (isValid(props.width)) el.style.maxWidth = get(props.width, width);
      void el.offsetWidth;
    }

    function onAfterLeave(el) {
      el.style.maxHeight = ``;
      el.style.maxWidth = ``;
    }

    const mProps = {
      name: 'expand-transition',
      onEnter,
      onAfterEnter,
      onBeforeLeave,
      onLeave,
      onAfterLeave
    };
    return () => {
      return h(Transition, mProps, slots);
    };
  }

});

ExpandTransition.install = app => {
  app.component(ExpandTransition.name, ExpandTransition);
};

export default ExpandTransition;