<template>
    <div class="ai-float-wrapper">
        <div class="ai-float-container" ref="containerRef">
            <!-- 悬浮按钮 -->
            <button ref="buttonRef" @click.stop="toggleChat" @mousedown="startDrag" class="ai-float-button"
                :class="{ 'pulse-animation': isNewMessage, 'active': showChat }" :style="buttonStyle">
                <span v-if="isNewMessage" class="notification-dot"></span>
                <div class="button-content">
                    <slot name="button-icon" :isChatOpen="showChat">
                        <svg v-if="!showChat" xmlns="http://www.w3.org/2000/svg" width="20" height="20"
                            viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                            stroke-linecap="round" stroke-linejoin="round">
                            <path d="m12 8-9.04 9.06a2.82 2.82 0 1 0 3.98 3.98L16 12" />
                            <circle cx="17" cy="7" r="5" />
                        </svg>
                        <svg v-else xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"
                            fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                            stroke-linejoin="round">
                            <line x1="18" y1="6" x2="6" y2="18"></line>
                            <line x1="6" y1="6" x2="18" y2="18"></line>
                        </svg>
                    </slot>
                    <span class="button-text">{{ showChat ? closeText : openText }}</span>
                </div>
            </button>
        </div>

        <!-- 聊天面板 -->
        <div v-if="showChat" class="chat-panel">
            <div class="chat-panel-content">
                <div class="chat-panel-header">
                    <div class="header-title">
                        <slot name="header-icon">
                            <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"
                                fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                                stroke-linejoin="round">
                                <path d="m12 8-9.04 9.06a2.82 2.82 0 1 0 3.98 3.98L16 12" />
                                <circle cx="17" cy="7" r="5" />
                            </svg>
                        </slot>
                        <h3>{{ headerTitle }}</h3>
                    </div>
                    <button @click="closeChat" class="close-button">&times;</button>
                </div>

                <div class="chat-panel-body">
                    <slot :closeChat="closeChat">
                        <!-- 默认插槽内容，如果未提供则使用AIChat组件 -->
                        <AIChat v-if="useDefaultAIChat" v-bind="aiChatProps" @new-message="handleNewMessage" />
                    </slot>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import AIChat from './AIChat.vue';

export default {
    name: 'AIFloatButton',
    components: {
        AIChat
    },
    props: {
        // AIChat 组件相关属性
        baseUrl: {
            type: String,
            default: null
        },
        modelAuthKey: {
            type: String,
            default: null
        },
        knowledgeBaseId: {
            type: String,
            default: null
        },
        knowledgeBaseUrl: {
            type: String,
            default: '/api/knowledgebases/query'
        },
        knowledgeBaseAuthKey: {
            type: String,
            default: ''
        },

        // UI 相关属性
        openText: {
            type: String,
            default: 'AI助手'
        },
        closeText: {
            type: String,
            default: '关闭'
        },
        headerTitle: {
            type: String,
            default: 'AI 助手'
        },

        // 行为相关属性
        useDefaultAIChat: {
            type: Boolean,
            default: true
        },

        // 位置相关属性
        initialPosition: {
            type: Object,
            default: function () { return { x: null, y: null }; } // 如果为null，则使用默认位置
        }
    },
    data() {
        return {
            showChat: false,
            isNewMessage: false,
            notificationTimeout: null,
            isDragging: false,
            dragState: {
                startX: 0,
                startY: 0,
                startLeft: 0,
                startTop: 0
            },
            buttonPosition: {
                x: this.initialPosition.x,
                y: this.initialPosition.y
            }
        };
    },
    computed: {
        // 计算传递给AIChat组件的属性
        aiChatProps() {
            return {
                baseUrl: this.baseUrl,
                modelAuthKey: this.modelAuthKey,
                knowledgeBaseId: this.knowledgeBaseId,
                knowledgeBaseUrl: this.knowledgeBaseUrl,
                knowledgeBaseAuthKey: this.knowledgeBaseAuthKey
            };
        },

        // 计算按钮样式
        buttonStyle() {
            // 如果有自定义位置，则使用自定义位置
            if (this.buttonPosition.x !== null && this.buttonPosition.y !== null) {
                return {
                    left: `${this.buttonPosition.x}px`,
                    top: `${this.buttonPosition.y}px`,
                };
            }

            // 否则使用默认的右下角位置
            return {
                bottom: '20px',
                right: '20px',
            };
        }
    },
    mounted() {
        document.addEventListener('keydown', this.handleEscapeKey);
        window.addEventListener('resize', this.handleWindowResize);
    },
    beforeDestroy() {
        document.removeEventListener('keydown', this.handleEscapeKey);
        document.removeEventListener('mousemove', this.onDrag);
        document.removeEventListener('mouseup', this.stopDrag);
        window.removeEventListener('resize', this.handleWindowResize);
        if (this.notificationTimeout) {
            clearTimeout(this.notificationTimeout);
        }
    },
    methods: {
        // 开始拖动
        startDrag(event) {
            // 如果点击的是按钮内容（图标或文本），则不触发拖动
            if (event.target.closest('.button-content')) {
                return;
            }

            event.preventDefault();
            this.isDragging = true;

            // 获取按钮当前位置
            const buttonRect = this.$refs.buttonRef.getBoundingClientRect();

            this.dragState = {
                startX: event.clientX,
                startY: event.clientY,
                startLeft: buttonRect.left,
                startTop: buttonRect.top
            };

            // 如果聊天面板打开，在拖动开始时立即更新其位置
            if (this.showChat) {
                // 强制重新计算buttonStyle
                this.$forceUpdate();
            }

            // 添加全局事件监听器
            document.addEventListener('mousemove', this.onDrag);
            document.addEventListener('mouseup', this.stopDrag);
        },

        // 拖动中
        onDrag(event) {
            if (!this.isDragging) return;

            event.preventDefault();

            // 计算新位置
            const deltaX = event.clientX - this.dragState.startX;
            const deltaY = event.clientY - this.dragState.startY;

            const newLeft = this.dragState.startLeft + deltaX;
            const newTop = this.dragState.startTop + deltaY;

            // 确保按钮不会被拖出屏幕边界
            const boundedLeft = Math.max(0, Math.min(newLeft, window.innerWidth - 64));
            const boundedTop = Math.max(0, Math.min(newTop, window.innerHeight - 64));

            // 更新按钮位置状态
            this.buttonPosition = {
                x: boundedLeft,
                y: boundedTop
            };

            // 如果聊天面板打开，在拖动过程中更新其位置
            if (this.showChat) {
                // 强制触发buttonStyle重新计算
                this.$forceUpdate();
            }
        },

        // 停止拖动
        stopDrag() {
            this.isDragging = false;

            // 移除全局事件监听器
            document.removeEventListener('mousemove', this.onDrag);
            document.removeEventListener('mouseup', this.stopDrag);
        },

        // 切换聊天面板显示状态
        toggleChat(event) {
            // 如果正在拖动，则不打开聊天面板
            if (this.isDragging) {
                this.isDragging = false;
                return;
            }

            event.stopPropagation();
            this.showChat = !this.showChat;
            this.isNewMessage = false;

            // 清除可能存在的定时器
            if (this.notificationTimeout) {
                clearTimeout(this.notificationTimeout);
                this.notificationTimeout = null;
            }

            this.$emit('toggle', this.showChat);
        },

        // 关闭聊天面板
        closeChat() {
            this.showChat = false;
            this.$emit('close');
        },

        // 处理新消息提醒
        handleNewMessage() {
            // 如果聊天窗口未打开，则显示新消息提醒
            if (!this.showChat) {
                this.isNewMessage = true;
                // 3秒后自动清除提醒
                if (this.notificationTimeout) {
                    clearTimeout(this.notificationTimeout);
                }
                this.notificationTimeout = setTimeout(() => {
                    this.isNewMessage = false;
                }, 3000);
            }
            this.$emit('new-message');
        },

        // 点击 Escape 键关闭聊天面板
        handleEscapeKey(event) {
            if (this.showChat && event.key === 'Escape') {
                this.closeChat();
            }
        },

        // 处理窗口大小变化
        handleWindowResize() {
            // 窗口大小变化时，强制重新计算面板位置
            if (this.showChat) {
                // 触发响应式更新
                this.$forceUpdate();
            }
        }
    }
};
</script>

<style scoped>
.ai-float-wrapper {
    position: relative;
    z-index: 1000;
}

.ai-float-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
}

.ai-float-button {
    position: fixed;
    background: linear-gradient(135deg, #4a6cf7 0%, #6a11cb 100%);
    color: white;
    border: none;
    border-radius: 50px;
    width: 64px;
    height: 64px;
    font-weight: bold;
    cursor: move;
    /* 显示拖动光标 */
    box-shadow: 0 6px 20px rgba(74, 108, 247, 0.4);
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    overflow: hidden;
    z-index: 1000;
}

.ai-float-button:hover:not(:active) {
    transform: translateY(-3px) scale(1.05);
    box-shadow: 0 10px 25px rgba(74, 108, 247, 0.5);
}

.ai-float-button:active {
    transform: translateY(0) scale(1);
}

.ai-float-button.active {
    display: none;

}

.button-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    pointer-events: none;
    /* 防止内容区域影响拖动 */
}

.button-text {
    font-size: 10px;
    font-weight: 600;
}

.notification-dot {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 16px;
    height: 16px;
    background: #ff4757;
    border: 2px solid white;
    border-radius: 50%;
    animation: pulse 1.5s infinite;
    z-index: 1;
    pointer-events: none;
    /* 防止通知点影响拖动 */
}

.pulse-animation {
    animation: pulse-button 2s infinite;
}

@keyframes pulse {
    0% {
        transform: scale(0.9);
        box-shadow: 0 0 0 0 rgba(255, 71, 87, 0.7);
    }

    70% {
        transform: scale(1);
        box-shadow: 0 0 0 8px rgba(255, 71, 87, 0);
    }

    100% {
        transform: scale(0.9);
        box-shadow: 0 0 0 0 rgba(255, 71, 87, 0);
    }
}

@keyframes pulse-button {
    0% {
        transform: scale(1);
    }

    50% {
        transform: scale(1.05);
    }

    100% {
        transform: scale(1);
    }
}

.chat-panel {
    width: 450px;
    min-height: 400px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
    border-radius: 16px;
    overflow: hidden;
    background: white;
    z-index: 1001;
    animation: slideIn 0.3s ease-out;
    position: fixed;
    bottom: 20px;
    right: 20px;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateY(-5%) scale(0.95);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.chat-panel-content {
    display: flex;
    flex-direction: column;
    height: 100%;
    max-height: 80vh;
}

.chat-panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 16px;
    background: linear-gradient(120deg, #4a6cf7 0%, #6a11cb 100%);
    color: white;
    flex-shrink: 0;
}

.header-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

.header-title h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}

.close-button {
    background: rgba(255, 255, 255, 0.2);
    border: none;
    border-radius: 50%;
    font-size: 20px;
    cursor: pointer;
    color: white;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
}

.close-button:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: rotate(90deg);
}

.chat-panel-body {
    flex: 1;
    height: 100%;
    overflow: auto;
    display: flex;
    flex-direction: column;
}

@media (max-width: 600px) {
    .chat-panel {
        width: calc(100vw - 20px);
        max-height: 80vh;
        max-width: 350px;
        bottom: 10px;
        right: 10px;
    }

    .chat-panel-content {
        max-height: 80vh;
    }

    .chat-panel-body {
        min-height: 300px;
    }

    .ai-float-button {
        width: 56px;
        height: 56px;
    }

    .ai-float-button.active {
        border-radius: 20px 20px 6px 6px;
    }

    .button-text {
        font-size: 9px;
    }
}
</style>