import { getCurrentInstance, h, ref, computed, watchEffect } from 'vue'
import { cellForced, defaultRenderCell, treeCellPrefix } from '../config'
import { parseWidth, parseMinWidth } from '../util'

function useRender(props, slots, owner) {
  const instance = getCurrentInstance()
  const columnId = ref('')
  const isSubColumn = ref(false)
  const realAlign = ref()
  const realHeaderAlign = ref()
  watchEffect(() => {
    realAlign.value = props.align ? 'is-' + props.align : null
    // nextline help render
    realAlign.value
  })
  watchEffect(() => {
    realHeaderAlign.value = props.headerAlign
      ? 'is-' + props.headerAlign
      : realAlign.value
    // nextline help render
    realHeaderAlign.value
  })
  const columnOrTableParent = computed(() => {
    let parent = instance.vnode.vParent || instance.parent
    while (parent && !parent.tableId && !parent.columnId) {
      parent = parent.vnode.vParent || parent.parent
    }
    return parent
  })

  const realWidth = ref(parseWidth(props.width))
  const realMinWidth = ref(parseMinWidth(props.minWidth))
  const setColumnWidth = (column) => {
    if (realWidth.value) column.width = realWidth.value
    if (realMinWidth.value) {
      column.minWidth = realMinWidth.value
    }
    if (!column.minWidth) {
      column.minWidth = 80
    }
    column.realWidth =
      column.width === undefined ? column.minWidth : column.width
    return column
  }
  const setColumnForcedProps = (column) => {
    // 对于特定类型的 column，某些属性不允许设置
    const type = column.type
    const source = cellForced[type] || {}
    Object.keys(source).forEach((prop) => {
      const value = source[prop]
      if (value !== undefined) {
        column[prop] = prop === 'className' ? `${column[prop]} ${value}` : value
      }
    })
    return column
  }

  const checkSubColumn = (children) => {
    if (children instanceof Array) {
      children.forEach((child) => check(child))
    } else {
      check(children)
    }
    function check(item) {
      if (item?.type?.name === 'ElTableColumn') {
        item.vParent = instance
      }
    }
  }
  const setColumnRenders = (column) => {
    // renderHeader 属性不推荐使用。
    if (props.renderHeader) {
      console.warn(
        '[Element Warn][TableColumn]Comparing to render-header, scoped-slot header is easier to use. We recommend users to use scoped-slot header.'
      )
    } else if (column.type !== 'selection') {
      column.renderHeader = (scope) => {
        // help render
        instance.columnConfig.value['label']
        const renderHeader = slots.header
        return renderHeader ? renderHeader(scope) : column.label
      }
    }

    let originRenderCell = column.renderCell
    // TODO: 这里的实现调整
    if (column.type === 'expand') {
      // 对于展开行，renderCell 不允许配置的。在上一步中已经设置过，这里需要简单封装一下。
      column.renderCell = (data) =>
        h(
          'div',
          {
            class: 'cell'
          },
          [originRenderCell(data)]
        )
      owner.value.renderExpanded = (data) => {
        return slots.default ? slots.default(data) : slots.default
      }
    } else {
      originRenderCell = originRenderCell || defaultRenderCell
      // 对 renderCell 进行包装
      column.renderCell = (data) => {
        let children = null
        if (slots.default) {
          children = slots.default(data)
        } else {
          children = originRenderCell(data)
        }
        const prefix = treeCellPrefix(data)
        const props = {
          class: 'cell',
          style: {}
        }
        if (column.showOverflowTooltip) {
          props.class += ' el-tooltip'
          props.style = {
            width: (data.column.realWidth || data.column.width) - 1 + 'px'
          }
        }
        checkSubColumn(children)
        return h('div', props, [prefix, children])
      }
    }
    return column
  }
  const getPropsData = (...propsKey) => {
    return propsKey.reduce((prev, cur) => {
      if (Array.isArray(cur)) {
        cur.forEach((key) => {
          prev[key] = props[key]
        })
      }
      return prev
    }, {})
  }
  const getColumnElIndex = (children, child) => {
    return [].indexOf.call(children, child)
  }

  return {
    columnId,
    realAlign,
    isSubColumn,
    realHeaderAlign,
    columnOrTableParent,
    setColumnWidth,
    setColumnForcedProps,
    setColumnRenders,
    getPropsData,
    getColumnElIndex
  }
}

export default useRender
