<template>
    <div class="app-action-menu">
        <teleport to="body" v-if="type === 'contextmenu'">
            <div class="app-action-menu__contextmenu" @contextmenu.prevent.capture @click="closeContextmenu"
                v-show="contextmenuOptions.show">
                <ul :style="styles">
                    <li :class="item.className" v-for="(item, index) in actionMenus" :key="index"
                        @click.stop="onClick(item, index)">
                        <el-icon v-if="item.icon">
                            <component :is="item.icon" />
                        </el-icon>
                        <span>{{ item.label }}</span>
                    </li>
                </ul>
            </div>
        </teleport>
        <div class="app-action-menu__dropdown" v-else-if="type === 'dropdown'">
            <el-dropdown ref="dropdownRef" trigger="contextmenu" v-if="actionMenus.length > 1">
                <el-button-group>
                    <el-button size="small" round @click="onClick(actionMenus[0], 0)">{{
                        actionMenus[0].label
                    }}</el-button>
                    <el-button size="small" icon="ArrowDownBold" round @click="dropdownRef.handleOpen()" />
                </el-button-group>
                <template #dropdown>
                    <el-dropdown-menu>
                        <template v-for="(item, index) in actionMenus" :key="index">
                            <el-dropdown-item :class="item.className" :icon="item.icon"
                                @click.stop="onClick(item, index)" v-if="index > 0">
                                {{ item.label }}
                            </el-dropdown-item>
                        </template>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
            <el-button size="small" round @click="onClick(actionMenus[0], 0)" v-else-if="actionMenus.length">{{
                actionMenus[0].label
            }}</el-button>
        </div>
        <div class="app-action-menu__btnbar" v-else>
            <template v-for="(item, index) in actionMenus" :key="index">
                <el-button :class="item.className" :type="item.type" :disabled="item.disabled"
                    @click.stop="onClick(item, index)" :link="linkButton">
                    <el-icon v-if="item.icon">
                        <component :is="item.icon" />
                    </el-icon>
                    <span v-if="item.label">{{ item.label }}</span>
                </el-button>
            </template>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref, shallowRef, computed, PropType, watchEffect } from 'vue'
import { ActionMenu } from './interface'

const props = defineProps({
    // 操作菜单
    menus: {
        type: Array as PropType<Model.UserRoutes[]>,
        required: true,
    },
    // 操作类型
    type: {
        type: String as PropType<'button' | 'dropdown' | 'contextmenu'>,
        default: 'button',
    },
    // 右键菜单
    contextmenu: {
        type: Object as PropType<{ show: boolean; clientX: number; clientY: number; }>,
        default: () => ({
            show: false,
            clientX: 0,
            clientY: 0,
        }),
    },
    // 链接按钮
    linkButton: {
        type: Boolean,
        default: false,
    },
    record: Object,
})

const emit = defineEmits(['click'])
const contextmenuOptions = shallowRef(props.contextmenu)
const dropdownRef = ref()
const actionMenus = ref<ActionMenu[]>([])

// 右键菜单坐标
const styles = computed(() => {
    const { clientX, clientY } = contextmenuOptions.value
    return {
        left: clientX + 'px',
        top: clientY + 'px',
    }
})

// 关闭右键菜单
const closeContextmenu = () => {
    contextmenuOptions.value.show = false
}

const onClick = (item: ActionMenu, index: number) => {
    item.record = props.record
    closeContextmenu()
    emit('click', item, index)
}

watchEffect(() => {
    actionMenus.value = props.menus.map((e) => ({
        name: e.code,
        label: e.title,
        icon: e.icon,
        className: e.className,
        hide: e.hidden,
    }))
    contextmenuOptions.value = props.contextmenu
})
</script>

<style lang="less">
@import './index.less';
</style>