// SignalR连接模块
import {config} from './config.js';
import {addMessage} from './message.js';
import {highlightCodeBlocks} from './highlight.js';
import {scrollToBottom} from './dom-utils.js';
import {renderMarkdown} from './markdown.js';

let connection = null;
let isConnected = false;
let isLoading = false;
let currentAssistantMessage = null;
let currentAssistantRaw = '';
let cancelBtn = null;

export function getConnection() {
    return connection;
}

export function getIsConnected() {
    return isConnected;
}

export function getIsLoading() {
    return isLoading;
}

export function setIsLoading(value) {
    isLoading = value;
}

export function getCurrentAssistantMessage() {
    return currentAssistantMessage;
}

export function setCurrentAssistantMessage(value) {
    currentAssistantMessage = value;
}

export function getCurrentAssistantRaw() {
    return currentAssistantRaw;
}

export function setCurrentAssistantRaw(value) {
    currentAssistantRaw = value;
}

export function getCancelBtn() {
    return cancelBtn;
}

export function setCancelBtn(value) {
    cancelBtn = value;
}

export function setConnectionStatus(connected, statusEl, updateInputState) {
    isConnected = connected;
    if (statusEl) {
        statusEl.textContent = connected ? '已连接' : '未连接';
        statusEl.className = `status ${connected ? 'connected' : 'disconnected'}`;
    }
    if (updateInputState) {
        updateInputState();
    }
}

export async function initConnection(chatArea, statusEl, updateInputState, refreshSessionListCallback, getCurrentSessionId) {
    connection = new signalR
        .HubConnectionBuilder()
        .withUrl(config.hubUrl)
        .withAutomaticReconnect([0, 0, 1000, 3000, 5000, 10000])
        .build();

    connection.on('NewSessionCreated', (sessionId) => {
        console.log('✅ 新会话已创建,SessionId:', sessionId);
        const currentSessionIdEl = document.getElementById('currentSessionId');
        if (currentSessionIdEl) currentSessionIdEl.value = sessionId;
        // pendingSessionElement 处理在 session.js 中
    });

    connection.on('SessionNameGenerated', async (data) => {
        let sessionId, sessionName;
        if (typeof data === 'object' && data !== null) {
            sessionId = data.sessionId;
            sessionName = data.sessionName;
        } else {
            sessionId = data;
        }

        console.log('✅ 会话名称已生成,SessionId:', sessionId, 'SessionName:', sessionName);
        // 动态导入 updateSessionTitle 函数
        const { updateSessionTitle } = await import('./session.js');
        
        // 尝试直接更新标题,将 sessionName 作为第四个参数传入
        const updated = await updateSessionTitle(sessionId, null, refreshSessionListCallback, sessionName);
        if (!updated && refreshSessionListCallback) {
            // 如果直接更新失败,则刷新整个列表
            refreshSessionListCallback();
        }
    });

    connection.on('StreamDelta', (delta) => {
        if (currentAssistantMessage) {
            const threshold = 100;
            const isAtBottom = chatArea ? (chatArea.scrollHeight - chatArea.scrollTop - chatArea.clientHeight < threshold) : true;

            currentAssistantRaw += delta;

            // 保存操作栏和原始内容元素(在 innerHTML 之前)
            const actionRow = currentAssistantMessage.querySelector('.message-actions');
            const ts = currentAssistantMessage.querySelector('.timestamp');
            // 保存取消按钮的引用(如果存在)
            const cancelBtnRef = cancelBtn;
            
            // 重新渲染 Markdown 内容(这会清空 innerHTML)
            currentAssistantMessage.innerHTML = renderMarkdown(currentAssistantRaw);
            
            // 重新创建操作栏(因为 innerHTML 已经清空了所有内容)
            let newActionRow = document.createElement('div');
            newActionRow.className = 'message-actions';
            
            // 如果有取消按钮,先添加取消按钮(在最前面)
            if (cancelBtnRef) {
                newActionRow.appendChild(cancelBtnRef);
            }
            
            // 如果有原来的 actionRow,尝试恢复其中的按钮
            if (actionRow) {
                // 复制按钮
                const copyBtn = actionRow.querySelector('.btn-copy-markdown');
                if (copyBtn) {
                    newActionRow.appendChild(copyBtn.cloneNode(true));
                } else {
                    // 如果没有,创建一个新的复制按钮
                    const newCopyBtn = document.createElement('button');
                    newCopyBtn.className = 'btn-copy-markdown';
                    newCopyBtn.title = '复制原始内容';
                    newCopyBtn.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
                    newActionRow.appendChild(newCopyBtn);
                }
            } else {
                // 如果没有原来的 actionRow,创建新的复制按钮
                const newCopyBtn = document.createElement('button');
                newCopyBtn.className = 'btn-copy-markdown';
                newCopyBtn.title = '复制原始内容';
                newCopyBtn.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
                newActionRow.appendChild(newCopyBtn);
            }
            
            // 创建或更新 rawEl(必须在 actionRow 内部,在复制按钮之后)
            const newRawEl = document.createElement('div');
            newRawEl.className = 'raw-markdown';
            newRawEl.style.display = 'none';
            newRawEl.textContent = currentAssistantRaw;
            newActionRow.appendChild(newRawEl);
            
            // 删除按钮(如果有的话,但流式生成时通常没有)
            if (actionRow) {
                const deleteBtn = actionRow.querySelector('.btn-delete-message');
                if (deleteBtn) {
                    newActionRow.appendChild(deleteBtn.cloneNode(true));
                }
            }
            
            // 恢复操作栏
            currentAssistantMessage.appendChild(newActionRow);

            // 恢复或新建 timestamp
            if (ts) {
                currentAssistantMessage.appendChild(ts);
            } else {
                let newTs = document.createElement('div');
                newTs.className = 'timestamp';
                newTs.textContent = new Date().toLocaleString();
                currentAssistantMessage.appendChild(newTs);
            }

            // 异步高亮代码块(不阻塞流式更新)
            highlightCodeBlocks(currentAssistantMessage).catch(err => {
                console.warn('代码高亮失败:', err);
            });
            if (isAtBottom) {
                scrollToBottom(chatArea);
            }
        }
    });

    connection.on('StreamCompleted', () => {
        isLoading = false;
        if (cancelBtn) {
            cancelBtn.remove();
            cancelBtn = null;
        }
        if (currentAssistantMessage) {
            highlightCodeBlocks(currentAssistantMessage).catch(err => {
                console.warn('代码高亮失败:', err);
            });
        }
        currentAssistantMessage = null;
        currentAssistantRaw = '';
        if (updateInputState) {
            updateInputState();
        }
        if (refreshSessionListCallback) {
            refreshSessionListCallback();
        }
    });

    connection.on('StreamCancelled', () => {
        isLoading = false;
        if (cancelBtn) {
            cancelBtn.remove();
            cancelBtn = null;
        }
        currentAssistantMessage = null;
        currentAssistantRaw = '';
        if (updateInputState) {
            updateInputState();
        }
        addMessage(chatArea, 'assistant', '已取消生成');
    });

    connection.on('SystemError', (errorData) => {
        isLoading = false;
        if (cancelBtn) {
            cancelBtn.remove();
            cancelBtn = null;
        }
        currentAssistantMessage = null;
        currentAssistantRaw = '';
        addMessage(chatArea, 'error', (errorData && errorData.content) || '发生错误');
        if (updateInputState) {
            updateInputState();
        }
    });

    connection.onreconnecting(() => setConnectionStatus(false, statusEl, updateInputState));
    connection.onreconnected(() => setConnectionStatus(true, statusEl, updateInputState));
    connection.onclose(() => {
        setConnectionStatus(false, statusEl, updateInputState);
        setTimeout(() => initConnection(chatArea, statusEl, updateInputState, refreshSessionListCallback, getCurrentSessionId), 5000);
    });

    try {
        await connection.start();
        setConnectionStatus(true, statusEl, updateInputState);
        console.log('📡 SignalR 连接已建立');
    } catch (err) {
        console.error('❌ 连接失败:', err);
        setConnectionStatus(false, statusEl, updateInputState);
        setTimeout(() => initConnection(chatArea, statusEl, updateInputState, refreshSessionListCallback, getCurrentSessionId), 5000);
    }
}

评论加载中...