// static/js/app.js

import * as api from './api.js'; // 导入API模块
import * as ui from './ui_manager.js'; // 导入UI管理模块

let currentSession = {}; // 全局变量,存储当前会话信息
let currentRoles = []; // 全局变量,存储当前角色列表
let currentMemories = []; // 全局变量,存储当前记忆集列表

// 初始化应用程序。
// 加载所有初始数据并设置事件监听器。
async function initializeApp() {
    console.log("应用程序初始化开始...");

    ui.initializeUIElements();

    // 恢复窗口宽度设置
    const savedWidth = localStorage.getItem('chatWindowWidth');
    if (savedWidth === 'full') {
        const mainContent = document.querySelector('.main-content');
        const container = document.querySelector('.container');
        mainContent.classList.add('full-width');
        container.classList.add('full-width');
        // 更新按钮图标
        const icon = ui.Elements.toggleWidthBtn.querySelector('i');
        icon.classList.remove('fa-expand-alt');
        icon.classList.add('fa-compress-alt');
    }

    // 设置导航菜单点击事件
    ui.Elements.navItems.forEach(item => {
        item.addEventListener('click', (e) => {
            e.preventDefault();
            ui.showSection(item.dataset.target);
            // 切换section时刷新数据
            if (item.dataset.target === 'config-section') loadConfigAndModels();
            if (item.dataset.target === 'features-section') loadFeaturesAndRoles();
            if (item.dataset.target === 'memory-section') loadMemoryAndMemories();
            if (item.dataset.target === 'log-section') loadLogs();
        });
    });

    // 加载初始会话信息、角色和记忆列表
    await loadInitialData();

    // 设置聊天区域事件监听
    ui.Elements.sendBtn.addEventListener('click', sendMessageHandler);
    ui.Elements.userInput.addEventListener('keydown', (e) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault(); // 阻止默认换行
            sendMessageHandler();
        }
    });
    ui.Elements.clearChatHistoryBtn.addEventListener('click', clearChatLogHandler);
    ui.Elements.toggleWidthBtn.addEventListener('click', toggleChatWindowWidthHandler);

    // 设置配置区域事件监听
    ui.Elements.saveConfigBtn.addEventListener('click', saveConfigHandler);
    ui.Elements.showApiKeyCheckbox.addEventListener('change', (e) => {
        ui.Elements.geminiApiKeyInput.type = e.target.checked ? 'text' : 'password';
    });

    // 设置特征区域事件监听
    ui.Elements.refreshFeaturesBtn.addEventListener('click', loadFeaturesAndRoles);
    ui.Elements.saveFeaturesBtn.addEventListener('click', saveFeaturesContentHandler);
    ui.Elements.createRoleBtn.addEventListener('click', createRoleHandler);

    // 设置记忆区域事件监听
    ui.Elements.refreshMemoryBtn.addEventListener('click', loadMemoryAndMemories);
    ui.Elements.saveMemoryBtn.addEventListener('click', saveMemoryContentHandler);
    ui.Elements.triggerMemoryUpdateBtn.addEventListener('click', triggerMemoryUpdateHandler);
    ui.Elements.createMemoryBtn.addEventListener('click', createMemoryHandler);

    // 设置日志区域事件监听
    ui.Elements.refreshLogBtn.addEventListener('click', loadLogs);

    // 默认显示聊天界面并加载历史
    ui.showSection('chat-section');
    await loadChatLog();
    console.log("应用程序初始化完毕。");
}

// 加载初始数据:会话信息、角色列表、记忆集列表。
async function loadInitialData() {
    try {
        currentSession = await api.fetchActiveSession();
        currentRoles = await api.fetchRoles(); // 赋值给全局变量
        currentMemories = await api.fetchMemories(); // 赋值给全局变量
        ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
        ui.setMemoryUpdateStatus(currentSession.memory_status);
        console.log("初始数据加载完成。", currentSession);
    } catch (error) {
        ui.showToast(`加载初始数据失败: ${error.message}`, 'error');
        console.error("加载初始数据失败:", error);
    }
}

// 加载并渲染配置和模型列表。
async function loadConfigAndModels() {
    try {
        const config = await api.fetchConfig();
        ui.renderConfigForm(config);

        // fetchModels 现在直接通过后端代理获取模型列表,不再需要 baseUrl 参数
        const models = await api.fetchModels();
        ui.populateModelSelects(models, config.API.DEFAULT_GEMINI_MODEL, config.API.MEMORY_UPDATE_MODEL);
        console.log("配置和模型列表加载完成。");
    } catch (error) {
        ui.showToast(`加载配置失败: ${error.message}`, 'error');
        console.error("加载配置失败:", error);
    }
}

// 保存配置处理函数。
async function saveConfigHandler() {
    const configData = {
        API: {
            GEMINI_API_BASE_URL: document.getElementById('gemini-api-base-url').value,
            GEMINI_API_KEY: ui.Elements.geminiApiKeyInput.value,
            DEFAULT_GEMINI_MODEL: ui.Elements.defaultGeminiModelSelect.options[ui.Elements.defaultGeminiModelSelect.selectedIndex].value,
            MEMORY_UPDATE_MODEL: ui.Elements.memoryUpdateModelSelect.options[ui.Elements.memoryUpdateModelSelect.selectedIndex].value,
        },
        Application: {
            CONTEXT_WINDOW_SIZE: parseInt(document.getElementById('context-window-size').value),
            MEMORY_RETENTION_TURNS: parseInt(document.getElementById('memory-retention-turns').value),
            MAX_SHORT_TERM_EVENTS: parseInt(document.getElementById('max-short-term-events').value),
        }
    };

    ui.toggleLoadingState(ui.Elements.saveConfigBtn, true);
    try {
        const response = await api.saveConfig(configData);
        ui.showToast(response.message, 'success');
        await loadConfigAndModels(); // 重新加载以确保UI同步
    } catch (error) {
        ui.showToast(`保存配置失败: ${error.message}`, 'error');
    } finally {
        ui.toggleLoadingState(ui.Elements.saveConfigBtn, false);
    }
}

// 加载并渲染聊天记录。
async function loadChatLog() {
    try {
        const chatLog = await api.fetchChatLog();
        // 确保聊天消息的 role 字段从后端返回的 'ai' 转换为 'bot'
        // 并且 content 字段在渲染前经过 DOMPurify 清理和 marked 解析
        ui.renderChatHistory(chatLog.map(msg => ({
            id: msg.id, // 传递消息ID
            role: msg.role === 'user' ? 'user' : 'bot',
            content: msg.content,
            timestamp: msg.timestamp
        })));
        console.log("聊天记录加载完成。");
    } catch (error) {
        ui.showToast(`加载聊天记录失败: ${error.message}`, 'error');
        console.error("加载聊天记录失败:", error);
    }
}

// 清空聊天记录处理函数。
async function clearChatLogHandler() {
    ui.showModal(
        "清空聊天记录",
        "确定要清空当前聊天记录吗?此操作不可逆。",
        async () => {
            ui.toggleLoadingState(ui.Elements.clearChatHistoryBtn, true);
            try {
                const response = await api.clearChatLog();
                ui.showToast(response.message, 'success');
                ui.renderChatHistory([]); // 清空UI
                currentSession.turn_counter = 0; // 重置轮次计数器
                ui.updateSessionInfo(currentSession);
                triggerMemoryUpdateHandler(); // 触发记忆更新
                console.log("聊天记录清空成功。");
            } catch (error) {
                ui.showToast(`清空聊天记录失败: ${error.message}`, 'error');
                console.error("清空聊天记录失败:", error);
            } finally {
                ui.toggleLoadingState(ui.Elements.clearChatHistoryBtn, false);
            }
        });
}


// 发送消息处理函数。
async function sendMessageHandler() {
    const message = ui.Elements.userInput.value.trim();
    if (!message) {
        return;
    }

    // 为用户消息生成一个唯一的ID
    const userMessageId = `user-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    ui.addChatMessage('user', message, new Date().toISOString(), userMessageId);
    ui.Elements.userInput.value = ''; // 清空输入框

    // 禁用发送按钮和输入框
    ui.toggleLoadingState(ui.Elements.sendBtn, true);
    ui.toggleLoadingState(ui.Elements.userInput, true);

    // 添加一个临时的"AI 正在思考..."消息,并生成一个唯一的ID
    const thinkingMessageId = `bot-thinking-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    ui.addChatMessage('bot', 'AI 正在思考...', new Date().toISOString(), thinkingMessageId);

    // 设置重试参数
    const maxRetries = 3; // 最大重试次数
    const retryDelay = 1000; // 重试间隔(毫秒)
    let retryCount = 0;
    let success = false;

    while (retryCount < maxRetries && !success) {
        try {
            if (retryCount > 0) {
                // 如果是重试,更新思考消息
                ui.updateChatMessageContent(thinkingMessageId, `AI 正在思考...(第${retryCount}次重试)`);
                await new Promise(resolve => setTimeout(resolve, retryDelay)); // 等待一段时间再重试
            }
            console.log("正在发送消息...", retryCount > 0 ? `(第${retryCount}次重试)` : "");

            // 检查是否支持流式响应
            // 使用流式响应方式发送消息
            try {
                const response = await api.sendMessage(message, true); // 添加第二个参数表示使用流式响应

                // 标记请求已成功
                success = true;

                // 初始化流式响应处理
                let fullResponse = "";
                let isFirstChunk = true;

                // 为响应创建一个永久的消息ID,替换思考消息
                const permanentBotMessageId = `bot-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;

                // 处理流式响应的每个块
                for await (const textChunk of response) {
                    if (textChunk) {
                        console.log('接收到文本块:', textChunk.substring(0, 50) + '...');
                        if (isFirstChunk) {
                            // 第一次收到数据时,替换思考消息为新的消息
                            ui.removeChatMessage(thinkingMessageId);
                            fullResponse = textChunk; // 初始化 fullResponse
                            ui.addChatMessage('bot', fullResponse, new Date().toISOString(), permanentBotMessageId);
                            isFirstChunk = false;
                        } else {
                            // 后续数据,累加并更新现有消息
                            fullResponse += textChunk;
                            ui.updateChatMessageContent(permanentBotMessageId, fullResponse);
                        }
                    }
                }

                // 流结束后,确保界面更新
                if (fullResponse && !isFirstChunk) {
                    ui.updateChatMessageContent(permanentBotMessageId, fullResponse);
                } else if (isFirstChunk) {
                    // 如果没有收到任何内容
                    ui.removeChatMessage(thinkingMessageId);
                    ui.addChatMessage('bot', '抱歉,未收到AI助手的响应,请重试。', new Date().toISOString(), permanentBotMessageId);
                }

                // 流式响应结束后,重新获取会话信息以更新 turn_counter 和 memory_status
                currentSession = await api.fetchActiveSession();
                ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
                triggerMemoryUpdateHandler(); // 触发记忆更新


            } catch (streamError) {
                console.warn("流式请求失败,回退到标准请求:", streamError);

                // 回退到标准请求
                const response = await api.sendMessage(message, false);

                if (response && response.success) {
                    console.log("消息发送成功,收到响应:", response);
                    // 成功时,更新临时消息为 AI 的实际回复
                    ui.updateChatMessageContent(thinkingMessageId, response.response);
                    // 更新会话信息
                    currentSession.turn_counter = response.turn_counter;
                    currentSession.memory_status = response.memory_status; // 更新记忆状态
                    ui.updateSessionInfo(currentSession, currentRoles, currentMemories);
                    success = true;
                    triggerMemoryUpdateHandler(); // 触发记忆更新
                } else if (response) {
                    console.warn("API返回成功但内容表示失败:", response);
                    throw new Error(response.message || '发送消息失败');
                } else {
                    throw new Error('服务器未返回有效响应');
                }
            }
        } catch (error) {
            console.error(`发送消息时发生错误 (尝试 ${retryCount + 1}/${maxRetries}):`, error);
            retryCount++;

            // 如果是最后一次尝试仍然失败
            if (retryCount >= maxRetries && !success) {
                // 移除思考消息并显示错误提示
                ui.removeChatMessage(thinkingMessageId);
                ui.showToast(`发送消息失败,已尝试 ${maxRetries} 次。请稍后再试。`, 'error');
            }
        }
    }

    // 重新启用发送按钮和输入框
    ui.toggleLoadingState(ui.Elements.sendBtn, false);
    ui.toggleLoadingState(ui.Elements.userInput, false);
}

// 加载并渲染特征内容和角色列表。
async function loadFeaturesAndRoles() {
    try {
        const roles = await api.fetchRoles();
        const featuresContent = await api.fetchFeaturesContent();

        ui.renderFeaturesContent(featuresContent);
        ui.renderRoleList(roles, currentSession.role_id, switchRoleHandler, deleteRoleHandler);
        console.log("特征和角色列表加载完成。");
    } catch (error) {
        ui.showToast(`加载特征或角色失败: ${error.message}`, 'error');
        console.error("加载特征或角色失败:", error);
    }
}

// 保存特征内容处理函数。
async function saveFeaturesContentHandler() {
    let content;
    try {
        content = JSON.parse(ui.Elements.featuresContentTextarea.value);
    } catch (error) {
        ui.showToast(`特征内容格式错误,请检查 JSON 格式: ${error.message}`, 'error');
        console.error("解析特征内容失败:", error);
        return;
    }

    ui.toggleLoadingState(ui.Elements.saveFeaturesBtn, true);
    try {
        const response = await api.saveFeaturesContent(content);
        ui.showToast(response.message, 'success');
    } catch (error) {
        ui.showToast(`保存特征内容失败: ${error.message}`, 'error');
        console.error("保存特征内容失败:", error);
    } finally {
        ui.toggleLoadingState(ui.Elements.saveFeaturesBtn, false);
    }
}

// 创建新角色处理函数。
async function createRoleHandler() {
    const roleId = ui.Elements.newRoleIdInput.value.trim();
    const roleName = ui.Elements.newRoleNameInput.value.trim();
    if (!roleId || !roleName) {
        ui.showToast("角色ID和名称不能为空。", 'warning');
        return;
    }

    ui.toggleLoadingState(ui.Elements.createRoleBtn, true);
    try {
        const response = await api.createRole(roleId, roleName);
        ui.showToast(response.message, 'success');
        ui.Elements.newRoleIdInput.value = '';
        ui.Elements.newRoleNameInput.value = '';
        await loadFeaturesAndRoles(); // 刷新列表
    } catch (error) {
        ui.showToast(`创建角色失败: ${error.message}`, 'error');
    } finally {
        ui.toggleLoadingState(ui.Elements.createRoleBtn, false);
    }
}

// 切换角色处理函数。
// @param { string } roleId 要切换到的角色ID。
async function switchRoleHandler(roleId) {
    if (roleId === currentSession.role_id) {
        ui.showToast("当前角色已是此角色。", 'info');
        return;
    }
    ui.showModal(
        "切换角色",
        `确定要切换到角色 "${roleId}" 吗?这会重置当前对话。`,
        async (confirmBtn) => { // 传入确认按钮元素
            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
            try {
                const response = await api.setActiveSession(roleId, currentSession.memory_id);
                currentSession = response;
                await loadInitialData();
                await loadFeaturesAndRoles();
                await loadChatLog();
                triggerMemoryUpdateHandler(); // 触发记忆更新
                ui.showToast(`已切换到角色 "${roleId}"`, 'success');
            } catch (error) {
                ui.showToast(`切换角色失败: ${error.message}`, 'error');
                console.error("切换角色失败:", error);
            } finally {
                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
            }
        }
    );
}

// 删除角色处理函数。
// @param { string } roleId 要删除的角色ID。
async function deleteRoleHandler(roleId) {
    if (roleId === currentSession.role_id) {
        ui.showToast("不能删除当前活跃的角色!", 'error');
        return;
    }
    ui.showModal(
        "删除角色",
        `确定要删除角色 "${roleId}" 吗?此操作可逆。`,
        async (confirmBtn) => { // 传入确认按钮元素
            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
            try {
                const response = await api.deleteRole(roleId);
                ui.showToast(response.message, 'success');
                await loadFeaturesAndRoles(); // 刷新列表
            } catch (error) {
                ui.showToast(`删除角色失败: ${error.message}`, 'error');
            } finally {
                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
            }
        }
    );
}

// 加载并渲染记忆内容和记忆集列表。
async function loadMemoryAndMemories() {
    try {
        const memories = await api.fetchMemories();
        const memoryContent = await api.fetchMemoryContent();

        ui.renderMemoryContent(memoryContent);
        ui.renderMemoryList(memories, currentSession.memory_id, switchMemoryHandler, deleteMemoryHandler);
        console.log("记忆内容和记忆集列表加载完成。");
    } catch (error) {
        ui.showToast(`加载记忆或记忆集失败: ${error.message}`, 'error');
        console.error("加载记忆或记忆集失败:", error);
    }
}

// 保存记忆内容处理函数。
async function saveMemoryContentHandler() {
    let content;
    try {
        content = JSON.parse(ui.Elements.memoryContentTextarea.value);
    } catch (error) {
        ui.showToast(`记忆内容格式错误,请检查 JSON 格式: ${error.message}`, 'error');
        console.error("解析记忆内容失败:", error);
        return;
    }

    ui.toggleLoadingState(ui.Elements.saveMemoryBtn, true);
    try {
        const response = await api.saveMemoryContent(content);
        ui.showToast(response.message, 'success');
    } catch (error) {
        ui.showToast(`保存记忆内容失败: ${error.message}`, 'error');
        console.error("保存记忆内容失败:", error);
    } finally {
        ui.toggleLoadingState(ui.Elements.saveMemoryBtn, false);
    }
}

// 创建新记忆集处理函数。
async function createMemoryHandler() {
    const memoryId = ui.Elements.newMemoryIdInput.value.trim();
    const memoryName = ui.Elements.newMemoryNameInput.value.trim();
    if (!memoryId || !memoryName) {
        ui.showToast("记忆集ID和名称不能为空。", 'warning');
        return;
    }

    ui.toggleLoadingState(ui.Elements.createMemoryBtn, true);
    try {
        const response = await api.createMemory(memoryId, memoryName);
        ui.showToast(response.message, 'success');
        ui.Elements.newMemoryIdInput.value = '';
        ui.Elements.newMemoryNameInput.value = '';
        await loadMemoryAndMemories(); // 刷新列表
    } catch (error) {
        ui.showToast(`创建记忆集失败: ${error.message}`, 'error');
    } finally {
        ui.toggleLoadingState(ui.Elements.createMemoryBtn, false);
    }
}

// 切换记忆集处理函数。
// @param { string } memoryId 要切换到的记忆集ID。
async function switchMemoryHandler(memoryId) {
    if (memoryId === currentSession.memory_id) {
        ui.showToast("当前记忆集是此记忆集。", 'info');
        return;
    }
    ui.showModal(
        "切换记忆集",
        `确定要切换到记忆集 "${memoryId}" 吗?这会重置当前对话。`,
        async (confirmBtn) => { // 传入确认按钮元素
            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
            try {
                const response = await api.setActiveSession(currentSession.role_id, memoryId);
                currentSession = response;
                await loadInitialData();
                await loadMemoryAndMemories();
                await loadChatLog();
                triggerMemoryUpdateHandler(); // 触发记忆更新
                ui.showToast(`已切换到记忆集 "${memoryId}"`, 'success');
            } catch (error) {
                ui.showToast(`切换记忆集失败: ${error.message}`, 'error');
                console.error("切换记忆集失败:", error);
            } finally {
                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
            }
        }
    );
}

// 删除记忆集处理函数。
// @param { string } memoryId 要删除的记忆集ID。
async function deleteMemoryHandler(memoryId) {
    if (memoryId === currentSession.memory_id) {
        ui.showToast("不能删除当前活跃的记忆集!", 'error');
        return;
    }
    ui.showModal(
        "删除记忆集",
        `确定要删除记忆集 "${memoryId}" 吗?此操作不可逆。`,
        async (confirmBtn) => { // 传入确认按钮元素
            ui.toggleLoadingState(confirmBtn, true); // 禁用确认按钮
            try {
                const response = await api.deleteMemory(memoryId);
                ui.showToast(response.message, 'success');
                await loadMemoryAndMemories(); // 刷新列表
            } catch (error) {
                ui.showToast(`删除记忆集失败: ${error.message}`, 'error');
            } finally {
                ui.toggleLoadingState(confirmBtn, false); // 重新启用确认按钮
            }
        }
    );
}

// 触发记忆更新处理函数。
async function triggerMemoryUpdateHandler() {
    ui.toggleLoadingState(ui.Elements.triggerMemoryUpdateBtn, true);
    ui.setMemoryUpdateStatus('updating'); // 设置为updating状态
    ui.Elements.memoryUpdateStatusText.textContent = '记忆整理中 (手动)...';
    try {
        const response = await api.triggerMemoryUpdate();
        ui.showToast(response.message, 'info');
        // 记忆更新是异步的,触发后需要重新获取会话信息来更新状态
        currentSession = await api.fetchActiveSession();
        ui.setMemoryUpdateStatus(currentSession.memory_status);
    } catch (error) {
        ui.showToast(`触发记忆更新失败: ${error.message}`, 'error');
        console.error("触发记忆更新失败:", error);
        ui.setMemoryUpdateStatus('error'); // 触发失败则显示错误状态
    } finally {
        ui.toggleLoadingState(ui.Elements.triggerMemoryUpdateBtn, false);
    }
}


// 加载并渲染日志内容。
async function loadLogs() {
    try {
        const logContent = await api.fetchLogs(); // 通过API获取日志
        ui.renderLogContent(logContent);
        console.log("日志加载完成。");
    } catch (error) {
        ui.showToast(`加载日志失败: ${error.message}`, 'error');
        console.error("加载日志失败:", error);
        ui.renderLogContent(`加载日志失败: ${error.message}`);
    }
}

// 切换聊天窗口宽度处理函数
function toggleChatWindowWidthHandler() {
    const mainContent = document.querySelector('.main-content');
    const container = document.querySelector('.container');

    // 同时切换主内容区和容器的全宽类
    mainContent.classList.toggle('full-width');
    container.classList.toggle('full-width');

    // 切换按钮图标
    const icon = ui.Elements.toggleWidthBtn.querySelector('i');
    if (mainContent.classList.contains('full-width')) {
        icon.classList.remove('fa-expand-alt');
        icon.classList.add('fa-compress-alt');
        localStorage.setItem('chatWindowWidth', 'full');
    } else {
        icon.classList.remove('fa-compress-alt');
        icon.classList.add('fa-expand-alt');
        localStorage.setItem('chatWindowWidth', 'default');
    }
}

// 应用程序启动
document.addEventListener('DOMContentLoaded', initializeApp);