<template>
    <div class="ai-chat-container">
        <!-- 聊天主界面 -->
        <div class="chat-main">
            <!-- 左侧边栏 - 会话列表 -->
            <div class="sidebar">
                <div class="sidebar-header">
                    <button class="new-chat-btn" @click="createNewChatDirect">
                        <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                            <path d="M8 3.5V12.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
                            <path d="M3.5 8H12.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
                        </svg>
                        <span>新建对话</span>
                    </button>
                </div>

                <div class="chat-list">
                    <div
                        v-for="(chat, index) in chatList"
                        :key="chat.id"
                        :class="['chat-item', { active: currentChatId === chat.id }]"
                        @click="selectChat(chat)"
                    >
                        <div class="chat-item-content">
                            <el-input
                                v-if="editingChatIndex === index"
                                v-model="chat.editingTitle"
                                size="mini"
                                @blur="confirmEditTitle(index)"
                                @keydown.native.enter.prevent="confirmEditTitle(index)"
                                @click.stop
                                ref="editInput"
                                class="chat-title-input"
                            >
                            </el-input>
                            <div
                                v-else
                                class="chat-item-title"
                                @dblclick.stop="startEditTitle(index, chat)"
                                title="双击编辑标题"
                            >{{ chat.title }}
                            </div>
                            <div class="chat-item-time">{{ formatTime(chat.time) }}</div>
                        </div>
                        <div class="chat-item-actions">
                            <i
                                class="el-icon-edit chat-item-edit"
                                @click.stop="startEditTitle(index, chat)"
                                title="修改标题"
                            ></i>
                            <i
                                v-if="index !== 0"
                                class="el-icon-top chat-item-pin"
                                @click.stop="pinChat(index)"
                                title="置顶会话"
                            ></i>
                            <i
                                class="el-icon-delete chat-item-clear-cache"
                                @click.stop="clearChatCache(index, chat)"
                                title="清除缓存"
                            ></i>
                            <i
                                class="el-icon-close chat-item-close"
                                @click.stop="closeChat(index)"
                                title="删除会话"
                            ></i>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 中间聊天区域 -->
            <div class="chat-content">
                <!-- 左侧客户画像面板 -->
                <div v-if="linkedCustomer" class="customer-portrait-panel">
                    <!-- 客户姓名固定顶部 -->
                    <div class="profile-item profile-item-main profile-item-sticky">
                        <span class="label"><i class="fas fa-user-circle"></i> 客户姓名：</span>
                        <span class="value highlight">{{ linkedCustomer.name }}</span>
                    </div>
                    <!-- 其他画像数据可滚动 -->
                    <div class="profile-scroll-content">
                        <template v-for="(value, key) in customerPortraitData">
                            <!-- 排除客户姓名和需求字段 -->
                            <div
                                v-if="key !== '客户姓名' && key !== '需求'"
                                :key="key"
                                class="profile-item"
                            >
                                    <span class="label">
                                        <i :class="getIconClass(key)"></i> {{ key }}：
                                    </span>
                                <span class="value">{{ value }}</span>
                            </div>
                        </template>
                        <!-- 需求单独显示，占满整行 -->
                        <div
                            v-if="customerPortraitData['需求']"
                            key="需求"
                            class="profile-item profile-item-full"
                        >
                                <span class="label">
                                    <i class="fas fa-bullseye"></i> 需求：
                                </span>
                            <span class="value long-text">{{ customerPortraitData['需求'] }}</span>
                        </div>
                        <!-- 当画像数据为空时显示提示 -->
                        <div v-if="!hasPortraitData"
                             class="profile-item profile-item-full">
                            <span class="value empty-tip">暂无画像信息</span>
                        </div>
                    </div>
                </div>
                <!-- 聊天标题 -->
                <div v-if="currentChatTitle && messages.length > 0" class="chat-title-header">
                    <h2 class="chat-title-text">{{ currentChatTitle }}</h2>
                </div>

                <!-- 消息列表 -->
                <div class="messages-container" ref="messagesContainer">
                    <!-- 欢迎界面 -->
                    <div v-if="messages.length === 0" class="welcome-container">
                        <div class="welcome-avatar">
                            <img src="/static/images/ai-avatar.svg" alt="AI" class="welcome-avatar-img"/>
                        </div>
                        <div class="welcome-text">今天有什么可以帮到你？</div>
                    </div>

                    <div v-else class="messages-list">
                        <div
                            v-for="(message, index) in messages"
                            :key="index"
                            :class="['message-row', message.type === 'user' ? 'message-user' : 'message-ai']"
                        >
                            <!-- AI 消息 -->
                            <div v-if="message.type === 'ai'" class="message-wrapper">
                                <div class="avatar avatar-ai">
                                    <img src="/static/images/ai-avatar.svg" alt="AI" @error="handleAvatarError"/>
                                </div>
                                <div class="message-body">
                                    <div class="message-name">
                                        AI 助手
                                        <span v-if="message.thinkingDuration" class="thinking-time">
                                            耗时 {{ formatThinkingTime(message.thinkingDuration) }}
                                        </span>
                                    </div>
                                    <div class="message-bubble message-bubble-ai">
                                        <div class="message-content" v-html="formatMessage(message.content)"></div>
                                    </div>
                                </div>
                            </div>

                            <!-- 用户消息 -->
                            <div v-else class="message-row message-user">
                                <div class="message-bubble message-bubble-user">
                                    <div class="message-content" v-html="formatUserMessage(message.content)"></div>
                                </div>
                            </div>
                        </div>

                        <!-- AI 思考中提示 -->
                        <div v-if="isAiThinking" class="message-row message-ai">
                            <div class="message-wrapper">
                                <div class="avatar avatar-ai">
                                    <img src="/static/images/ai-avatar.svg" alt="AI" @error="handleAvatarError"/>
                                </div>
                                <div class="message-body">
                                    <div class="message-name">AI 助手</div>
                                    <div class="message-bubble message-bubble-ai thinking-bubble">
                                        <div class="thinking-indicator">
                                            <span></span>
                                            <span></span>
                                            <span></span>
                                        </div>
                                        <span class="thinking-text">思考中 {{
                                                formatThinkingTime(aiThinkingDuration)
                                            }}</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 输入区域 -->
                <div class="input-area" :class="{ 'input-disabled': isAiThinking }">
                    <!-- 关联客户按钮 -->
                    <div class="customer-link-bar">
                        <el-button
                            size="small"
                            type="primary"
                            plain
                            @click="linkCustomer"
                            class="customer-link-btn"
                            :disabled="isAiThinking"
                        >
                            <i class="el-icon-user"></i>
                            关联客户
                        </el-button>
                        <span v-if="linkedCustomer" class="linked-customer-info">
              <i class="el-icon-check"></i>
              已关联：{{ linkedCustomer.name }}
              <span v-if="linkedCustomer.intentionDegree" style="margin-left: 8px; color: #67c23a;">
                意向度：{{ linkedCustomer.intentionDegree }}
              </span>
              <el-tag
                  size="mini"
                  :type="getAttritionLevelTagType(linkedCustomer.attritionLevel)"
                  style="margin-left: 8px;"
              >
                {{ getAttritionLevelText(linkedCustomer.attritionLevel) }}
              </el-tag>
              <i class="el-icon-close unlink-icon" @click="unlinkCustomer" title="取消关联"></i>
            </span>
                    </div>
                    <div class="input-container">
                        <div class="input-box">
                            <el-input
                                v-model="inputMessage"
                                type="textarea"
                                :rows="3"
                                placeholder="输入消息... (Shift+Enter 换行，Enter 发送)"
                                @keydown.native.enter.exact.prevent="sendMessage"
                                resize="none"
                                class="message-input"
                                :disabled="isAiThinking"
                            >
                            </el-input>
                            <div class="send-btn-wrapper" @click="sendMessage" title="点击发送"
                                 :class="{ 'disabled': isAiThinking }">
                                <i class="el-icon-top"></i>
                            </div>
                        </div>
                    </div>
                    <div class="input-tip">
                        AI 生成内容仅供参考，请谨慎判断
                        <span v-if="isAiThinking" class="thinking-tip"> · AI 正在思考中，请稍候...</span>
                    </div>
                </div>
            </div>
        </div>

        <!-- 客户选择对话框 -->
        <el-dialog
            v-if="customerDialogVisible"
            :visible.sync="customerDialogVisible"
            title="选择客户"
            width="900px"
            :close-on-click-modal="false"
            @close="cancelSelectCustomer"
        >
            <div class="customer-dialog-content">
                <!-- 筛选区域 -->
                <div class="customer-filter">
                    <el-form :inline="true" size="small">
                        <el-form-item label="客户名称">
                            <el-input
                                v-model="customerFilter.customerName"
                                placeholder="请输入客户名称"
                                clearable
                                @keyup.enter.native="handleCustomerFilter"
                            />
                        </el-form-item>
                        <el-form-item label="流失风险等级">
                            <el-select
                                v-model="customerFilter.attritionLevel"
                                placeholder="请选择风险等级"
                                clearable
                            >
                                <el-option label="未知" :value="0"/>
                                <el-option label="无风险" :value="1"/>
                                <el-option label="低风险" :value="2"/>
                                <el-option label="中风险" :value="3"/>
                                <el-option label="高风险" :value="4"/>
                            </el-select>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="handleCustomerFilter">
                                <i class="el-icon-search"></i> 搜索
                            </el-button>
                            <el-button @click="resetCustomerFilter">
                                <i class="el-icon-refresh"></i> 重置
                            </el-button>
                        </el-form-item>
                    </el-form>
                </div>

                <el-table
                    :data="customerList"
                    v-loading="customerLoading"
                    highlight-current-row
                    @current-change="handleCurrentChange"
                    border
                >
                    <el-table-column type="radio" width="50" align="center"></el-table-column>
                    <el-table-column prop="customerId" label="客户 ID" width="120" align="center"></el-table-column>
                    <el-table-column prop="customerName" label="客户名称" min-width="200"
                                     align="center"></el-table-column>
                    <el-table-column label="流失风险等级" width="150" align="center">
                        <template slot-scope="scope">
                            <el-tag :type="getAttritionLevelTagType(scope.row.attritionLevel)" size="small">
                                {{ getAttritionLevelText(scope.row.attritionLevel) }}
                            </el-tag>
                        </template>
                    </el-table-column>
                    <el-table-column prop="intentionDegree" label="意向度" width="150" align="center">
                        <template slot-scope="scope">
                            <span>{{ scope.row.intentionDegree || '-' }}</span>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="100" align="center" fixed="right">
                        <template slot-scope="scope">
                            <el-button
                                type="primary"
                                size="small"
                                @click="selectCustomerByClick(scope.row)"
                            >
                                选择
                            </el-button>
                        </template>
                    </el-table-column>
                </el-table>

                <div class="customer-pagination">
                    <el-pagination
                        @current-change="handleCustomerPageChange"
                        :current-page="customerPagination.pageNum"
                        :page-size="customerPagination.pageSize"
                        :total="customerPagination.total"
                        layout="total, prev, pager, next, jumper"
                        background
                        :page-sizes="[5, 10, 20, 50]"
                    >
                    </el-pagination>
                </div>
            </div>

            <span slot="footer" class="dialog-footer">
        <el-button @click="cancelSelectCustomer">关 闭</el-button>
      </span>
        </el-dialog>


    </div>
</template>

<script>
import {listAllAnalyze} from "../../../api/crm/customerAnalyze";
import {
    createChatSession,
    updateChatSessionTitle,
    updateChatSessionCustomer,
    deleteChatSession,
    getChatMessageList,
    saveChatMessage,
    batchSaveMessages,
    getChatSessionList,
    pinChatSession, getAiReply
} from "../../../api/aiChat/aiChatSession";

export default {
    name: 'CustomerAiChat',
    data() {
        return {
            // 会话列表数据
            chatList: [],
            // 当前选中的会话 ID
            currentChatId: null,
            // 当前会话的消息列表
            messages: [],
            // 输入框中的消息内容
            inputMessage: '',
            // 是否正在加载数据
            isLoading: false,
            // AI 是否正在思考回复中
            isAiThinking: false,
            // AI 开始思考的时间戳
            aiThinkingStartTime: 0,
            // AI 思考已持续的时长（毫秒）
            aiThinkingDuration: 0,
            // 思考计时器实例
            thinkingTimer: null,
            // 当前会话的标题
            currentChatTitle: '',
            // 当前已关联的客户信息
            linkedCustomer: null,
            // 会话与客户的关联映射表 {chatId: customer}
            customerLinkMap: {},
            // 标记是否已发送第一条消息（用于控制会话标题生成）
            hasSentFirstMessage: false,
            // 记录用户手动编辑过标题的会话 ID，防止被自动覆盖
            manuallyEditedTitles: {},
            // 客户选择对话框是否可见
            customerDialogVisible: false,
            // 客户列表数据
            customerList: [],
            // 客户分页配置
            customerPagination: {
                pageNum: 1,
                pageSize: 5,
                total: 0
            },
            // 客户列表是否正在加载中
            customerLoading: false,
            // 当前选中的客户 ID
            selectedCustomerId: null,
            // 客户筛选条件
            customerFilter: {
                customerName: '',
                attritionLevel: null
            },
            // 当前正在编辑标题的会话索引
            editingChatIndex: -1,
            // 是否正在编辑会话标题
            isEditingChat: false,
            // 待发送的消息队列（用于批量保存）
            messageQueue: [],
            // 是否正在保存消息到后端
            isSaving: false,
            // 队列中待保存的消息数量
            pendingSaveCount: 0,
            // 单次批量保存的最大消息数量
            maxBatchSize: 10,
            // 延迟保存的时间（毫秒），避免频繁请求
            saveDelay: 800,
            // 保存定时器实例
            saveTimer: null,
            // localStorage 缓存键前缀
            localCacheKey: 'ai_chat_cache_',
            // 消息加载游标 {sessionId: lastMsgTime}，用于分页加载历史消息
            messageCursor: {},
            // 是否正在加载更多历史消息
            isLoadingMore: false,
            // 是否还有更多历史消息可加载
            hasMoreMessages: true,
            // 消息重试次数记录 {tempId: count}
            retryCounts: {},
            // IndexedDB 是否已完成初始化
            dbInitialized: false,
            // IndexedDB 数据库实例
            db: null,
            // 同步锁，防止并发操作导致数据不一致
            syncLock: false,
            // 正在创建的会话 Promise，防止重复创建同一个会话
            sessionCreatingPromise: null,
            // 待关联的客户信息（在会话创建后使用）
            pendingLinkedCustomer: null,
            // 当前会话是否已发送第一条消息
            firstMessageSent: false,
            // 客户画像数据缓存 {chatId: portraitJson}
            customerPortraitCache: {}
        }
    },
    created() {
        // 初始化 IndexedDB
        this.initIndexedDB()
        // ✅ 同步从后端加载会话列表
        this.loadSessionsFromBackend()
    },
    computed: {
        // 是否有画像数据（排除客户姓名）
        hasPortraitData() {
            if (!this.linkedCustomer || !this.linkedCustomer.customerPortraitJson) {
                return false;
            }
            try {
                const portrait = typeof this.linkedCustomer.customerPortraitJson === 'string'
                    ? JSON.parse(this.linkedCustomer.customerPortraitJson)
                    : this.linkedCustomer.customerPortraitJson;
                // 排除客户姓名后是否还有其他数据
                const keys = Object.keys(portrait).filter(k => k !== '客户姓名');
                return keys.length > 0;
            } catch (error) {
                console.error('解析客户画像 JSON 失败:', error);
                return false;
            }
        },

        // 客户画像数据 (从最新的沟通记录中获取)
        customerPortraitData() {
            if (!this.linkedCustomer || !this.linkedCustomer.customerPortraitJson) {
                return {};
            }

            // ✅ 使用缓存避免重复解析
            const cached = this.customerPortraitCache[this.currentChatId]
            if (cached && typeof cached === 'object') {
                return cached
            }

            try {
                if (typeof this.linkedCustomer.customerPortraitJson === 'string') {
                    const parsed = JSON.parse(this.linkedCustomer.customerPortraitJson);
                    // 缓存到 currentChatId
                    if (this.currentChatId) {
                        this.customerPortraitCache[this.currentChatId] = parsed
                    }
                    return parsed;
                }
                return this.linkedCustomer.customerPortraitJson;
            } catch (error) {
                console.error('解析客户画像 JSON 失败:', error);
                return {};
            }
        },

        // 传递给 AI 的完整画像数据（包含客户姓名）
        aiPortraitData() {
            if (!this.linkedCustomer) {
                return null;
            }

            let portrait = {};

            // 如果有画像 JSON，解析它
            if (this.linkedCustomer.customerPortraitJson) {
                try {
                    const portraitStr = this.linkedCustomer.customerPortraitJson;
                    portrait = typeof portraitStr === 'string'
                        ? JSON.parse(portraitStr)
                        : portraitStr;
                } catch (error) {
                    console.error('解析客户画像 JSON 失败:', error);
                    portrait = {};
                }
            }

            // ✅ 如果画像中没有客户姓名，则添加进去
            if (!portrait['客户姓名'] && this.linkedCustomer.name) {
                portrait['客户姓名'] = this.linkedCustomer.name;
            }

            return portrait;
        }
    },
    methods: {
        // 生成唯一 ID(13 位时间戳 +sessionId) - 用于会话 ID 生成
        generateUniqueId(sessionId) {
            const timestamp = Date.now().toString()
            // 使用 crypto.getRandomValues() 生成密码学安全的随机数
            const randomArray = new Uint32Array(1)
            if (window.crypto && window.crypto.getRandomValues) {
                window.crypto.getRandomValues(randomArray)
            } else {
                randomArray[0] = Math.floor(Math.random() * 10000)
            }
            const suffix = sessionId || (randomArray[0] % 10000).toString(36).padStart(5, '0')
            return `${timestamp}${suffix}`
        },

        // 生成临时会话 ID(13 位时间戳 +5 位随机数) - 用于后端会话创建前的本地标识
        generateTempSessionId() {
            const timestamp = Date.now().toString()
            const randomArray = new Uint32Array(1)
            if (window.crypto && window.crypto.getRandomValues) {
                window.crypto.getRandomValues(randomArray)
            } else {
                randomArray[0] = Math.floor(Math.random() * 100000)
            }
            const randomStr = (randomArray[0] % 100000).toString().padStart(5, '0')
            return `${timestamp}${randomStr}`
        },

        // 用后端 sessionId 替换临时 ID 的最后 5 位 - 保持 ID 连续性
        replaceTempIdWithSessionId(tempId, sessionId) {
            const timestamp = tempId.substring(0, 13)
            return `${timestamp}${sessionId}`
        },
        // 初始化 IndexedDB - 用于本地消息存储和离线访问
        initIndexedDB() {
            if (!window.indexedDB) {
                console.warn('浏览器不支持 IndexedDB，使用 localStorage 降级方案')
                return
            }

            const request = indexedDB.open('AiChatDB', 1)

            request.onerror = (event) => {
                console.error('IndexedDB 初始化失败:', event.target.error)
                this.dbInitialized = false
            }

            request.onsuccess = (event) => {
                this.db = event.target.result
                this.dbInitialized = true

                // 版本变更时关闭连接
                this.db.onversionchange = () => {
                    console.warn('IndexedDB 版本变更，建议关闭连接')
                }
            }

            request.onupgradeneeded = (event) => {
                const db = event.target.result

                // 创建会话存储表
                if (!db.objectStoreNames.contains('sessions')) {
                    const sessionStore = db.createObjectStore('sessions', {keyPath: 'id'})
                    sessionStore.createIndex('time', 'time')
                }

                // 创建消息存储表
                if (!db.objectStoreNames.contains('messages')) {
                    const messageStore = db.createObjectStore('messages', {
                        keyPath: 'tempId',
                        autoIncrement: true
                    })
                    messageStore.createIndex('sessionId', 'sessionId')
                    messageStore.createIndex('time', 'time')
                }
            }
        },

        // IndexedDB 事务封装 - 统一错误处理和事务管理
        _dbTransaction(storeName, mode, operation) {
            return new Promise((resolve, reject) => {
                if (!this.dbInitialized || !this.db) {
                    reject(new Error('IndexedDB 未初始化'))
                    return
                }
                try {
                    const transaction = this.db.transaction([storeName], mode)
                    const store = transaction.objectStore(storeName)
                    const request = operation(store)

                    request.onsuccess = () => resolve(request.result)
                    request.onerror = (event) => reject(event.target.error)
                    transaction.oncomplete = () => {}
                    transaction.onerror = (event) => reject(event.target.error)
                } catch (error) {
                    reject(error)
                }
            })
        },

        // IndexedDB 新增数据
        dbAdd(storeName, data) {
            return this._dbTransaction(storeName, 'readwrite', store => store.add(data))
        },

        // IndexedDB 更新数据
        dbPut(storeName, data) {
            return this._dbTransaction(storeName, 'readwrite', store => store.put(data))
        },

        // IndexedDB 通过索引查询数据
        dbGetByIndex(storeName, indexName, value) {
            return this._dbTransaction(storeName, 'readonly', store => {
                const index = store.index(indexName)
                return index.getAll(value)
            })
        },

        // IndexedDB 获取所有数据
        dbGetAll(storeName) {
            return this._dbTransaction(storeName, 'readonly', store => store.getAll())
        },

        // IndexedDB 删除数据
        dbDelete(storeName, key) {
            return this._dbTransaction(storeName, 'readwrite', store => store.delete(key))
        },


        // 直接创建新会话 - 本地临时会话，等待后端确认
        createNewChatDirect() {
            const newTitle = '新会话 ' + (this.chatList.length + 1)
            const tempSessionId = this.generateTempSessionId()
            const newChat = {
                id: tempSessionId,
                title: newTitle,
                time: Date.now(),
                messages: [],
                sessionId: null,
                isSynced: false,
                linkedCustomer: null,
                linkedCustomerId: null
            }
            this.chatList.unshift(newChat)
            this.selectChat(newChat)
            this.currentChatTitle = newTitle

            // 清空当前消息，显示欢迎状态
            this.messages = []
            // ✅ 关键修复：新建对话时才重置关联客户，但如果已经有 pendingLinkedCustomer 则保留
            if (!this.pendingLinkedCustomer) {
                this.linkedCustomer = null
            }
            this.firstMessageSent = false

            // 清空手动编辑标题的记录
            delete this.manuallyEditedTitles[newChat.id]

            // 清理定时器，防止内存泄漏
            this.clearThinkingTimer()
            this.clearSaveTimer()

            // 滚动到顶部以显示欢迎界面
            this.$nextTick(() => {
                const container = this.$refs.messagesContainer
                if (container) {
                    container.scrollTop = 0
                }
            })
        },

        // 创建后端会话 - 带锁机制防止重复创建，确保客户关联一致性
        async createBackendSession(chat, message) {
            // 使用 sessionCreatingPromise 作为锁，避免重复创建
            if (this.sessionCreatingPromise) {
                console.warn('会话已在创建中，请勿重复调用')
                return false
            }

            try {
                this.syncLock = true

                // ✅ 关键修复：优先从 pendingLinkedCustomer 恢复，确保 customerId 不为空
                if (!this.linkedCustomer && this.pendingLinkedCustomer) {
                    this.linkedCustomer = {...this.pendingLinkedCustomer}
                }
                // ✅ 关键修复：获取正确的 customerId（按优先级：this.linkedCustomer > chat.linkedCustomer > pendingLinkedCustomer）
                const customerId = this.linkedCustomer?.id || chat.linkedCustomer?.id || this.pendingLinkedCustomer?.id || null

                // 如果用户已手动编辑标题，使用编辑后的标题，否则使用第一条消息
                const hasManuallyEdited = this.manuallyEditedTitles[chat.id]
                const titleToSave = hasManuallyEdited ? chat.title : message

                const params = {
                    title: titleToSave,
                    customerId: customerId
                }

                // 等待 Promise 完成
                const response = await createChatSession(params)

                if (response.code === 200 && response.data) {
                    const oldId = chat.id
                    const backendSessionId = response.data.sessionId

                    chat.sessionId = backendSessionId
                    chat.isSynced = true
                    chat.linkedCustomerId = customerId

                    // 使用后端返回的 sessionId 更新会话 ID
                    chat.id = this.replaceTempIdWithSessionId(oldId, backendSessionId)

                    // 更新相关映射
                    if (oldId !== chat.id) {
                        // 更新 customerLinkMap
                        if (this.customerLinkMap[oldId]) {
                            this.customerLinkMap[chat.id] = this.customerLinkMap[oldId]
                            delete this.customerLinkMap[oldId]
                        }

                        // 更新 manuallyEditedTitles
                        if (this.manuallyEditedTitles[oldId]) {
                            this.manuallyEditedTitles[chat.id] = this.manuallyEditedTitles[oldId]
                            delete this.manuallyEditedTitles[oldId]
                        }

                        // 更新 currentChatId
                        if (this.currentChatId === oldId) {
                            this.currentChatId = chat.id
                        }
                    }

                    // ✅ 关键修复：确保关联客户与后端一致
                    if (this.linkedCustomer && this.linkedCustomer.id === customerId) {
                        chat.linkedCustomer = {...this.linkedCustomer}
                        this.customerLinkMap[chat.id] = this.linkedCustomer
                    } else if (customerId && chat.linkedCustomer) {
                        // ✅ 修复：如果之前已关联客户但 this.linkedCustomer 为空，从 chat 中恢复
                        this.linkedCustomer = {...chat.linkedCustomer}
                        this.customerLinkMap[chat.id] = chat.linkedCustomer
                    } else if (customerId) {
                        // ✅ 新增：如果有 customerId 但没有客户详情，尝试从其他地方查找
                        const foundChat = this.chatList.find(c => c.linkedCustomerId === customerId && c.linkedCustomer)
                        if (foundChat?.linkedCustomer) {
                            this.linkedCustomer = {...foundChat.linkedCustomer}
                            chat.linkedCustomer = this.linkedCustomer
                            this.customerLinkMap[chat.id] = this.linkedCustomer
                        } else {
                        }
                    } else if (this.pendingLinkedCustomer) {
                        // ✅ 这个情况应该不会被触发了，因为已经在最开始恢复了
                    } else {
                    }

                    // 更新缓存
                    this.cacheSession(chat)

                    return true
                } else {
                    this.$message.error(response.msg || '创建会话失败')
                    return false
                }
            } catch (error) {
                this.$message.error(error.message || '创建会话异常')
                return false
            } finally {
                this.syncLock = false
                // 确保锁释放
                this.sessionCreatingPromise = null
            }
        },

        // 开始编辑会话标题 - 激活输入框并聚焦
        startEditTitle(index, chat) {
            this.$set(chat, 'editingTitle', chat.title)
            this.editingChatIndex = index
            this.isEditingChat = true
            this.$nextTick(() => {
                if (this.$refs.editInput && this.$refs.editInput[index]) {
                    this.$refs.editInput[index].focus()
                    this.$refs.editInput[index].select()
                }
            })
        },

        // 确认编辑会话标题 - 验证并保存新标题
        confirmEditTitle(index) {
            const chat = this.chatList[index]
            if (!chat) return

            const newTitle = (chat.editingTitle || '').trim()
            if (!newTitle) {
                this.$message.warning('标题不能为空')
                chat.editingTitle = chat.title
                this.exitEditMode(chat)
                return
            }

            chat.title = newTitle
            if (chat.id === this.currentChatId) {
                this.currentChatTitle = newTitle
            }

            this.manuallyEditedTitles[chat.id] = true
            this.exitEditMode(chat)
        },

        // 退出编辑模式
        exitEditMode(chat) {
            this.editingChatIndex = -1
            this.isEditingChat = false
            if (chat) {
                delete chat.editingTitle
            }
        },

        // 选择聊天 - 同步加载消息、恢复关联客户和画像缓存
        selectChat(chat) {
            // 如果正在编辑标题，先确认或取消编辑
            if (this.isEditingChat && this.editingChatIndex !== -1) {
                const editingChat = this.chatList[this.editingChatIndex]
                if (editingChat?.editingTitle) {
                    this.confirmEditTitle(this.editingChatIndex)
                } else {
                    this.exitEditMode(null)
                }
            }

            this.clearThinkingTimer()

            // ✅ 关键修复：保存当前会话的关联客户和画像缓存到 map 中
            if (this.currentChatId) {
                if (this.linkedCustomer) {
                    this.customerLinkMap[this.currentChatId] = this.linkedCustomer
                } else {
                    delete this.customerLinkMap[this.currentChatId]
                }
                if (this.linkedCustomer?.customerPortraitJson) {
                    this.customerPortraitCache[this.currentChatId] = this.linkedCustomer.customerPortraitJson
                }
            }

            const oldChatId = this.currentChatId
            this.currentChatId = chat.id
            this.currentChatTitle = chat.title || ''

            // ✅ 关键修复：优先从 customerLinkMap 恢复，其次从 chat.linkedCustomer 恢复
            let linkedCustomer = this.customerLinkMap[chat.id] || chat.linkedCustomer || null

            // ✅ 如果 chat 有 linkedCustomerId 但没有 linkedCustomer，尝试从其他会话中查找
            if (!linkedCustomer && chat.linkedCustomerId) {
                // 从其他会话中查找相同的 customerId
                const foundChat = this.chatList.find(c => c.linkedCustomerId === chat.linkedCustomerId && c.linkedCustomer)
                if (foundChat?.linkedCustomer) {
                    linkedCustomer = foundChat.linkedCustomer
                }
            }

            this.linkedCustomer = linkedCustomer
            // 恢复客户画像缓存
            if (this.customerPortraitCache[chat.id]) {
                if (this.linkedCustomer) {
                    this.linkedCustomer.customerPortraitJson = this.customerPortraitCache[chat.id]
                }
            } else if (linkedCustomer?.customerPortraitJson) {
                this.customerPortraitCache[chat.id] = linkedCustomer.customerPortraitJson
            }

            this.firstMessageSent = chat.messages?.length > 0

            // 同步加载消息：优先从 IndexedDB 加载最新 50 条
            this.isLoadingMore = true

            if (this.dbInitialized && chat.sessionId) {
                const cachedMessages = this.dbGetByIndex('messages', 'sessionId', chat.sessionId)
                if (cachedMessages?.length > 0) {
                    this.messages = cachedMessages
                        .sort((a, b) => b.time - a.time)
                        .slice(0, 50)
                        .reverse()
                    this.hasMoreMessages = cachedMessages.length >= 50
                } else if (chat.messages?.length > 0) {
                    this.messages = chat.messages.slice(-50)
                    this.hasMoreMessages = chat.messages.length > 50
                } else {
                    this.messages = []
                    this.hasMoreMessages = false
                }
            } else if (chat.messages?.length > 0) {
                this.messages = chat.messages.slice(-50)
                this.hasMoreMessages = chat.messages.length > 50
            } else {
                this.messages = []
                this.hasMoreMessages = false
            }

            this.isLoadingMore = false

            this.$nextTick(() => this.scrollToBottom())
        },

        // 发送消息 - 包含防重复发送、批量保存、会话自动创建等机制
        async sendMessage() {
            // 如果 AI 正在思考，禁止发送
            if (this.isAiThinking) {
                this.$message.warning('AI 正在思考中，请等待回复完成后再发送消息')
                return
            }

            if (!this.inputMessage.trim() || this.isLoading) {
                console.warn('消息为空或正在加载，跳过')
                return
            }

            // 如果没有会话列表或当前没有选中的会话，创建新对话
            if (this.chatList.length === 0 || !this.currentChatId) {
                this.createNewChatDirect()
                // 等待会话创建完成再发送消息
                await new Promise(resolve => setTimeout(resolve, 100))
            }

            const currentChat = this.chatList.find(c => c.id === this.currentChatId)
            if (!currentChat) {
                this.$message.error('会话不存在，请重试')
                return
            }

            // 如果是第一条消息且没有 sessionId，先创建后端会话
            if (!currentChat.sessionId) {
                try {
                    // 使用 Promise 锁防止重复创建
                    if (this.sessionCreatingPromise) {
                        await this.sessionCreatingPromise
                    } else {
                        // 创建 Promise 并保存引用
                        this.sessionCreatingPromise = new Promise((resolve, reject) => {
                            this.createBackendSession(currentChat, this.inputMessage)
                                .then(success => resolve(success))
                                .catch(error => reject(error))
                        })

                        const success = await this.sessionCreatingPromise

                        if (!success || !currentChat.sessionId) {
                            throw new Error('创建后端会话失败')
                        }
                    }
                } catch (error) {
                    this.$message.error('创建会话失败，请稍后重试')
                    this.sessionCreatingPromise = null
                    return
                }
            }

            // 保存用户输入
            const userInput = this.inputMessage.trim()

            // 只有未手动编辑过标题且是第一条消息时，才使用第一条消息作为标题
            const hasManuallyEdited = this.manuallyEditedTitles[currentChat.id]
            if (!hasManuallyEdited && !this.firstMessageSent) {
                const newTitle = userInput.substring(0, 50) + (userInput.length > 50 ? '...' : '')
                currentChat.title = newTitle
                this.currentChatTitle = newTitle
                // 异步更新后端标题
                if (currentChat.sessionId) {
                    this.updateBackendSessionTitle(currentChat.sessionId, newTitle).catch(err => {
                        console.error('更新后端标题失败:', err)
                    })
                }
            } else if (hasManuallyEdited) {
            }

            // 创建用户消息对象
            const userMessage = {
                type: 'user',
                content: userInput,
                time: Date.now(),
                isSynced: false,
                tempId: 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
            }

            // 立即添加到消息列表并显示
            this.messages.push(userMessage)

            // 立即清空输入框
            this.inputMessage = ''

            // 设置加载状态
            this.isLoading = true
            // 标记 AI 开始思考
            this.isAiThinking = true
            this.aiThinkingStartTime = Date.now()
            this.aiThinkingDuration = 0

            // 启动计时器
            if (this.thinkingTimer) {
                clearInterval(this.thinkingTimer)
            }
            this.thinkingTimer = setInterval(() => {
                this.aiThinkingDuration = Date.now() - this.aiThinkingStartTime
            }, 100)

            // 标记已发送第一条消息
            this.firstMessageSent = true

            // 立即滚动到底部
            this.$nextTick(() => {
                this.scrollToBottom()
            })

            // 将消息加入队列，延迟批量保存
            this.queueMessage(userMessage)

            // 调用 AI 接口获取回复
            setTimeout(async () => {
                await this.getAIResponse(userInput)
            }, 1000)
        },

        // 获取 AI 回复 - 包含思考时长统计、错误重试机制
        getAIResponse(userInput) {
            if (this.syncLock) {
                console.warn('AI 回复中，请稍后')
                return
            }

            try {
                this.syncLock = true

                // 组装调用 AI 接口的参数
                const param = {
                    chatId: this.currentChatId,
                    content: userInput,
                    portrait: this.aiPortraitData
                }

                getAiReply(param).then(response => {
                    if (response.code === 200) {
                        // 计算思考耗时
                        const thinkingDuration = Date.now() - this.aiThinkingStartTime

                        // 停止计时器并重置状态
                        this.clearThinkingTimer()

                        // 创建 AI 消息对象
                        const aiMessage = {
                            type: 'ai',
                            time: Date.now(),
                            isSynced: false,
                            tempId: 'ai_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9),
                            thinkingDuration: thinkingDuration,
                            contentType: response.data.contentType,
                            content: response.data.content,
                            metadata: response.data.metadata,
                            tokenCount: response.data.tokenCount,
                            modelName: response.data.modelName,
                            costTime: response.data.costTime,
                            status: response.data.status
                        }

                        // 立即添加到消息列表
                        this.messages.push(aiMessage)

                        // 立即关闭加载状态
                        this.isLoading = false

                        // 将 AI 回复也加入队列保存
                        this.queueMessage(aiMessage)

                        // 更新当前聊天的消息列表
                        const currentChat = this.chatList.find(c => c.id === this.currentChatId)
                        if (currentChat) {
                            // 深拷贝消息数组，避免引用问题
                            currentChat.messages = [...this.messages]
                            // 将当前对话移动到最前面
                            const index = this.chatList.indexOf(currentChat)
                            if (index > 0) {
                                this.chatList.splice(index, 1)
                                this.chatList.unshift(currentChat)
                            }
                            // 更新缓存
                            this.cacheSession(currentChat)
                        }

                        // 立即滚动到底部
                        this.$nextTick(() => {
                            this.scrollToBottom()
                        })
                    }
                }).catch(error => {
                    // 异常时也重置状态
                    this.clearThinkingTimer()
                    this.isLoading = false
                    this.$message.error('获取 AI 回复失败:' + error)
                });
            } catch (error) {
                this.clearThinkingTimer()
                this.isLoading = false
                this.$message.error('获取 AI 回复异常:' + error)
            } finally {
                this.syncLock = false
            }
        },

        // 滚动到底部 - 平滑滚动到消息列表底部
        scrollToBottom() {
            const container = this.$refs.messagesContainer
            if (container) {
                this.$nextTick(() => {
                    container.scrollTop = container.scrollHeight
                })
            }
        },

        // 格式化时间 - 智能显示相对时间
        formatTime(timestamp) {
            const date = new Date(timestamp)
            const now = new Date()
            const diff = now.getTime() - date.getTime()

            // 今天
            if (diff < 86400000 && date.getDate() === now.getDate()) {
                const hours = date.getHours().toString().padStart(2, '0')
                const minutes = date.getMinutes().toString().padStart(2, '0')
                return `今天 ${hours}:${minutes}`
            }

            // 昨天
            const yesterday = new Date(now)
            yesterday.setDate(yesterday.getDate() - 1)
            if (date.getDate() === yesterday.getDate() &&
                date.getMonth() === yesterday.getMonth() &&
                date.getFullYear() === yesterday.getFullYear()) {
                return '昨天'
            }

            // 更早
            const month = (date.getMonth() + 1).toString().padStart(2, '0')
            const day = date.getDate().toString().padStart(2, '0')
            return `${month}-${day}`
        },

        // 格式化思考耗时 - 毫秒转秒显示
        formatThinkingTime(ms) {
            if (ms < 1000) {
                return `${ms}ms`
            } else {
                const seconds = (ms / 1000).toFixed(1)
                return `${seconds}s`
            }
        },

        // 格式化消息内容（支持简单的 markdown，XSS 防护）
        formatMessage(content) {
            if (!content) return ''

            // XSS 防护：转义 HTML 特殊字符
            let formatted = content
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#39;')

            // 移除危险的 protocol
            formatted = formatted.replace(/(javascript|data|vbscript):/gi, '$1:')
            // 移除 on* 事件处理器
            formatted = formatted.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '')
                .replace(/\s*on\w+\s*=\s*[^\s>]*/gi, '')
            // 移除危险标签
            formatted = formatted.replace(/<\/??\s*(script|iframe|object|embed|form|input|textarea|button|select|option)[^>]*>/gi, '')

            // 换行转<br>
            formatted = formatted.replace(/\n/g, '<br>')
            // **bold** 转粗体
            formatted = formatted.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
            // *italic* 转斜体
            formatted = formatted.replace(/\*(.+?)\*/g, '<em>$1</em>')

            return formatted
        },

        // 格式化用户消息（XSS 防护）
        formatUserMessage(content) {
            if (!content) return ''

            // XSS 防护：转义 HTML 特殊字符
            let formatted = content
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#39;')

            // 移除危险的 protocol 和事件处理器
            formatted = formatted.replace(/(javascript|data|vbscript):/gi, '$1:')
                .replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, '')
                .replace(/\s*on\w+\s*=\s*[^\s>]*/gi, '')
                .replace(/<\/??\s*(script|iframe|object|embed|form|input|textarea|button|select|option)[^>]*>/gi, '')

            // 换行转<br>
            return formatted.replace(/\n/g, '<br>')
        },

        // 关闭会话
        async closeChat(index) {
            const chat = this.chatList[index]

            // 如果关闭的是当前选中的会话
            if (this.currentChatId === chat.id) {
                if (index > 0) {
                    this.selectChat(this.chatList[index - 1])
                } else if (this.chatList.length > 1) {
                    this.selectChat(this.chatList[1])
                } else {
                    // 关闭最后一个会话，清空所有状态
                    this.resetAllState()
                }
            }

            // 删除会话的关联客户映射
            delete this.customerLinkMap[chat.id]
            delete this.customerPortraitCache[chat.id]

            // 删除会话
            this.chatList.splice(index, 1)

            // 调用后端 API 删除会话
            if (chat.sessionId) {
                try {
                    deleteChatSession(chat.sessionId).then(response => {
                        if (response.code !== 200) {
                            this.$message.error('会话从本地删除失败')
                        }
                    });
                } catch (error) {
                    this.$message.error('会话已从本地删除，但服务器端删除失败')
                }
            }

            // 清理 IndexedDB 中的该会话数据
            if (chat.sessionId && this.dbInitialized) {
                this.dbDelete('sessions', chat.id).catch(err => {
                    console.error('删除会话失败:', err)
                })

                this.dbGetByIndex('messages', 'sessionId', chat.sessionId).then(msgs => {
                    if (msgs?.length > 0) {
                        Promise.all(
                            msgs.map(msg => this.dbDelete('messages', msg.tempId))
                        ).catch(err => {
                            console.error('删除消息失败:', err)
                        })
                    }
                }).catch(err => {
                    console.error('查询消息失败:', err)
                })
            }

            // 清理 localStorage
            this.cacheSessionList()
            this.$message.success('会话已删除')
        },

        // 重置所有状态
        resetAllState() {
            this.currentChatId = null
            this.messages = []
            this.linkedCustomer = null
            this.currentChatTitle = ''
            this.customerLinkMap = {}
            this.customerPortraitCache = {}
            this.firstMessageSent = false
            this.manuallyEditedTitles = {}
            this.clearThinkingTimer()
            this.clearSaveTimer()
        },

        // 头像加载失败处理
        handleAvatarError(event) {
            event.target.style.display = 'none'
            event.target.parentElement.innerHTML = '<i class="el-icon-user" style="font-size: 20px; color: white;"></i>'
        },

        // 关联客户
        linkCustomer() {
            this.customerDialogVisible = true
            // 重置到第一页
            this.customerPagination.pageNum = 1
            // 重置筛选条件
            this.resetCustomerFilter()
        },

        // 获取客户列表
        getCustomerList() {
            this.customerLoading = true
            const params = {
                pageNum: this.customerPagination.pageNum,
                pageSize: this.customerPagination.pageSize
            }
            // 添加筛选条件
            if (this.customerFilter.customerName) {
                params.customerName = this.customerFilter.customerName
            }
            if (this.customerFilter.attritionLevel !== null && this.customerFilter.attritionLevel !== undefined) {
                params.attritionLevel = this.customerFilter.attritionLevel
            }
            listAllAnalyze(params).then(response => {
                this.customerList = response.data.list || []
                this.customerPagination.total = response.data.total || 0
                this.customerLoading = false
            }).catch(() => {
                this.customerLoading = false
            })
        },

        // 处理客户筛选（SQL 注入防护）
        handleCustomerFilter() {
            // ✅ 过滤特殊字符，防止 SQL 注入
            const customerName = this.customerFilter.customerName?.trim()
            if (customerName) {
                // 只允许字母、数字、中文、下划线、短横线
                if (!/^[\w\u4e00-\u9fa5-]+$/.test(customerName)) {
                    this.$message.warning('客户名称包含非法字符，请重新输入')
                    return
                }
            }

            this.customerPagination.pageNum = 1
            this.getCustomerList()
        },

        // 重置客户筛选
        resetCustomerFilter() {
            this.customerFilter.customerName = ''
            this.customerFilter.attritionLevel = null
            this.customerPagination.pageNum = 1
            this.getCustomerList()
        },

        // 处理客户分页
        handleCustomerPageChange(page) {
            this.customerPagination.pageNum = page
            this.getCustomerList()
        },

        // 点击选择按钮选择客户（增强实时性 + 修复客户 ID 保存）
        selectCustomerByClick(customer) {
            if (customer) {
                const newLinkedCustomer = {
                    id: customer.customerId,
                    name: customer.customerName,
                    attritionLevel: customer.attritionLevel,
                    intentionDegree: customer.intentionDegree,
                    customerPortraitJson: customer.customerPortraitJson
                }

                // ✅ 立即更新当前关联客户
                this.linkedCustomer = newLinkedCustomer

                // ✅ 保存到 pendingLinkedCustomer，确保新建会话时不会丢失
                this.pendingLinkedCustomer = newLinkedCustomer

                // ✅ 更新当前会话的关联客户（包括 linkedCustomerId）
                const currentChat = this.chatList.find(c => c.id === this.currentChatId)
                if (currentChat) {
                    currentChat.linkedCustomer = {...newLinkedCustomer}
                    currentChat.linkedCustomerId = customer.customerId // ✅ 关键修复：设置持久化 ID
                    this.cacheSession(currentChat)

                    // ✅ 调用后端 API 更新会话的客户关联
                    if (currentChat.sessionId) {
                        updateChatSessionCustomer(currentChat.sessionId, customer.customerId)
                            .then(() => {
                            })
                            .catch(error => {
                                this.$message.warning('客户关联已更新，但保存到服务器失败:' + error)
                            })
                    } else {
                    }
                }

                // ✅ 更新 customerLinkMap
                if (this.currentChatId) {
                    this.customerLinkMap[this.currentChatId] = newLinkedCustomer
                }

                this.customerDialogVisible = false

                // ✅ 强制刷新视图
                this.$forceUpdate()
            }
        },
        // 获取图标类名
        getIconClass(key) {
            const iconMap = {
                '性别': 'fas fa-venus-mars',
                '年龄': 'fas fa-calendar-alt',
                '职业': 'fas fa-briefcase',
                '地区': 'fas fa-map-marker-alt',
                '来源': 'fas fa-source',
                '意向度': 'fas fa-heart',
                '备注': 'fas fa-sticky-note'
            };
            return iconMap[key] || 'fas fa-info-circle';
        },

        // 取消选择客户（安全清理）
        cancelSelectCustomer() {
            this.customerDialogVisible = false
            this.selectedCustomerId = null
            // ✅ 清空筛选条件，防止数据泄露
            this.customerFilter.customerName = ''
            this.customerFilter.attritionLevel = null
        },

        // 获取流失风险等级文本
        getAttritionLevelText(level) {
            const levelMap = {
                0: '未知',
                1: '无风险',
                2: '低风险',
                3: '中风险',
                4: '高风险'
            }
            return levelMap[level] !== undefined ? levelMap[level] : '未知'
        },

        // 获取流失风险等级标签类型
        getAttritionLevelTagType(level) {
            const typeMap = {
                0: 'info', // 未知
                1: 'success', // 无风险
                2: '', // 低风险
                3: 'warning', // 中风险
                4: 'danger' // 高风险
            }
            return typeMap[level] !== undefined ? typeMap[level] : 'info'
        },

        // 处理表格行选择（单选）
        handleCurrentChange(val) {
            if (val) {
                this.selectedCustomerId = val.customerId
            }
        },

        // 取消关联客户
        unlinkCustomer() {
            this.linkedCustomer = null

            // 同步清理当前会话的关联客户
            const currentChat = this.chatList.find(c => c.id === this.currentChatId)
            if (currentChat) {
                currentChat.linkedCustomer = null
                this.cacheSession(currentChat)
            }

            // 清理 customerLinkMap
            if (this.currentChatId) {
                delete this.customerLinkMap[this.currentChatId]
            }

            this.$message.success('已取消关联客户')
        },

        // 清除会话缓存
        clearChatCache(index, chat) {
            this.$confirm(`确定要清除会话"${chat.title}"的缓存吗？清除后将无法查看历史消息。`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                try {
                    // 1. 清理 IndexedDB 中的消息
                    if (this.dbInitialized && chat.sessionId) {
                        const messages = this.dbGetByIndex('messages', 'sessionId', chat.sessionId)
                        if (messages && messages.length > 0) {
                            messages.forEach(msg => this.dbDelete('messages', msg.tempId))
                        }
                    }

                    // 2. 清空本地消息数组
                    chat.messages = []

                    // 3. 如果清除的是当前选中的会话，同步清空显示
                    if (chat.id === this.currentChatId) {
                        this.messages = []
                    }

                    // 4. 更新缓存
                    this.cacheSession(chat)

                    this.$message.success('缓存已清除')
                } catch (error) {
                    this.$message.error('清除缓存失败，原因:' + error)
                }
            }).catch(() => {
                // 用户取消
            })
        },

        // 置顶会话
        pinChat(index) {
            if (index === 0) return // 第一个不需要置顶

            const chat = this.chatList[index]
            // 从当前位置移除
            this.chatList.splice(index, 1)
            // 添加到第一个位置
            this.chatList.unshift(chat)
            this.$message.success('会话已置顶')

            // 异步更新后端置顶状态
            if (chat.sessionId) {
                pinChatSession(chat.sessionId, 1).catch(err => {
                    console.error('更新置顶状态失败:', err)
                })
            }
        },

        // 将消息加入队列（智能批量保存 + 确保 sessionId 唯一性）
        async queueMessage(message) {
            const currentChat = this.chatList.find(c => c.id === this.currentChatId)

            // ✅ 验证 sessionId 是否存在
            if (!currentChat) {
                this.$message.error('会话不存在，无法保存消息')
                return
            }

            if (!currentChat.sessionId) {
                console.warn('sessionId 不存在，等待会话创建')
                await new Promise(resolve => setTimeout(resolve, 100))
                if (!currentChat.sessionId) {
                    this.$message.error('会话初始化失败，请重试')
                    return
                }
            }

            const tempId = message.tempId || ('msg_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9))
            this.messageQueue.push({
                ...message,
                sessionId: currentChat.sessionId,
                tempId: tempId,
                retryCount: 0
            })
            this.pendingSaveCount++

            // 清除之前的定时器
            if (this.saveTimer) {
                clearTimeout(this.saveTimer)
            }

            // 智能保存策略：
            // 1. 达到阈值立即保存
            // 2. 否则延迟保存，延迟时间随消息数量动态调整
            if (this.pendingSaveCount >= this.maxBatchSize) {
                this.flushMessageQueue()
            } else {
                // 动态延迟：消息越少等待时间越长，最多 3 秒
                const dynamicDelay = Math.min(this.saveDelay * (this.maxBatchSize / this.pendingSaveCount), 3000)
                this.saveTimer = setTimeout(() => {
                    this.flushMessageQueue()
                }, dynamicDelay)
            }
        },

        // 批量刷新消息队列到后端（带重试机制）
        async flushMessageQueue() {
            if (this.isSaving || this.messageQueue.length === 0) return

            this.isSaving = true

            try {
                const currentChat = this.chatList.find(c => c.id === this.currentChatId)

                // ✅ 确保 sessionId 存在
                if (!currentChat || !currentChat.sessionId) {
                    console.error('flushMessageQueue: sessionId 不存在')
                    this.isSaving = false
                    return
                }

                // 只处理需要发送的消息（重试次数<3）
                const messagesToSend = this.messageQueue.filter(msg => msg.retryCount < 3)

                if (messagesToSend.length === 0) {
                    // 所有消息都超过重试次数，清空队列
                    this.messageQueue = []
                    this.pendingSaveCount = 0
                    this.isSaving = false
                    this.$message.warning('部分消息保存失败，请检查网络连接')
                    return
                }

                // 从队列移除
                this.messageQueue = this.messageQueue.filter(msg => msg.retryCount >= 3)
                this.pendingSaveCount = this.messageQueue.length

                // 批量保存消息
                const saveData = messagesToSend.map(msg => ({
                    sessionId: currentChat.sessionId,
                    senderType: msg.type === 'user' ? 1 : 2,
                    contentType: 1,
                    content: msg.content,
                    metadata: msg.metadata ? JSON.stringify(msg.metadata) : null
                }))


                const response = await batchSaveMessages({messages: saveData})


                if (response.code === 0 || response.code === 200) {
                    // 标记消息为已同步
                    messagesToSend.forEach(msg => {
                        const message = this.messages.find(m => m.tempId === msg.tempId)
                        if (message) {
                            message.isSynced = true
                        }
                    })

                    // 保存到 IndexedDB（异步，不阻塞）
                    if (this.dbInitialized) {
                        const messagesToSave = messagesToSend.map(msg => ({
                            sessionId: currentChat.sessionId,
                            type: msg.type,
                            content: msg.content,
                            time: msg.time,
                            isSynced: true,
                            metadata: msg.metadata
                        }))

                        // 并行保存所有消息
                        await Promise.all(
                            messagesToSave.map(msg => this.dbAdd('messages', msg))
                        )
                    }

                } else {
                    throw new Error(response.msg || '保存失败')
                }
            } catch (error) {
                console.error('批量保存消息失败:', error)

                // 指数退避重试
                try {
                    if (typeof messagesToSend !== 'undefined' && messagesToSend.length > 0) {
                        messagesToSend.forEach(msg => {
                            msg.retryCount++
                            this.messageQueue.push(msg)
                        })
                        this.pendingSaveCount += messagesToSend.length

                        // 如果有消息重试超过 3 次，提示用户
                        const failedMessages = this.messageQueue.filter(msg => msg.retryCount >= 3)
                        if (failedMessages.length > 0 && failedMessages.length === this.messageQueue.length) {
                            this.$message.error('消息保存失败，请检查网络连接')
                        }
                    }
                } catch (innerError) {
                    this.$message.error('处理重试消息失败:', innerError)
                }
            } finally {
                this.isSaving = false
            }
        },

        // 从后端加载会话列表（优先显示置顶会话）
        loadSessionsFromBackend() {
            getChatSessionList({pageNum: 1, pageSize: 10})
                .then(response => {
                    if (response.code === 200 && response.rows && response.rows.length > 0) {
                        const backendSessions = response.rows

                        // ✅ 转换为前端会话格式
                        this.chatList = backendSessions.map(session => ({
                            id: this.generateUniqueId(session.sessionId),
                            title: session.title || '未命名会话',
                            time: new Date(session.createTime).getTime(),
                            sessionId: session.sessionId,
                            isSynced: true,
                            linkedCustomerId: session.customerId || null,
                            linkedCustomer: null,
                            messages: (session.messageList || [])
                                .sort((a, b) => {
                                    const timeA = new Date(a.createTime).getTime()
                                    const timeB = new Date(b.createTime).getTime()
                                    if (timeA === timeB) {
                                        return (a.senderType === 1 ? -1 : 1) - (b.senderType === 1 ? -1 : 1)
                                    }
                                    return timeA - timeB
                                })
                                .map(msg => ({
                                    type: msg.senderType === 1 ? 'user' : 'ai',
                                    content: msg.content,
                                    time: new Date(msg.createTime).getTime(),
                                    isSynced: true,
                                    metadata: msg.metadata ? JSON.parse(msg.metadata) : null
                                }))
                        }))

                        // ✅ 清空旧缓存并写入新数据
                        this.clearAllCache()
                        this.cacheSessionList()

                        // ✅ 加载所有会话的关联客户信息
                        if (this.chatList.length > 0) {
                            const customerIds = this.chatList
                                .filter(chat => chat.linkedCustomerId)
                                .map(chat => chat.linkedCustomerId)

                            if (customerIds.length > 0) {
                                listAllAnalyze({
                                    customerIds: customerIds,
                                    pageNum: 1,
                                    pageSize: 10
                                }).then(response => {
                                    // ✅ 关键修复：接口返回的是 response.data.list
                                    if (response.data && response.data.list && response.data.list.length > 0) {
                                        const customersMap = {}
                                        response.data.list.forEach(customer => {
                                            customersMap[customer.customerId] = {
                                                id: customer.customerId,
                                                name: customer.customerName,
                                                attritionLevel: customer.attritionLevel,
                                                intentionDegree: customer.intentionDegree,
                                                customerPortraitJson: customer.customerPortraitJson
                                            }
                                        })

                                        // 为每个会话恢复关联客户
                                        this.chatList.forEach(chat => {
                                            if (chat.linkedCustomerId && customersMap[chat.linkedCustomerId]) {
                                                const linkedCustomer = customersMap[chat.linkedCustomerId]
                                                chat.linkedCustomer = linkedCustomer
                                                this.customerLinkMap[chat.id] = linkedCustomer

                                                if (linkedCustomer.customerPortraitJson) {
                                                    this.customerPortraitCache[chat.id] = linkedCustomer.customerPortraitJson
                                                }
                                            }
                                        })

                                        // ✅ 选择第一个会话（置顶的）
                                        const firstChat = this.chatList[0]
                                        this.selectChat(firstChat)
                                    } else {
                                        const firstChat = this.chatList[0]
                                        this.selectChat(firstChat)
                                    }
                                }).catch(error => {
                                    console.error('批量加载关联客户失败:', error)
                                    const firstChat = this.chatList[0]
                                    this.selectChat(firstChat)
                                })
                            } else {
                                const firstChat = this.chatList[0]
                                this.selectChat(firstChat)
                            }
                        }
                    } else {
                        this.currentChatId = null
                        this.messages = []
                        this.currentChatTitle = ''
                        this.linkedCustomer = null
                        this.customerLinkMap = {}
                    }
                })
                .catch(error => {
                    this.$message.error('加载会话列表失败，请稍后重试')
                })
        },

        // 清空所有缓存
        clearAllCache() {
            try {
                // 清空 IndexedDB
                if (this.dbInitialized && this.db) {
                    const sessions = this.dbGetAll('sessions')
                    if (sessions?.length > 0) {
                        sessions.forEach(s => this.dbDelete('sessions', s.id))
                    }

                    const messages = this.dbGetAll('messages')
                    if (messages?.length > 0) {
                        messages.forEach(m => this.dbDelete('messages', m.tempId))
                    }
                }

                // 清空 localStorage 中所有相关缓存
                Object.keys(localStorage).forEach(key => {
                    if (key.startsWith(this.localCacheKey)) {
                        localStorage.removeItem(key)
                    }
                })

                // 清空内存缓存
                this.customerPortraitCache = {}
                this.customerLinkMap = {}
                this.retryCounts = {}
                this.messageCursor = {}

            } catch (error) {
                console.error('清空缓存失败:', error)
            }
        },


        // 缓存会话列表到本地（只缓存元数据，不缓存消息）
        cacheSessionList() {
            try {
                // 更新 IndexedDB（只存会话元数据）
                if (this.dbInitialized) {
                    const sessionsToSave = this.chatList.map(c => ({
                        id: c.id,
                        title: c.title,
                        time: c.time,
                        sessionId: c.sessionId,
                        isSynced: c.isSynced,
                        linkedCustomerId: c.linkedCustomer?.id || null
                    }))

                    // 同步保存会话
                    sessionsToSave.forEach(s => this.dbPut('sessions', s))
                }

                // 降级到 localStorage（只存元数据，减小体积）
                const sessionsToCache = this.chatList.map(c => ({
                    id: c.id,
                    title: c.title,
                    time: c.time,
                    sessionId: c.sessionId,
                    isSynced: c.isSynced,
                    linkedCustomerId: c.linkedCustomer?.id || null
                }))
                localStorage.setItem(
                    this.localCacheKey + 'sessions',
                    JSON.stringify(sessionsToCache)
                )
            } catch (error) {
                console.error('缓存会话列表失败:', error)
            }
        },

        // 缓存会话到本地（只缓存元数据，不缓存消息）
        cacheSession(chat) {
            try {
                const index = this.chatList.findIndex(c => c.id === chat.id)
                if (index !== -1) {
                    this.chatList[index] = chat
                }

                // 更新缓存的会话列表
                this.cacheSessionList()
            } catch (error) {
                console.error('缓存会话失败:', error)
            }
        },

        // 异步更新后端会话标题
        async updateBackendSessionTitle(sessionId, title) {
            try {
                await updateChatSessionTitle({sessionId, title})
            } catch (error) {
                console.error('更新会话标题失败:', error)
            }
        },

        // ✅ 清理思考计时器
        clearThinkingTimer() {
            if (this.thinkingTimer) {
                clearInterval(this.thinkingTimer)
                this.thinkingTimer = null
            }
            this.isAiThinking = false
            this.aiThinkingDuration = 0
        },

        // ✅ 清理保存定时器
        clearSaveTimer() {
            if (this.saveTimer) {
                clearTimeout(this.saveTimer)
                this.saveTimer = null
            }
            this.isSaving = false
            this.pendingSaveCount = 0
        },

        // 加载更多历史消息（分页加载）
        loadMoreMessages() {
            if (this.isLoadingMore || !this.hasMoreMessages) return

            const currentChat = this.chatList.find(c => c.id === this.currentChatId)
            if (!currentChat || !currentChat.sessionId) return

            this.isLoadingMore = true

            try {
                // 从 IndexedDB 加载更多
                if (this.dbInitialized) {
                    const allMessages = this.dbGetByIndex('messages', 'sessionId', currentChat.sessionId)
                    if (allMessages && allMessages.length > this.messages.length) {
                        // 计算已加载的数量
                        const loadedCount = this.messages.length
                        const moreMessages = allMessages
                            .sort((a, b) => b.time - a.time) // 按时间倒序
                            .slice(loadedCount, loadedCount + 50) // 再加载 50 条
                            .reverse() // 正序显示

                        if (moreMessages.length > 0) {
                            this.messages.unshift(...moreMessages)
                            this.hasMoreMessages = loadedCount + moreMessages.length < allMessages.length
                        } else {
                            this.hasMoreMessages = false
                        }
                    } else {
                        this.hasMoreMessages = false
                    }
                } else {
                    // 降级到后端 API
                    const cursor = this.messageCursor[currentChat.id] || Date.now()
                    getChatMessageList({
                        sessionId: currentChat.sessionId,
                        cursor: cursor,
                        limit: 50,
                        direction: 'before'
                    }).then(response => {
                        if (response.code === 0 && response.data.length > 0) {
                            const historyMessages = response.data.map(msg => ({
                                type: msg.senderType === 1 ? 'user' : 'ai',
                                content: msg.content,
                                time: new Date(msg.createTime).getTime(),
                                isSynced: true,
                                metadata: msg.metadata ? JSON.parse(msg.metadata) : null
                            }))

                            this.messages.unshift(...historyMessages)

                            const oldestMsg = historyMessages[historyMessages.length - 1]
                            this.messageCursor[currentChat.id] = oldestMsg.time

                            if (response.data.length < 50) {
                                this.hasMoreMessages = false
                            }
                        } else {
                            this.hasMoreMessages = false
                        }
                    }).catch(error => {
                        console.error('加载更多消息失败:', error)
                    }).finally(() => {
                        this.isLoadingMore = false
                    })

                }
            } catch (error) {
                console.error('加载更多消息失败:', error)
            } finally {
                this.isLoadingMore = false
            }
        },

        // 监听滚动，触发加载更多
        handleScroll(event) {
            const container = event.target
            if (container.scrollTop < 100 && !this.isLoadingMore) {
                this.loadMoreMessages()
            }
        },

    },
    mounted() {
        // ✅ 绑定滚动事件监听
        const container = this.$refs.messagesContainer
        if (container) {
            container.addEventListener('scroll', this.handleScroll, {passive: true})
        }
    },
    beforeDestroy() {

        // 移除滚动事件监听
        const container = this.$refs.messagesContainer
        if (container) {
            container.removeEventListener('scroll', this.handleScroll)
        }

        // 清除所有定时器
        this.clearThinkingTimer()
        this.clearSaveTimer()

        // 确保所有消息都已保存
        if (this.messageQueue.length > 0) {
            this.flushMessageQueue()
        }

        // 关闭 IndexedDB 连接
        if (this.db) {
            this.db.close()
            this.db = null
            this.dbInitialized = false
        }

        // 清空所有缓存和数据
        this.customerPortraitCache = {}
        this.customerLinkMap = {}
        this.chatList = []
        this.messages = []
        this.messageQueue = []
        this.retryCounts = {}
        this.messageCursor = {}
        this.linkedCustomer = null
        this.pendingLinkedCustomer = null

        // 清空 localStorage 中的缓存
        Object.keys(localStorage).forEach(key => {
            if (key.startsWith(this.localCacheKey)) {
                localStorage.removeItem(key)
            }
        })

    }
}
</script>

<style lang="scss" scoped>
.ai-chat-container {
    height: 100%;
    width: 100%;
    display: flex;
    background: #f9fafb;
}

.chat-main {
    display: flex;
    width: 100%;
    height: 100%;
}

/* 左侧边栏 */
.sidebar {
    width: 260px;
    min-width: 260px;
    background: #f9f9fb;
    border-right: 1px solid #e5e5ea;
    display: flex;
    flex-direction: column;
}

.sidebar-header {
    padding: 16px;
    border-bottom: 1px solid #e5e5ea;
}

.new-chat-btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 16px;
    background: white;
    color: #1c1c1c;
    border: 1px solid #e5e5ea;
    border-radius: 8px;
    cursor: pointer;
    font-size: 14px;
    transition: all 0.2s ease;

    &:hover {
        background: #f5f5f5;
        border-color: #d4d4d4;
    }
}

.chat-list {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
}

.chat-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    margin-bottom: 4px;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s ease;
    position: relative;

    &:hover {
        background: #f3f4f6;

        .chat-item-actions {
            opacity: 1;
        }
    }

    &.active {
        background: #e8f4ff; // ✅ 当前选中会话的浅蓝色背景
    }
}

.chat-item-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    opacity: 0;
    transition: opacity 0.2s ease;
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
}

// 会话操作按钮通用样式
.chat-item-action-icon {
    font-size: 14px;
    color: #9ca3af;
    cursor: pointer;
    padding: 6px;
    border-radius: 6px;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

.chat-item-clear-cache {
    @extend .chat-item-action-icon;

    &:hover {
        background: #fef3c7;
        color: #f59e0b;
    }
}

.chat-item-close {
    @extend .chat-item-action-icon;

    &:hover {
        background: #fee2e2;
        color: #ef4444;
    }
}

.chat-item-pin {
    @extend .chat-item-action-icon;

    &:hover {
        background: #fef3c7;
        color: #f59e0b;
    }
}

.chat-item-edit {
    @extend .chat-item-action-icon;

    &:hover {
        background: #dbeafe;
        color: #3b82f6;
    }
}

.chat-item-icon {
    /* 已移除，预留位置 */
}

.chat-item-content {
    flex: 1;
    overflow: hidden;
}

.chat-item-title {
    font-size: 14px;
    color: #1c1c1c;
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;

    &:hover {
        background: rgba(0, 0, 0, 0.05);
        border-radius: 4px;
        padding: 2px 4px;
        margin: -2px -4px;
    }
}

.chat-title-input {
    ::v-deep .el-input__inner {
        padding: 4px 8px;
        font-size: 14px;
        height: 28px;
    }
}

.chat-item-time {
    font-size: 12px;
    color: #999;
}
.chat-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: white;
    height: calc(100vh - 90px);
    overflow: hidden;
    position: relative;
}

// 客户画像面板 - 悬浮卡片设计
.customer-portrait-panel {
    position: absolute;
    top: 50%;
    left: 12px;
    transform: translateY(-50%);
    width: 320px;
    background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
    border-radius: 16px;
    padding: 16px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(209, 213, 219, 0.5);
    z-index: 100;
    max-height: calc(100vh - 320px);
    display: flex;
    flex-direction: column;
    backdrop-filter: blur(8px);
}

@keyframes slideInLeft {
    from {
        opacity: 0;
        transform: translateX(-30px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

.profile-grid {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.profile-scroll-content {
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-height: 0;
    margin-top: 8px;
    padding-top: 0;
}

// 滚动条美化
.profile-scroll-content::-webkit-scrollbar {
    width: 6px;
}

.profile-scroll-content::-webkit-scrollbar-track {
    background: transparent;
}

.profile-scroll-content::-webkit-scrollbar-thumb {
    background: #bae6fd;
    border-radius: 3px;

    &:hover {
        background: #7dd3fc;
    }
}

.profile-item-sticky {
    position: sticky;
    top: 0;
    z-index: 1;
    background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
    border-color: #bfdbfe;
    box-shadow: 0 2px 8px rgba(186, 230, 253, 0.25);
    border-radius: 8px;
    margin-bottom: 8px;
}

// 画像项通用样式
.profile-item-base {
    display: grid;
    grid-template-columns: 85px 1fr;
    align-items: flex-start;
    gap: 5px;
    padding: 6px 10px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.85);
    transition: all 0.2s ease;

    &:hover {
        background: rgba(255, 255, 255, 0.95);
        transform: translateX(2px);
    }
}

.profile-item {
    @extend .profile-item-base;
}

.profile-item-main {
    @extend .profile-item-base;
    background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);

    &:hover {
        background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
    }
}

.profile-item-full {
    grid-template-columns: 85px 1fr;
}

// 标签和值的通用样式
.label-base {
    font-size: 13px;
    color: #0f172a;
    font-weight: 600;
    white-space: normal;
    word-break: break-all;
    max-width: 85px;
    display: flex;
    align-items: center;
    gap: 6px;
    line-height: 1.4;

    i {
        color: #0ea5e9;
        font-size: 14px;
        width: 14px;
        text-align: center;
        flex-shrink: 0;
    }
}

.value-base {
    font-size: 14px;
    color: #0369a1;
    font-weight: 600;
    word-break: break-word;
    line-height: 1.5;
    min-width: 0;
}

.label {
    @extend .label-base;
}

.value {
    @extend .value-base;

    &.highlight {
        color: #dc2626;
        font-weight: 600;
        font-size: 15px;
    }

    &.long-text {
        color: #334155;
        font-weight: 400;
    }

    &.empty-tip {
        color: #94a3b8;
        font-style: italic;
        font-size: 14px;
    }
}

// 聊天标题头部
.chat-title-header {
    position: sticky;
    top: 0;
    left: 0;
    right: 0;
    background: white;
    padding: 20px 24px;
    border-bottom: 1px solid #f0f0f0;
    z-index: 10;
    text-align: center;
}

.chat-title-text {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #1c1c1c;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
    letter-spacing: -0.02em;
}

.messages-container {
    flex: 1;
    overflow-y: auto;
    padding: 24px;
    scroll-behavior: smooth;
    max-width: 768px;
    margin: 0 auto;
    width: 100%;
    position: relative;
}

// 欢迎界面
.welcome-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    min-height: 400px;
    animation: fadeIn 0.5s ease;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.welcome-avatar {
    width: 120px;
    height: 120px;
    margin-bottom: 24px;
    animation: float 3s ease-in-out infinite;
}

@keyframes float {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-10px);
    }
}

.welcome-avatar-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.welcome-text {
    font-size: 28px;
    font-weight: 600;
    color: #1c1c1c;
    text-align: center;
    letter-spacing: 0.5px;
}


.message-row {
    display: flex;
    margin-bottom: 24px;

    &.message-user {
        justify-content: flex-end;
    }

    &.message-ai {
        justify-content: flex-start;
    }
}

.message-wrapper {
    display: flex;
    gap: 12px;
    max-width: 80%;

    &.message-wrapper-user {
        flex-direction: row-reverse;
    }
}

.avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
    background: #f5f5f5;
    display: flex;
    align-items: center;
    justify-content: center;

    img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    &.avatar-ai {
        background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
    }

    &.avatar-user {
        background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    }
}

.message-body {
    display: flex;
    flex-direction: column;

    &.message-body-user {
        align-items: flex-end;
    }
}

.message-name {
    font-size: 13px;
    color: #999;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    gap: 8px;

    &.message-name-user {
        text-align: right;
    }
}

// AI 回复耗时显示
.thinking-time {
    font-size: 12px;
    color: #0ea5e9;
    font-weight: 500;
    background: rgba(14, 165, 233, 0.1);
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}

// 消息气泡基础样式
.message-bubble-base {
    padding: 12px 16px;
    border-radius: 12px;
    font-size: 15px;
    line-height: 1.6;
    word-break: break-word;
    transition: all 0.2s ease;
}

.message-bubble {
    @extend .message-bubble-base;

    &.message-bubble-ai {
        background: transparent;
        border: none;
        padding-left: 0;
        box-shadow: none;
    }

    &.message-bubble-user {
        background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
        color: #1c1c1c;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);

        &:hover {
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
        }
    }
}

.thinking-bubble {
    display: flex;
    align-items: center;
    padding: 16px 20px;
    gap: 12px;
}

.thinking-text {
    font-size: 14px;
    color: #0ea5e9;
    font-weight: 500;
    white-space: nowrap;
}

.thinking-indicator {
    display: flex;
    gap: 4px;

    span {
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: #999;
        animation: bounce 1.4s infinite ease-in-out both;

        &:nth-child(1) {
            animation-delay: -0.32s;
        }

        &:nth-child(2) {
            animation-delay: -0.16s;
        }
    }
}

@keyframes bounce {
    0%, 80%, 100% {
        transform: scale(0);
    }
    40% {
        transform: scale(1);
    }
}

.input-area {
    background: white;
    border-top: 1px solid #e5e5ea;
    padding: 16px 24px;
    flex-shrink: 0;

    &.input-disabled {
        opacity: 0.6;
        pointer-events: none;
    }
}

// 关联客户按钮栏
.customer-link-bar {
    max-width: 768px;
    margin: 0 auto 12px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.customer-link-btn {
    display: flex;
    align-items: center;
    gap: 4px;
}

.linked-customer-info {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    background: linear-gradient(135deg, #f0f9ff 0%, #e0f7fa 100%);
    border: 1px solid #bae6fd;
    border-radius: 8px;
    font-size: 13px;
    color: #0366d6;
    box-shadow: 0 1px 3px rgba(3, 102, 214, 0.1);
    transition: all 0.2s ease;

    &:hover {
        box-shadow: 0 2px 6px rgba(3, 102, 214, 0.15);
    }

    i {
        font-size: 12px;
    }

    .unlink-icon {
        cursor: pointer;
        color: #999;
        font-size: 14px;
        transition: all 0.2s ease;

        &:hover {
            color: #ef4444;
            transform: scale(1.1);
        }
    }
}

.input-container {
    max-width: 768px;
    margin: 0 auto;
    position: relative;
}

.input-box {
    flex: 1;
    position: relative;

    ::v-deep .el-textarea__inner {
        border: 1px solid #e5e5ea;
        border-radius: 12px;
        padding: 12px 50px 12px 16px;
        font-size: 15px;
        resize: none;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        background: linear-gradient(to bottom, #fafafa, #ffffff);

        &:focus {
            border-color: #d4d4d4;
            background: white;
            box-shadow: 0 0 0 3px rgba(228, 228, 231, 0.2);
        }

        &:hover:not(:focus) {
            border-color: #d4d4d4;
            background: white;
        }
    }
}

.send-btn-wrapper {
    position: absolute;
    right: 8px;
    bottom: 8px;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: linear-gradient(135deg, #1c1c1c 0%, #374151 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    color: white;
    font-size: 16px;
    box-shadow: 0 2px 8px rgba(28, 28, 28, 0.2);

    &:hover {
        background: linear-gradient(135deg, #374151 0%, #4b5563 100%);
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(28, 28, 28, 0.3);
    }

    &:active {
        transform: translateY(0) scale(0.95);
        box-shadow: 0 1px 4px rgba(28, 28, 28, 0.2);
    }

    &.disabled {
        background: linear-gradient(135deg, #d1d5db 0%, #9ca3af 100%);
        cursor: not-allowed;
        opacity: 0.6;
        box-shadow: none;

        &:hover {
            background: linear-gradient(135deg, #d1d5db 0%, #9ca3af 100%);
            transform: none;
        }

        &:active {
            transform: none;
        }
    }
}


.input-tip {
    max-width: 768px;
    margin: 8px auto 0;
    text-align: center;
    font-size: 12px;
    color: #999;

    .thinking-tip {
        color: #0ea5e9;
        font-weight: 500;
    }
}

// 滚动条样式 - 美化设计
.messages-container::-webkit-scrollbar {
    width: 6px;
}

.messages-container::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.05);
    border-radius: 3px;
}

.messages-container::-webkit-scrollbar-thumb {
    background: linear-gradient(to bottom, #d1d5db, #9ca3af);
    border-radius: 3px;
    transition: background 0.3s ease;

    &:hover {
        background: linear-gradient(to bottom, #9ca3af, #6b7280);
    }
}

.chat-list::-webkit-scrollbar {
    width: 6px;
}

.chat-list::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.03);
    border-radius: 3px;
}

.chat-list::-webkit-scrollbar-thumb {
    background: linear-gradient(to bottom, #e5e7eb, #d1d5db);
    border-radius: 3px;
    transition: all 0.3s ease;

    &:hover {
        background: linear-gradient(to bottom, #d1d5db, #9ca3af);
    }
}

// 客户选择对话框样式
.customer-dialog-content {
    .customer-filter {
        margin-bottom: 16px;
        padding: 16px;
        background: #f5f7fa;
        border-radius: 8px;
        border: 1px solid #e4e7ed;

        ::v-deep .el-form-item {
            margin-bottom: 0;
            margin-right: 20px;
        }

        ::v-deep .el-input__inner {
            width: 200px;
        }

        ::v-deep .el-select {
            width: 150px;
        }
    }

    .el-table {
        margin-bottom: 16px;
    }

    .customer-pagination {
        display: flex;
        justify-content: flex-end;
        padding: 12px 0;
    }
}
</style>
