import { defineComponent, computed, createVNode, Fragment } from 'vue';
import { useTheme } from '../_theme/useTheme';
import { timelineProps } from './props';
import { COMPONENT_NAME, prefixCls } from './const';
import { cls, calcTitlePosition, calcDescPosition, getTitleOppositePosition } from './utils';
import { useCustomIcons } from './useCustomIcons';
import Icon from './icon';

/** 渲染标题、辅助描述 */
const renderNodeContent = _ref => {
  let {
    title,
    titlePosition,
    descPosition,
    desc,
    titleClass,
    descClass,
    appendantStyle,
    titleWidth,
    direction
  } = _ref;
  const titleElement = createVNode("div", {
    "class": [cls('item-title'), cls(`item-title-layout-${titlePosition}`), titleClass]
  }, [title]);
  const descElement = desc ? createVNode("div", {
    "class": [cls('item-desc'), cls(`item-desc-layout-${descPosition}`), descClass]
  }, [desc]) : undefined;

  // 标题、辅助描述同侧
  if (descPosition !== 'opposite') {
    return createVNode("div", {
      "class": [cls('item-content-wrapper'), cls(`item-content-wrapper-${titlePosition}`)],
      "style": appendantStyle
    }, [titleElement, descElement]);
  }

  // 标题、辅助描述分侧
  return createVNode(Fragment, null, [createVNode("div", {
    "class": [cls('item-content-wrapper'), cls(`item-content-wrapper-${titlePosition}`)],
    "style": [appendantStyle, direction === 'column' && descPosition === 'opposite' && titleWidth && {
      width: titleWidth
    }]
  }, [titleElement]), descElement && createVNode("div", {
    "class": [cls('item-content-wrapper'), cls(`item-content-wrapper-${getTitleOppositePosition(titlePosition)}`)],
    "style": appendantStyle
  }, [descElement])]);
};
const renderNode = nodeProps => {
  const {
    node,
    index,
    props,
    slots,
    nodeAppendantStyleMap
  } = nodeProps;
  const {
    direction,
    titlePosition,
    descPosition,
    titleClass,
    descClass
  } = props;
  const {
    title,
    desc,
    icon
  } = node;
  const calculatedTitlePosition = calcTitlePosition(index, titlePosition, node.titlePosition);
  const calculatedDescPosition = calcDescPosition(direction, descPosition);
  let descContent;
  // prop 的渲染函数优先级高于插槽
  if (slots.desc) {
    descContent = slots.desc({
      index,
      item: props.data[index]
    });
  } else if (typeof desc === 'function') {
    descContent = desc({
      index,
      item: props.data[index]
    });
  } else {
    descContent = desc;
  }

  // prop 的渲染函数优先级高于插槽
  let titleContent;
  if (slots.title) {
    titleContent = slots.title({
      index,
      item: props.data[index]
    });
  } else if (typeof title === 'function') {
    titleContent = title({
      index,
      item: props.data[index]
    });
  } else {
    titleContent = title;
  }
  const appendantStyle = nodeAppendantStyleMap.value.get(index);
  return createVNode("li", {
    "class": [cls('item'), cls(`item-layout-${calculatedTitlePosition}`)],
    "key": index
  }, [createVNode("div", {
    "class": [cls('item-tail'), index === props.data.length - 1 && cls('item-tail-last')],
    "style": [appendantStyle === null || appendantStyle === void 0 ? void 0 : appendantStyle.tail, props.direction === 'column' && descPosition === 'opposite' && props.titleWidth && {
      left: props.titleWidth
    }]
  }, null), renderNodeContent({
    title: titleContent,
    titleClass,
    descClass,
    titlePosition: calculatedTitlePosition,
    descPosition: calculatedDescPosition,
    desc: descContent,
    appendantStyle: appendantStyle === null || appendantStyle === void 0 ? void 0 : appendantStyle.content,
    titleWidth: props.titleWidth,
    direction: props.direction
  }), createVNode(Icon, {
    "key": index,
    "index": index,
    "icon": icon,
    "data": props.data,
    "style": [props.direction === 'column' && descPosition === 'opposite' && props.titleWidth && {
      left: props.titleWidth
    }],
    "slotRender": slots.icon
  }, null)]);
};
var timeline = defineComponent({
  name: COMPONENT_NAME,
  props: timelineProps,
  slots: Object,
  setup: (props, _ref2) => {
    let {
      slots
    } = _ref2;
    useTheme();
    const {
      nodeAppendantStyleMap
    } = useCustomIcons(props.direction, props.data);
    const classList = computed(() => [prefixCls, cls(`direction-${props.direction}`), cls(`layout-${props.titlePosition}`), cls(`desc-${props.descPosition}`)]);
    return () => createVNode("ul", {
      "class": classList.value
    }, [props.data.map((node, index) => renderNode({
      node,
      index,
      props,
      slots,
      nodeAppendantStyleMap
    }))]);
  }
});

export { timeline as default };
