<script>
import { columnProps } from './util/props'
import { cellDefaults } from './util/config'
import { getDefaultColumn, parseWidth } from './util/util'
let columnIdSeed = 0

export default {
  name: 'xTableColumns',
  props: columnProps,
  computed: {
    owner() {
      let parent = this.$parent
      while (parent && !parent.tableId) {
        parent = parent.$parent
      }
      return parent
    },
    columnOrTableParent() {
      let parent = this.$parent
      while (parent && !parent.tableId && !parent.columnId) {
        parent = parent.$parent
      }
      return parent
    }
  },
  beforeCreate() {
    this.columnConfig = {}
    this.columnId = ''
  },
  created() {
    const { owner, columnOrTableParent: parent } = this
    this.isSubColumn = owner !== parent
    this.columnId = (parent.tableId || parent.columnId) + '_column_' + columnIdSeed++

    cellDefaults.default.minWidth = this.owner.defaultColumnWidth
    this.columnConfig = getDefaultColumn(this.type, {
      id: this.columnId,
      type: this.type,
      label: this.label,
      prop: this.prop,
      width: this.width,
      minWidth: parseWidth(this.minWidth),
      fixed: this.isSubColumn ? parent.fixed : this.fixed,
      sortable: this.sortable === '' ? true : this.sortable,
      sortMethod: this.sortMethod,
      sortOrders: this.sortOrders,
      resizable: this.resizable,
      formatter: this.formatter,
      align: this.headerAlign || this.align,
      headerAlign: this.headerAlign,
      isExpandKey: this.isExpandKey,
      parent: parent.columnConfig,
      destroyed: false
    })

    // 注册 watcher
    this.registerWatchers()
  },
  mounted() {
    const { owner, columnOrTableParent: parent, isSubColumn, $scopedSlots, columnConfig, type } = this
    const children = isSubColumn ? parent.$el.children : parent.$refs.hiddenContent.children
    const columnIndex = [].indexOf.call(children, this.$el)

    // 展开行
    if ($scopedSlots.expand) {
      owner.expendRender = (h, scope) => $scopedSlots.expand(scope)
      columnConfig.width = 40
      columnConfig.minWidth = 40
    }

    // 表头前置插槽
    if ($scopedSlots.prepend) {
      columnConfig.prependHeader = (h, scope) => $scopedSlots.prepend(scope)
    }

    // 表头后置插槽
    if ($scopedSlots.append) {
      columnConfig.appendHeader = (h, scope) => $scopedSlots.append(scope)
    }

    // 自定义表头
    if ($scopedSlots.header) {
      if (type === 'selection') {
        throw new Error('Table Column: Selection column doesn\'t allow to set scoped-slot header.')
      } else {
        columnConfig.customHeader = (h, scope) => $scopedSlots.header(scope)
      }
    }

    // 表头文本插槽
    if ($scopedSlots.headerText) {
      columnConfig.headerText = (h, scope) => $scopedSlots.headerText(scope)
    }

    // 自定义列
    if ($scopedSlots.content) {
      columnConfig.customRender = (h, scope) => $scopedSlots.content(scope)
    }

    // 树结构文本插槽
    if ($scopedSlots.treeText) {
      columnConfig.treeText = (h, scope) => $scopedSlots.treeText(scope)
    }

    owner.store.commit('insertColumn', this.columnConfig, columnIndex, isSubColumn ? parent.columnConfig : null)
  },
  beforeDestroy() {
    if (!this.$parent) return
    const parent = this.$parent
    this.columnConfig.destroyed = true
    this.owner.store.commit('removeColumn', this.columnConfig, this.isSubColumn ? parent.columnConfig : null)
  },
  methods: {
    registerWatchers() {
      const props = ['label', 'sortable', 'formatter', 'fixed']
      // 一些属性具有别名
      const aliases = {
        width: 'currentWidth'
      }
      const allAliases = props.reduce((prev, cur) => {
        prev[cur] = cur
        return prev
      }, aliases)

      Object.keys(allAliases).forEach(key => {
        const columnKey = aliases[key]

        this.$watch(key, (newVal) => {
          this.columnConfig[columnKey] = newVal
          this.owner.updateColumns(this.columnConfig, true)
        })
      })
    }
  },
  render(createElement) {
    return createElement('div', this.$slots.default)
  }
}
</script>
