import { defineComponent, computed, provide, createVNode } from 'vue';
import { isFunction, isUndefined } from 'lodash-es';
import { useTheme } from '../_theme/useTheme';
import { useNormalModel } from '../_util/use/useModel';
import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../_util/constants';
import { COMPONENT_NAME, TransferStyle, TRANSFER_INJECT_KEY } from './const';
import { transferProps } from './props';
import OneWayTransfer from './oneWayTransfer';
import TwoWayTransfer from './twoWayTransfer';
import { defaultFilter, isTree } from './utils';

const Transfer = defineComponent({
  name: COMPONENT_NAME,
  props: transferProps,
  emits: [UPDATE_MODEL_EVENT, CHANGE_EVENT],
  slots: Object,
  setup: (props, _ref) => {
    let {
      emit,
      slots
    } = _ref;
    useTheme();
    const [modelValue] = useNormalModel(props, emit);
    const filter = computed(() => {
      if (isFunction(props.filter)) {
        return props.filter;
      }
      return defaultFilter;
    });
    const renderLabel = option => {
      if (slots.label) {
        return slots.label({
          option
        });
      }
      return option.label;
    };

    // 滚动部分的高度，决定是否开启虚拟滚动
    const scrollContentHeight = computed(() => {
      if (isUndefined(props.height)) {
        return null;
      }
      let contentHeight = props.height - TransferStyle.PANEL_PADDING * 2 - TransferStyle.PANEL_BLOCK_GAP - TransferStyle.PANEL_HEADER_HEIGHT;
      if (props.filterable) {
        contentHeight = contentHeight - TransferStyle.PANEL_BLOCK_GAP - TransferStyle.PANEL_FILTER_HEIGHT;
      }
      return contentHeight;
    });
    const rootStyle = computed(() => {
      return props.height ? {
        height: `${props.height}px`
      } : undefined;
    });
    const handleChange = changeValue => {
      emit(CHANGE_EVENT, changeValue);
    };
    provide(TRANSFER_INJECT_KEY, {
      modelValue,
      rootStyle,
      filter,
      renderLabel,
      handleChange,
      scrollContentHeight,
      rootProps: props
    });
    return () => {
      if (!props.twoWay) {
        return createVNode(OneWayTransfer, null, null);
      }
      if (isTree(props.options)) {
        console.warn(`[${COMPONENT_NAME}]: 双向穿梭框不允许使用树形结构`);
        return createVNode(OneWayTransfer, null, null);
      }
      return createVNode(TwoWayTransfer, null, null);
    };
  }
});

export { Transfer as default };
