<template>
  <span class="table-row-action">
    <template v-for="action in normalizedActions.normal">
      <el-tooltip
        v-if="action.tooltip"
        v-bind="{ effect: 'light', placement: 'top', ...(action.tooltipProps || {}) }"
        :key="action.tooltip"
        class="table-row-action-tooltip"
        :content="action.tooltip"
      >
        <MonitorComponent :monitor="action.monitor" :monitor-extra="{ row }">
          <el-button
            class="table-row-action-tooltip__button"
            v-bind="{ size: 'mini', ...action.buttonProps }"
            @click="handleClick(action)"
          ></el-button>
        </MonitorComponent>
      </el-tooltip>
      <MonitorComponent v-else :key="action.label" :monitor="action.monitor" :monitor-extra="{ row }">
        <el-button
          v-bind="{ size: 'mini', ...action.buttonProps }"
          :key="action.label"
          class="table-row-action-button"
          @click="handleClick(action)"
          >{{ action.label }}</el-button
        >
      </MonitorComponent>
    </template>
    <el-dropdown
      v-if="normalizedActions.group.length"
      class="table-row-action-group"
      v-bind="{ size: 'small', ...groupDropdownProps }"
    >
      <el-button class="table-row-action-group-link" size="mini" type="text"
        >{{ groupDropdownText }}<i class="el-icon-arrow-down el-icon--right"></i
      ></el-button>

      <el-dropdown-menu slot="dropdown">
        <MonitorComponent
          v-for="action in normalizedActions.group"
          :key="action.tooltip || action.label"
          :monitor-extra="{ row }"
          :monitor="action.monitor"
        >
          <el-dropdown-item :key="action.label" @click.native="handleClick(action)">
            <i v-if="action.buttonProps.icon" :class="action.buttonProps.icon" class="table-row-action-group-icon"></i>
            <span>{{ action.tooltip || action.label }}</span>
          </el-dropdown-item>
        </MonitorComponent>
      </el-dropdown-menu>
    </el-dropdown>
  </span>
</template>

<script>
import { MonitorComponent } from '@datago/monitor'
import { BUILT_IN_ROW_ACTIONS, formatAction, mergeActionProps } from './bridge'

export default {
  name: 'TableRowAction',
  components: { MonitorComponent },
  inject: ['tableRoot'],
  inheritAttrs: false,
  props: {
    $index: Number,
    row: {
      type: Object,
      default: () => ({}),
    },
    column: {
      type: Object,
      default: () => ({}),
    },
    actions: {
      type: Array,
      default: () => [],
    },
    grouped: {
      type: Number,
      default: 3,
    },
    groupDivided: {
      type: Boolean,
      default: true,
    },
    groupDropdownProps: {
      type: Object,
      default: () => ({}),
    },
    groupDropdownText: {
      type: String,
      default: '更多',
    },
  },
  computed: {
    normalizedActions() {
      const normal = []
      const group = []
      const dividerFirst = (options = []) => {
        if (!this.groupDivided) return options
        options[0] && (options[0].divided = true)
        return options
      }
      this.actions.forEach((action) => {
        const normalizedAction = this.normalizedAction(action)

        if (!normalizedAction) return

        if (!normalizedAction.group) {
          normal.push(normalizedAction)
        } else {
          group.push(normalizedAction)
        }
      })
      if (this.grouped && normal.length > this.grouped) {
        dividerFirst(group)
        group.unshift(...normal.splice(this.grouped, normal.length - this.grouped))
      }

      return { normal, group }
    },
  },
  methods: {
    async handleClick(action) {
      const { row, $index } = this
      const { handler, builtIn, onBefore, onAfter } = action || {}

      if (typeof onBefore === 'function') {
        await onBefore(action, this.row, this.$index)
      }

      const BUILT_IN_ACTION_MAP = {
        edit: () => this.tableRoot.showEditForm('update', this.row, this.$index),
        del: () => this.tableRoot.deleteRows([this.row]),
        detail: () => this.tableRoot.showEditForm('readonly', this.row, this.$index),
      }

      this.$emit('row-action-click', { action, row, $index })

      if (typeof handler === 'function') {
        await handler(action, row, $index)
      } else if (builtIn) {
        await (BUILT_IN_ACTION_MAP[builtIn] && BUILT_IN_ACTION_MAP[builtIn]())
      }

      if (typeof onAfter === 'function') {
        onAfter(action, this.row, this.$index)
      }
    },
    normalizedAction(action) {
      const { extraProps: extraPropsFunc, judge, extraPropsParams, render, renderPara, ...actionProps } = action
      if (typeof judge === 'function' && !judge(this.row)) return

      let extraProps = {}
      if (typeof render === 'function') {
        extraProps = formatAction(render(this.row, renderPara), false)
      } else if (typeof extraPropsFunc === 'function') {
        extraProps = extraPropsFunc(this.row, extraPropsParams)
      }

      const builtIn = extraProps.builtIn || actionProps.builtIn

      const builtInProps = BUILT_IN_ROW_ACTIONS[builtIn] || {}

      return mergeActionProps(builtInProps, actionProps, extraProps)
    },
  },
}
</script>
