import { log } from "./table-system/logger.js";
import { getContext, extension_settings } from "/scripts/extensions.js";
import { eventSource, event_types } from "/script.js";
import { extensionName } from "../utils/settings.js";

function collectDataToBuffer(buffer, tableName, rowObj) {
    if (!buffer[tableName]) {
        buffer[tableName] = {
            headers: Object.keys(rowObj),
            rows: []
        };
    } else {
        const newKeys = Object.keys(rowObj);
        newKeys.forEach(k => {
            if (!buffer[tableName].headers.includes(k)) {
                buffer[tableName].headers.push(k);
            }
        });
    }
    buffer[tableName].rows.push(rowObj);
}

function flushBufferToMarkdown(buffer) {
    let output = "";
    const tableNames = Object.keys(buffer);

    if (tableNames.length === 0) return "";

    for (const tableName of tableNames) {
        const { headers, rows } = buffer[tableName];
        if (rows.length === 0) continue;

        const firstColKey = headers[0];
        const firstColVal = rows[0] ? rows[0][firstColKey] : '';
        const isIndexCol = (firstColKey && (firstColKey.includes('索引') || firstColKey.includes('Index'))) ||
                           (typeof firstColVal === 'string' && /^\s*M\d+/.test(firstColVal));

        if (isIndexCol) {
            rows.sort((a, b) => {
                const valA = String(a[firstColKey] || '');
                const valB = String(b[firstColKey] || '');
                return valA.localeCompare(valB, undefined, { numeric: true });
            });
        } else {

            rows.reverse();
        }

        output += `\n# ${tableName}档案\n`;
        output += `| ${headers.join(' | ')} |\n`;
        output += `|${headers.map(() => '---').join('|')}|\n`;

        for (const rowObj of rows) {
            const rowArr = headers.map(h => {
                const val = rowObj[h];
                let safeVal = (val === undefined || val === null) ? '' : String(val);
                safeVal = safeVal.replace(/\|/g, '\\|').replace(/\n/g, ' '); 
                return safeVal;
            });
            output += `| ${rowArr.join(' | ')} |\n`;
        }
        output += `\n`;
    }
    return output;
}

function processText(text) {
    const blockRegex = /【(.*?)档案[:：]\s*.*?】\s*((?:-\s*.*?[:：].*?(?:\r?\n|$))+)/g;
    const itemRegex = /-\s*(.*?)[:：]\s*(.*?)(?:\r?\n|$)/g;
    
    const buffer = {};
    let found = false;

    const cleanText = text.replace(blockRegex, (match, tableName, content) => {
        found = true;
        const rowObj = {};
        
        let itemMatch;
        itemRegex.lastIndex = 0;

        while ((itemMatch = itemRegex.exec(content)) !== null) {
            const key = itemMatch[1].trim();
            const val = itemMatch[2].trim();
            if (key) {
                rowObj[key] = val;
            }
        }

        if (Object.keys(rowObj).length > 0) {
            collectDataToBuffer(buffer, tableName, rowObj);
        }
        
        return ""; // 移除原始文本
    });

    return { cleanText, buffer, found };
}

function handlePromptProcessing(data) {
    // 【V146.5】检查上下文优化开关
    const settings = extension_settings[extensionName];
    if (settings && settings.context_optimization_enabled === false) {
        // log('[ContextOptimizer] 上下文优化已禁用，跳过处理。', 'info');
        return;
    }

    if (!data) return;

    if (typeof data.prompt === 'string') {
        const { cleanText, buffer, found } = processText(data.prompt);
        if (found) {
            const mergedTable = flushBufferToMarkdown(buffer);
            if (mergedTable) {
                data.prompt = cleanText + "\n" + mergedTable;
                log('[ContextOptimizer] 已优化上下文：合并了分散的世界书条目 (Text Mode)。', 'success');
            }
        }

    } else if (Array.isArray(data.chat)) {
        console.log('[ContextOptimizer] 检测到 Chat Completion 格式...');
        
        const newChat = [];
        let modifiedCount = 0;

        for (const msg of data.chat) {
            const newMsg = { ...msg };
            
            if (typeof newMsg.content === 'string') {
                const { cleanText, buffer, found } = processText(newMsg.content);
                
                if (found) {
                    const mergedTable = flushBufferToMarkdown(buffer);
                    if (mergedTable) {
                        newMsg.content = cleanText + "\n" + mergedTable;
                        modifiedCount++;
                    }
                }
            }
            newChat.push(newMsg);
        }

        if (modifiedCount > 0) {
            console.log(`[ContextOptimizer] 已原地优化 ${modifiedCount} 条消息中的表格数据。`);
            
            // 全量替换，确保生效
            data.chat.splice(0, data.chat.length, ...newChat);
            log('[ContextOptimizer] 已优化上下文：合并了分散的世界书条目 (Chat Mode - In Place)。', 'success');
        }

    }
}

/**
 * 注册监听器
 */
export function registerContextOptimizerMacros() {
    console.log('[ContextOptimizer] 正在注册监听器...');
    const context = getContext();
    
    if (context) {
        console.log('[ContextOptimizer] Context APIs:', Object.keys(context));
    }

    if (context && context.registerChatCompletionModifier) {
        context.registerChatCompletionModifier((chat) => {
            console.log('[ContextOptimizer] ChatCompletionModifier 触发');
            const data = { chat: chat };
            handlePromptProcessing(data);
            return data.chat;
        });
        log('[ContextOptimizer] 已注册 Chat Completion Modifier。', 'success');

    } else if (context && context.registerPromptModifier) {
            context.registerPromptModifier((prompt) => {
                console.log('[ContextOptimizer] PromptModifier 触发');
                const data = { prompt: prompt };
                handlePromptProcessing(data);
                return data.prompt;
            });
            log('[ContextOptimizer] 已注册 Prompt Modifier (正则模式)。', 'success');

    } else if (eventSource) {
        eventSource.on('chat_completion_prompt_ready', (...args) => {
            if (args[0] && typeof args[0] === 'object') {
                 handlePromptProcessing(args[0]);
            }
        });
        
        eventSource.on(event_types.GENERATION_STARTED, (...args) => {
             if (args.length > 1 && args[1] && typeof args[1].prompt === 'string') {
                  handlePromptProcessing(args[1]);
             } else if (args[0] && typeof args[0].prompt === 'string') {
                  handlePromptProcessing(args[0]);
             }
        });
        
        log('[ContextOptimizer] 已绑定事件监听 (Text/Chat 双模式)。', 'info');
    } else {
        console.error('[ContextOptimizer] 无法获取 eventSource。');
    }
}
export function resetContextBuffer() {
}
