<template>
  <div class="ecp-table-action">
    <!-- 主操作按钮组 -->
    <span
      v-for="(action, index) in visibleActions"
      :key="`action-${index}`"
      class="ecp-table-action__item"
    >
      <!-- 气泡确认 -->
      <el-popconfirm
        v-if="action.popConfirm"
        :title="action.popConfirm.title"
        :confirm-button-text="action.popConfirm.okText || '确定'"
        :cancel-button-text="action.popConfirm.cancelText || '取消'"
        @confirm="handlePopConfirmConfirm(action, $event)"
        @cancel="handlePopConfirmCancel(action, $event)"
      >
        <span slot="reference">
          <component
            :is="action.tooltip ? 'el-tooltip' : 'span'"
            v-bind="action.tooltip ? normalizeTooltip(action.tooltip) : {}"
          >
            <el-button
              :type="getButtonType(action)"
              size="small"
              :disabled="action.disabled"
              v-bind="action.props"
               @click="handleActionClick(action, $event)"
            >
              <i v-if="action.icon" :class="['ecp-table-action__icon', action.icon]" />
              <span>{{ action.label }}</span>
            </el-button>
          </component>
        </span>
      </el-popconfirm>

      <!-- 普通按钮 -->
      <component
        v-else
        :is="action.tooltip ? 'el-tooltip' : 'span'"
        v-bind="action.tooltip ? normalizeTooltip(action.tooltip) : {}"
      >
        <el-button
          :type="getButtonType(action)"
          size="small"
          :disabled="action.disabled"
          v-bind="action.props"
          @click="handleActionClick(action, $event)"
        >
          <i v-if="action.icon" :class="['ecp-table-action__icon', action.icon]" />
          <span>{{ action.label }}</span>
        </el-button>
      </component>

      <el-divider v-if="action.divider" direction="vertical" />
    </span>

    <!-- 下拉更多操作 -->
    <el-dropdown v-if="visibleDropDownActions.length" trigger="click" @command="handleDropdownCommand">
      <span class="ecp-table-action__more">
        <el-button type="text" size="small">
          更多<i class="el-icon-arrow-down el-icon--right" />
        </el-button>
      </span>
      <el-dropdown-menu slot="dropdown">
        <el-dropdown-item
          v-for="(action, index) in visibleDropDownActions"
          :key="`dropdown-${index}`"
          :command="index"
          :disabled="action.disabled"
          :divided="!!action.divider"
        >
          <span class="ecp-table-action__dropdown-item">
            <i v-if="action.icon" :class="['ecp-table-action__icon', action.icon]" />
            <span>{{ action.label }}</span>
          </span>
        </el-dropdown-item>
      </el-dropdown-menu>
    </el-dropdown>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { MessageBox } from 'element-ui'
import type { TableActionItem } from './types'
import { normalizeTooltipConfig } from '../utils/tooltip'

const props = withDefaults(
  defineProps<{
    actions?: TableActionItem[]
    dropDownActions?: TableActionItem[]
    /** 是否阻止按钮 click 冒泡，参考 VbenAdmin stopButtonPropagation */
    stopButtonPropagation?: boolean
  }>(),
  {
    actions: () => [],
    dropDownActions: () => [],
    stopButtonPropagation: false,
  }
)

const normalizeTooltip = (tooltip?: TableActionItem['tooltip']) => {
  return normalizeTooltipConfig(tooltip) || {}
}

const getButtonType = (action: TableActionItem) => {
  if (action.type) return action.type
  if (action.color === 'error') return 'danger'
  if (action.color === 'success') return 'success'
  if (action.color === 'warning') return 'warning'
  return 'text'
}

const filterVisible = (list: TableActionItem[]) =>
  list.filter((item) => {
    const { ifShow } = item
    if (typeof ifShow === 'boolean') return ifShow
    if (typeof ifShow === 'function') return ifShow(item)
    return true
  })

const visibleActions = computed(() => filterVisible(props.actions || []))
const visibleDropDownActions = computed(() => filterVisible(props.dropDownActions || []))

const showPopConfirmAsMessageBox = (config: NonNullable<TableActionItem['confirm']>) => {
  return MessageBox.confirm(config.title, config.boxTitle || '提示', {
    confirmButtonText: config.okText || '确定',
    cancelButtonText: config.cancelText || '取消',
    type: config.type || 'warning',
  })
    .then(() => config.confirm?.())
    .catch(() => config.cancel?.())
}

const handleClick = (action: TableActionItem, e: MouseEvent) => {
  if (props.stopButtonPropagation) {
    e.stopPropagation()
  }
  if (action?.confirm) {
    showPopConfirmAsMessageBox(action.confirm)
    return
  }
  action.onClick?.(e)
}

const handleActionClick = (action: TableActionItem, e: MouseEvent) => {
  handleClick(action, e)
}

const handlePopConfirm = (action: TableActionItem, type: 'confirm' | 'cancel', e: MouseEvent) => {
  if (props.stopButtonPropagation) {
    e.stopPropagation()
  }
  if (!action.popConfirm) return
  if (type === 'confirm') {
    action.popConfirm.confirm?.()
  } else {
    action.popConfirm.cancel?.()
  }
}

const handlePopConfirmConfirm = (action: TableActionItem, e: MouseEvent) => {
  handlePopConfirm(action, 'confirm', e)
}

const handlePopConfirmCancel = (action: TableActionItem, e: MouseEvent) => {
  handlePopConfirm(action, 'cancel', e)
}

const handleDropdownCommand = (index: number | string) => {
  const idx = Number(index)
  const action = visibleDropDownActions.value[idx]
  if (!action || action.disabled) return
  if (action.popConfirm) {
    const title = action.popConfirm.title
    const okText = action.popConfirm.okText || '确定'
    const cancelText = action.popConfirm.cancelText || '取消'
    MessageBox.confirm(title, '提示', {
      confirmButtonText: okText,
      cancelButtonText: cancelText,
      type: 'warning',
    })
      .then(() => action.popConfirm?.confirm?.())
      .catch(() => action.popConfirm?.cancel?.())
    return
  }
  action.onClick?.({} as MouseEvent)
}
</script>

<style>
.ecp-table-action {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.ecp-table-action__item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.ecp-table-action__icon {
  margin-right: 4px;
}
.ecp-table-action__more {
  display: inline-flex;
  align-items: center;
}
.ecp-table-action__dropdown-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
</style>
