import { getContext, extension_settings } from "/scripts/extensions.js";
import { setExtensionPrompt, eventSource, event_types } from "/script.js";
import { callAI } from "./api.js";
import { callNgmsAI } from "./api/Ngms_api.js";
import { extensionName } from "../utils/settings.js";
import { getMemoryState, updateRow, insertRow, deleteRow, clearAllTables } from "./table-system/manager.js";

const FRACTAL_INJECTION_KEY = 'HANLINYUAN_FRACTAL_MEMORY';
const BUFFER_SIZE = 5;
const UPDATE_INTERVAL = 5;



export async function initializeFractalMemory() {
    eventSource.on(event_types.MESSAGE_RECEIVED, handleMessageReceived);
    console.log('[分形记忆] 系统已启动，正在构建多维记忆...');
}

let messageCounter = 0;

async function handleMessageReceived() {
    messageCounter++;
    if (messageCounter >= UPDATE_INTERVAL) {
        messageCounter = 0;
        await updateSceneLayer();
    }
}

async function updateSceneLayer() {
    const context = getContext();
    const settings = extension_settings[extensionName];
    
    if (!settings.fractalMemory) {
        settings.fractalMemory = {
            saga: "故事刚刚开始...",
            arc: [],
            scene: []
        };
    }
    const memory = settings.fractalMemory;

    console.log('[分形记忆] 正在提取近期事态...');

    const recentChat = context.chat.slice(-UPDATE_INTERVAL).map(m => `${m.name}: ${m.mes}`).join('\n');
    
    const prompt = `
请将以下对话总结为一句话的“场景事件”，描述发生了什么。
要求：简洁、客观、包含关键动作。

【对话内容】
${recentChat}

【输出】
(仅输出一句话总结)
`;
    
    const newEvent = await _callLLM(prompt);
    if (!newEvent) return;

    console.log(`[分形记忆] 新增场景事件: ${newEvent}`);
    memory.scene.push(newEvent);

    if (memory.scene.length >= BUFFER_SIZE) {
        await compressSceneToArc();
    }

    context.saveSettingsDebounced();
    injectFractalMemory();
    syncToTables();
}

async function compressSceneToArc() {
    const context = getContext();
    const settings = extension_settings[extensionName];
    const memory = settings.fractalMemory;

    console.log('[分形记忆] 场景层已满，正在压缩至篇章层...');

    const sceneEvents = memory.scene.join('\n');
    const prompt = `
请将以下 5 个连续的“场景事件”合并总结为一条“篇章节点”。
这条节点应该概括这一系列事件对剧情的推动作用。

【场景事件列表】
${sceneEvents}

【输出】
(仅输出一句话总结)
`;

    const newArcEvent = await _callLLM(prompt);
    if (!newArcEvent) return;

    console.log(`[分形记忆] 新增篇章节点: ${newArcEvent}`);
    
    memory.arc.push(newArcEvent);
    memory.scene = [];

    if (memory.arc.length >= BUFFER_SIZE) {
        await compressArcToSaga();
    }
}

async function compressArcToSaga() {
    const context = getContext();
    const settings = extension_settings[extensionName];
    const memory = settings.fractalMemory;

    console.log('[分形记忆] 篇章层已满，正在重写宏观史诗...');

    const arcEvents = memory.arc.join('\n');
    const oldSaga = memory.saga;

    const prompt = `
请根据“旧的宏观史诗”和新发生的“篇章事件”，重写并更新整个故事的“宏观史诗”。
宏观史诗应该是一个高度概括的段落，描述故事的起因、经过和当前状态。

【旧史诗】
${oldSaga}

【新篇章事件】
${arcEvents}

【输出】
(输出一段更新后的宏观史诗，约 100-200 字)
`;

    const newSaga = await _callLLM(prompt);
    if (!newSaga) return;

    console.log(`[分形记忆] 宏观史诗已更新。`);
    
    memory.saga = newSaga;
    memory.arc = [];
}

function syncToTables() {
    const settings = extension_settings[extensionName];
    if (!settings || !settings.fractalMemory) return;
    const memory = settings.fractalMemory;
    const tables = getMemoryState();
    if (!tables) return;

    const targetTableName = '【系统】分形记忆';
    const tableIndex = tables.findIndex(t => t.name === targetTableName);
    
    if (tableIndex !== -1) {
        const table = tables[tableIndex];
        const targetRows = [];

        targetRows.push({
            0: '宏观史诗',
            1: memory.saga
        });

        memory.arc.forEach((event, i) => {
            targetRows.push({
                0: `篇章-${i+1}`,
                1: event
            });
        });

        memory.scene.forEach((event, i) => {
            targetRows.push({
                0: `场景-${i+1}`,
                1: event
            });
        });

        while (table.rows.length > targetRows.length) {
            deleteRow(tableIndex, table.rows.length - 1);
        }

        targetRows.forEach((rowData, i) => {
            if (i < table.rows.length) {
                updateRow(tableIndex, i, rowData);
            } else {
                insertRow(tableIndex, rowData);
            }
        });
    }
}

export function injectFractalMemory() {
    const settings = extension_settings[extensionName];
    if (!settings || !settings.fractalMemory) return;

    const memory = settings.fractalMemory;

    let content = `【分形记忆系统】\n`;
    
    content += `[宏观史诗]\n${memory.saga}\n\n`;
    
    if (memory.arc.length > 0) {
        content += `[当前篇章]\n${memory.arc.map(e => `- ${e}`).join('\n')}\n\n`;
    }
    
    if (memory.scene.length > 0) {
        content += `[近期事态]\n${memory.scene.map(e => `- ${e}`).join('\n')}`;
    }

    setExtensionPrompt(
        FRACTAL_INJECTION_KEY,
        content,
        0, 
        4, 
        false,
        0
    );
}


async function _callLLM(prompt) {
    const settings = extension_settings[extensionName];
    const messages = [{ role: 'user', content: prompt }];
    
    try {
        let responseText = '';
        if (settings.ngmsEnabled) {
            responseText = await callNgmsAI(messages);
        } else {
            responseText = await callAI(messages);
        }
        return responseText.trim();
    } catch (error) {
        console.error('[分形记忆] AI 调用失败:', error);
        return null;
    }
}
