<template>
    <!-- 遮罩层 -->
    <view v-if="visible" class="im-message-action-mask" :class="{ 'im-message-action-mask--show': showMask }"
        @click="close" @touchmove.prevent />

    <!-- 操作菜单 -->
    <view v-if="visible" class="im-message-action" :class="[
        `im-message-action--${position}`,
        `im-message-action--${theme}`,
        {
            'im-message-action--show': showMenu
        }
    ]" :style="menuStyle" @touchmove.stop>
        <!-- 操作项列表 -->
        <scroll-view v-if="actions.length > 0" class="im-message-action__list" scroll-y :show-scrollbar="false">
            <view v-for="(action, index) in filteredActions" :key="action.key || index" class="im-message-action__item"
                :class="[
                    `im-message-action__item--${action.type || 'default'}`,
                    {
                        'im-message-action__item--disabled': action.disabled,
                        'im-message-action__item--danger': action.danger,
                        'im-message-action__item--divider': action.divider
                    }
                ]" @click="handleItemClick(action)">
                <!-- 分隔线 -->
                <view v-if="action.divider" class="im-message-action__divider"></view>

                <!-- 正常操作项 -->
                <template v-else>
                    <!-- 图标 -->
                    <view class="im-message-action__icon" v-if="action.icon">
                        <im-icon :name="action.icon" :size="iconSize" :color="getIconColor(action)"
                            :spin="action.loading" />
                    </view>

                    <!-- 文本 -->
                    <text class="im-message-action__text" :style="{ color: getTextColor(action) }">
                        {{ action.text }}
                    </text>

                    <!-- 角标/提示 -->
                    <view v-if="action.badge || action.hint" class="im-message-action__extra">
                        <im-badge v-if="action.badge" :content="action.badge" :type="action.badgeType || 'danger'"
                            size="small" />
                        <text v-else-if="action.hint" class="im-message-action__hint">
                            {{ action.hint }}
                        </text>
                    </view>
                </template>
            </view>
        </scroll-view>

        <!-- 自定义内容插槽 -->
        <slot v-else></slot>

        <!-- 取消按钮 -->
        <view v-if="showCancel" class="im-message-action__cancel" @click="handleCancel">
            <text class="im-message-action__cancel-text">{{ cancelText }}</text>
        </view>

        <!-- 三角形箭头 -->
        <view v-if="showArrow && position.includes('top')" class="im-message-action__arrow" :style="arrowStyle"></view>
    </view>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import ImIcon from '../im-icon/im-icon.vue'
import ImBadge from '../im-badge/im-badge.vue'
import type { MessageActionItem, MessageActionProps, MessageActionEmits } from '../../types/components/message-action'

const props = withDefaults(defineProps<MessageActionProps>(), {
    visible: false,
    position: 'bottom',
    theme: 'light',
    actions: () => [],
    showCancel: true,
    cancelText: '取消',
    maxHeight: '400rpx',
    width: '300rpx',
    borderRadius: '16rpx',
    showArrow: true,
    arrowSize: 12,
    iconSize: 20,
    x: 0,
    y: 0,
    offsetX: 0,
    offsetY: 10,
    fitViewport: true,
    animation: true,
    animationDuration: 300,
    showMask: true,
    maskClosable: true,
    maskColor: 'rgba(0, 0, 0, 0.5)'
})

const emit = defineEmits<MessageActionEmits>()

// 响应式数据
const showMenu = ref(false)
const showMask = ref(false)
const menuRect = ref({ width: 0, height: 0 })
const viewportRect = ref({ width: 0, height: 0 })
const adjustedPosition = ref('bottom')

// 计算属性
const filteredActions = computed(() => {
    return props.actions.filter(action => !action.hidden)
})

const menuStyle = computed(() => {
    const style: Record<string, string> = {
        '--max-height': typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight,
        '--width': typeof props.width === 'number' ? `${props.width}px` : props.width,
        '--border-radius': typeof props.borderRadius === 'number' ? `${props.borderRadius}px` : props.borderRadius,
        '--animation-duration': `${props.animationDuration}ms`
    }

    // 动态位置
    const positionStyle = getPositionStyle()
    Object.assign(style, positionStyle)

    return style
})

const arrowStyle = computed(() => {
    const style: Record<string, string> = {
        '--arrow-size': `${props.arrowSize}px`
    }

    if (props.position.includes('top')) {
        style.bottom = `-${props.arrowSize}px`
    } else {
        style.top = `-${props.arrowSize}px`
    }

    // 箭头位置对齐
    if (props.position.includes('left')) {
        style.left = '20rpx'
    } else if (props.position.includes('right')) {
        style.right = '20rpx'
    } else {
        style.left = '50%'
        style.transform = 'translateX(-50%)'
    }

    return style
})

// 方法
const getPositionStyle = () => {
    const style: Record<string, string> = {}
    const { x, y, offsetX, offsetY } = props

    // 获取视口尺寸
    const getViewportSize = () => {
        const systemInfo = uni.getSystemInfoSync()
        return {
            width: systemInfo.windowWidth,
            height: systemInfo.windowHeight
        }
    }

    if (!viewportRect.value.width) {
        viewportRect.value = getViewportSize()
    }

    let finalX = x + offsetX
    let finalY = y + offsetY

    // 适应视口边界
    if (props.fitViewport && menuRect.value.width > 0) {
        // 检查右侧边界
        if (finalX + menuRect.value.width > viewportRect.value.width) {
            finalX = viewportRect.value.width - menuRect.value.width - 10
        }

        // 检查左侧边界
        if (finalX < 10) {
            finalX = 10
        }

        // 检查底部边界（如果是top位置）
        if (props.position.includes('top') && finalY + menuRect.value.height > viewportRect.value.height) {
            // 如果超出底部，切换到bottom位置
            adjustedPosition.value = props.position.replace('top', 'bottom')
            finalY = y - offsetY - menuRect.value.height
        }

        // 检查顶部边界（如果是bottom位置）
        if (props.position.includes('bottom') && finalY - menuRect.value.height < 0) {
            // 如果超出顶部，切换到top位置
            adjustedPosition.value = props.position.replace('bottom', 'top')
            finalY = y + offsetY
        }
    }

    // 设置位置
    if (props.position.includes('left')) {
        style.left = `${finalX}px`
    } else if (props.position.includes('right')) {
        style.right = `${viewportRect.value.width - finalX}px`
    } else {
        style.left = '50%'
        style.transform = `translateX(-50%)`
        style.top = `${finalY}px`
    }

    if (props.position.includes('top')) {
        style.top = `${finalY}px`
    } else if (props.position.includes('bottom')) {
        style.bottom = `${viewportRect.value.height - finalY}px`
    }

    return style
}

const getIconColor = (action: MessageActionItem): string => {
    if (action.disabled) return '#C0C4CC'

    switch (action.type) {
        case 'primary': return '#409EFF'
        case 'success': return '#67C23A'
        case 'warning': return '#E6A23C'
        case 'danger': return '#F56C6C'
        case 'info': return '#909399'
        default: return '#606266'
    }
}

const getTextColor = (action: MessageActionItem): string => {
    if (action.disabled) return '#C0C4CC'
    if (action.danger) return '#F56C6C'

    switch (action.type) {
        case 'primary': return '#409EFF'
        case 'success': return '#67C23A'
        case 'warning': return '#E6A23C'
        case 'danger': return '#F56C6C'
        case 'info': return '#909399'
        default: return '#303133'
    }
}

const handleItemClick = async (action: MessageActionItem) => {
    if (action.disabled || action.loading) return

    // 触发选择事件
    emit('select', action, props.message)
    emit('click', action.key, props.message)

    // 执行自定义处理器
    if (action.handler) {
        try {
            await action.handler()
        } catch (error) {
            console.error('Action handler error:', error)
        }
    }

    // 非持续显示的操作项，执行后关闭
    if (!action.loading) {
        close()
    }
}

const handleCancel = () => {
    emit('cancel')
    close()
}

const open = () => {
    if (props.visible) return

    emit('before-open')
    emit('update:visible', true)

    nextTick(() => {
        setTimeout(() => {
            showMask.value = true
            showMenu.value = true
            emit('open')
            emit('after-open')
        }, 50)
    })
}

const close = () => {
    if (!props.visible) return

    emit('before-close')
    showMenu.value = false
    showMask.value = false

    setTimeout(() => {
        emit('update:visible', false)
        emit('close')
        emit('after-close')
        adjustedPosition.value = props.position
    }, props.animationDuration)
}

const updatePosition = (x: number, y: number) => {
    // 更新位置的方法
    // const { offsetX, offsetY } = props

    // 重新计算位置
    const systemInfo = uni.getSystemInfoSync()
    viewportRect.value = {
        width: systemInfo.windowWidth,
        height: systemInfo.windowHeight
    }

    // 触发重新计算
    nextTick()
}

// 监听可见性变化
watch(() => props.visible, (newVal) => {
    if (newVal) {
        open()
    } else {
        close()
    }
})

// 监听位置变化
watch(() => props.x, () => {
    if (props.visible) {
        nextTick()
    }
})

watch(() => props.y, () => {
    if (props.visible) {
        nextTick()
    }
})

// 暴露给父组件的方法
defineExpose({
    open,
    close,
    updatePosition,
    updateActions: (newActions: MessageActionItem[]) => {
        // 可以通过ref调用更新actions
    }
})
</script>

<style scoped lang="scss">
.im-message-action-mask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: v-bind('props.maskColor');
    z-index: 9998;
    opacity: 0;
    transition: opacity var(--animation-duration, 300ms) ease;

    &--show {
        opacity: 1;
    }
}

.im-message-action {
    position: fixed;
    z-index: 9999;
    min-width: 200rpx;
    max-width: 90vw;
    max-height: var(--max-height, 400rpx);
    width: var(--width, 300rpx);
    background-color: #ffffff;
    border-radius: var(--border-radius, 16rpx);
    box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15);
    overflow: hidden;
    opacity: 0;
    transform: translateY(20rpx) scale(0.95);
    transition: all var(--animation-duration, 300ms) cubic-bezier(0.34, 1.56, 0.64, 1);

    // 主题变体
    &--light {
        background-color: #ffffff;
        color: #303133;
    }

    &--dark {
        background-color: #2a2a2a;
        color: #ffffff;
    }

    &--card {
        background-color: #ffffff;
        border: 1rpx solid #e4e7ed;
        box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
    }

    // 显示状态
    &--show {
        opacity: 1;
        transform: translateY(0) scale(1);
    }

    // 位置变体
    &--top {
        transform-origin: bottom center;
    }

    &--bottom {
        transform-origin: top center;
    }

    &--top-left {
        transform-origin: bottom right;
    }

    &--top-right {
        transform-origin: bottom left;
    }

    &--bottom-left {
        transform-origin: top right;
    }

    &--bottom-right {
        transform-origin: top left;
    }
}

.im-message-action__list {
    max-height: calc(var(--max-height, 400rpx) - 100rpx);
}

.im-message-action__item {
    display: flex;
    align-items: center;
    padding: 28rpx 32rpx;
    position: relative;
    cursor: pointer;
    transition: background-color 0.2s ease;

    &:active:not(&--disabled) {
        background-color: #f5f7fa;

        .im-message-action--dark & {
            background-color: rgba(255, 255, 255, 0.1);
        }

        .im-message-action--card & {
            background-color: #fafafa;
        }
    }

    &--disabled {
        cursor: not-allowed;
        opacity: 0.5;
    }

    &--danger {
        .im-message-action__text {
            color: #f56c6c;
        }
    }

    &--divider {
        padding: 0;
        height: 1rpx;
        background-color: #e4e7ed;

        .im-message-action--dark & {
            background-color: rgba(255, 255, 255, 0.1);
        }
    }
}

.im-message-action__divider {
    width: 100%;
    height: 1rpx;
    background-color: #e4e7ed;

    .im-message-action--dark & {
        background-color: rgba(255, 255, 255, 0.1);
    }
}

.im-message-action__icon {
    margin-right: 16rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32rpx;
    flex-shrink: 0;
}

.im-message-action__text {
    flex: 1;
    font-size: 30rpx;
    line-height: 1.4;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.im-message-action__extra {
    margin-left: 16rpx;
    flex-shrink: 0;
}

.im-message-action__hint {
    font-size: 24rpx;
    color: #909399;

    .im-message-action--dark & {
        color: #aaaaaa;
    }
}

.im-message-action__cancel {
    border-top: 1rpx solid #e4e7ed;
    padding: 28rpx 32rpx;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.2s ease;

    .im-message-action--dark & {
        border-top-color: rgba(255, 255, 255, 0.1);
    }

    &:active {
        background-color: #f5f7fa;

        .im-message-action--dark & {
            background-color: rgba(255, 255, 255, 0.1);
        }
    }
}

.im-message-action__cancel-text {
    font-size: 30rpx;
    color: #606266;
    font-weight: 500;

    .im-message-action--dark & {
        color: #cccccc;
    }
}

.im-message-action__arrow {
    position: absolute;
    width: 0;
    height: 0;
    border-style: solid;

    .im-message-action--top & {
        border-width: var(--arrow-size, 12px) var(--arrow-size, 12px) 0 var(--arrow-size, 12px);
        border-color: #ffffff transparent transparent transparent;

        .im-message-action--dark & {
            border-color: #2a2a2a transparent transparent transparent;
        }

        .im-message-action--card & {
            border-color: #ffffff transparent transparent transparent;
        }
    }

    .im-message-action--bottom & {
        border-width: 0 var(--arrow-size, 12px) var(--arrow-size, 12px) var(--arrow-size, 12px);
        border-color: transparent transparent #ffffff transparent;

        .im-message-action--dark & {
            border-color: transparent transparent #2a2a2a transparent;
        }

        .im-message-action--card & {
            border-color: transparent transparent #ffffff transparent;
        }
    }
}

// 移除默认的滚动条
.im-message-action ::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
    color: transparent;
}

// 暗色模式适配
@media (prefers-color-scheme: dark) {
    .im-message-action--light {
        background-color: #2a2a2a;
        color: #ffffff;
        box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.3);
    }
}

// 响应式调整
@media (max-width: 768px) {
    .im-message-action {
        width: 80vw;
        max-width: 400rpx;
    }

    .im-message-action__item,
    .im-message-action__cancel {
        padding: 24rpx 28rpx;
    }
}
</style>