import { p2pNetwork } from '../network/p2p.js';
import { documentReader } from '../documents/reader.js';
import { getMinimax } from '../constraints/index.js';
export class AgentProtocol {
    peerId;
    identityName;
    pendingTasks = new Map();
    taskQueue = [];
    autoSendThreshold = 0.7;
    autonomousMode = true;
    constructor(peerId, identityName) {
        this.peerId = peerId;
        this.identityName = identityName || `Agent-${peerId.substring(0, 8)}`;
        this.setupMessageHandler();
    }
    setupMessageHandler() {
        p2pNetwork.onMessage('task', async (data, from) => {
            const message = JSON.parse(new TextDecoder().decode(data));
            await this.handleTask(message);
        });
        p2pNetwork.onMessage('result', async (data, from) => {
            const message = JSON.parse(new TextDecoder().decode(data));
            await this.handleResult(message);
        });
        p2pNetwork.onMessage('feedback', async (data, from) => {
            const message = JSON.parse(new TextDecoder().decode(data));
            await this.handleFeedback(message);
        });
        p2pNetwork.onMessage('improve', async (data, from) => {
            const message = JSON.parse(new TextDecoder().decode(data));
            await this.handleImproveRequest(message);
        });
        p2pNetwork.onMessage('improved', async (data, from) => {
            const message = JSON.parse(new TextDecoder().decode(data));
            await this.handleImprovedResult(message);
        });
    }
    async sendTask(task, targetPeer) {
        const message = {
            type: 'task',
            from: this.peerId,
            to: targetPeer,
            taskId: task.taskId,
            payload: JSON.stringify(task),
            timestamp: Date.now()
        };
        this.pendingTasks.set(task.taskId, task);
        await p2pNetwork.sendMessage(targetPeer, 'task', JSON.stringify(message));
    }
    async broadcastTask(task) {
        const message = {
            type: 'task',
            from: this.peerId,
            taskId: task.taskId,
            payload: JSON.stringify(task),
            timestamp: Date.now()
        };
        this.pendingTasks.set(task.taskId, task);
        await p2pNetwork.broadcast('task', JSON.stringify(message));
    }
    async requestImprove(documentPath, requirements, targetPeer) {
        const task = {
            taskId: `improve-${Date.now()}`,
            action: 'improve',
            documentPath,
            requirements,
            context: `Requested by ${this.identityName}`
        };
        const message = {
            type: 'improve',
            from: this.peerId,
            to: targetPeer,
            taskId: task.taskId,
            payload: JSON.stringify(task),
            timestamp: Date.now()
        };
        this.pendingTasks.set(task.taskId, task);
        if (targetPeer) {
            await p2pNetwork.sendMessage(targetPeer, 'improve', JSON.stringify(message));
        }
        else {
            await p2pNetwork.broadcast('improve', JSON.stringify(message));
        }
    }
    async handleTask(message) {
        const task = JSON.parse(message.payload);
        if (task.action === 'read' && task.documentPath) {
            const content = await documentReader.read(task.documentPath);
            const result = await this.processDocument(content, task.context);
            const resultMsg = {
                type: 'result',
                from: this.peerId,
                to: message.from,
                taskId: task.taskId,
                payload: JSON.stringify(result),
                timestamp: Date.now()
            };
            await p2pNetwork.sendMessage(message.from, 'result', JSON.stringify(resultMsg));
        }
        else if (task.action === 'improve' && task.documentPath && task.requirements) {
            const result = await this.processImprove(task);
            const resultMsg = {
                type: 'improved',
                from: this.peerId,
                to: message.from,
                taskId: task.taskId,
                payload: JSON.stringify(result),
                timestamp: Date.now()
            };
            if (result.shouldAutoSend && this.autonomousMode) {
                console.log(`\n🤖 [${this.identityName}] 自动发送改进结果 (质量: ${(result.qualityScore * 10).toFixed(1)}/10)`);
                await p2pNetwork.sendMessage(message.from, 'improved', JSON.stringify(resultMsg));
            }
            else if (result.needsApproval) {
                console.log(`\n📋 [${this.identityName}] 改进完成，等待审批 (质量: ${(result.qualityScore * 10).toFixed(1)}/10)`);
            }
        }
    }
    async processImprove(task) {
        const llm = getMinimax();
        const content = await documentReader.read(task.documentPath);
        const improvedContent = await llm.improveContent(content.text, task.requirements, task.context);
        const qualityScore = llm.estimateQuality(content.text, improvedContent);
        const shouldAutoSend = await llm.shouldAutoSend(qualityScore, this.autoSendThreshold);
        return {
            taskId: task.taskId,
            success: true,
            originalPath: task.documentPath,
            improvedContent,
            qualityScore,
            shouldAutoSend,
            needsApproval: !shouldAutoSend
        };
    }
    async processDocument(content, context) {
        const llm = getMinimax();
        const chunks = documentReader.chunk(content.text);
        const summaries = [];
        let totalQuality = 0;
        for (const chunk of chunks) {
            const result = await llm.summarize(chunk, context);
            summaries.push(result.summary);
            totalQuality += result.qualityScore;
        }
        const combinedSummary = summaries.join('\n\n');
        const avgQuality = totalQuality / chunks.length;
        const canAutoSend = await llm.shouldAutoSend(avgQuality, this.autoSendThreshold);
        return {
            taskId: `task-${Date.now()}`,
            success: true,
            result: combinedSummary,
            qualityScore: avgQuality,
            needsApproval: !canAutoSend,
            autoSent: canAutoSend && this.autonomousMode
        };
    }
    async handleResult(message) {
        const result = JSON.parse(message.payload);
        const task = this.pendingTasks.get(message.taskId);
        if (result.needsApproval && !result.autoSent) {
            console.log('\n📋 文档处理完成，需要人工确认:');
            console.log(`   质量评分: ${(result.qualityScore * 10).toFixed(1)}/10`);
            console.log(`   摘要预览: ${result.result?.substring(0, 200)}...\n`);
        }
        else if (result.autoSent || this.autonomousMode) {
            console.log('\n✅ 文档处理完成，自动发送汇报');
            await this.autoReport(result, message.from);
        }
    }
    async handleImproveRequest(message) {
        const task = JSON.parse(message.payload);
        console.log(`\n📝 [${this.identityName}] 收到改进请求: ${task.documentPath}`);
        console.log(`   要求: ${task.requirements}`);
    }
    async handleImprovedResult(message) {
        const result = JSON.parse(message.payload);
        const task = this.pendingTasks.get(message.taskId);
        console.log('\n✨ 改进结果已接收:');
        console.log(`   原始文档: ${result.originalPath}`);
        console.log(`   质量评分: ${(result.qualityScore * 10).toFixed(1)}/10`);
        console.log(`   自动发送: ${result.shouldAutoSend ? '是' : '否'}`);
        console.log(`   改进预览: ${result.improvedContent?.substring(0, 200)}...\n`);
    }
    async handleFeedback(message) {
        const { taskId, improvements } = JSON.parse(message.payload);
        console.log(`\n📝 [${this.identityName}] 收到改进意见 for task ${taskId}:`, improvements);
    }
    async autoReport(result, fromPeer) {
        const reportMsg = {
            type: 'report',
            from: this.peerId,
            taskId: result.taskId,
            payload: JSON.stringify({
                summary: result.result,
                qualityScore: result.qualityScore,
                fromAgent: this.identityName
            }),
            timestamp: Date.now()
        };
        const peers = p2pNetwork.getPeers();
        const failedPeers = [];
        for (const peer of peers) {
            if (peer !== fromPeer) {
                try {
                    await p2pNetwork.sendMessage(peer, 'report', JSON.stringify(reportMsg));
                    console.log(`[${this.identityName}] 汇报已发送至 ${peer}`);
                }
                catch (sendError) {
                    console.warn(`[${this.identityName}] 发送汇报至 ${peer} 失败: ${sendError}`);
                    failedPeers.push(peer);
                }
            }
        }
        // 重试失败的发送
        if (failedPeers.length > 0) {
            console.log(`[${this.identityName}] 尝试重新发送汇报至 ${failedPeers.length} 个失败节点`);
            await this.retryFailedReports(reportMsg, failedPeers, 2);
        }
    }
    async retryFailedReports(reportMsg, failedPeers, maxRetries) {
        for (let attempt = 1; attempt <= maxRetries; attempt++) {
            if (failedPeers.length === 0)
                break;
            console.log(`[${this.identityName}] 重试第 ${attempt}/${maxRetries} 次`);
            await this.sleep(1000 * attempt); // 指数退避
            const stillFailed = [];
            for (const peer of failedPeers) {
                try {
                    await p2pNetwork.sendMessage(peer, 'report', JSON.stringify(reportMsg));
                    console.log(`[${this.identityName}] 重试成功: ${peer}`);
                }
                catch {
                    stillFailed.push(peer);
                }
            }
            failedPeers = stillFailed;
        }
        if (failedPeers.length > 0) {
            console.log(`[${this.identityName}] 最终仍有 ${failedPeers.length} 个节点发送失败，将加入待重试队列`);
            this.queueFailedReports(reportMsg, failedPeers);
        }
    }
    failedReportsQueue = [];
    queueFailedReports(msg, peers) {
        this.failedReportsQueue.push({
            msg,
            peers,
            timestamp: Date.now()
        });
        // 限制队列大小
        if (this.failedReportsQueue.length > 50) {
            this.failedReportsQueue = this.failedReportsQueue.slice(-50);
        }
    }
    async processFailedReportsQueue() {
        if (this.failedReportsQueue.length === 0)
            return;
        console.log(`[${this.identityName}] 处理待重试汇报队列 (${this.failedReportsQueue.length} 条)`);
        const processed = [];
        for (let i = 0; i < this.failedReportsQueue.length; i++) {
            const item = this.failedReportsQueue[i];
            const stillFailed = [];
            for (const peer of item.peers) {
                try {
                    await p2pNetwork.sendMessage(peer, 'report', JSON.stringify(item.msg));
                    console.log(`[${this.identityName}] 队列重试成功: ${peer}`);
                }
                catch {
                    stillFailed.push(peer);
                }
            }
            if (stillFailed.length === 0) {
                processed.push(i);
            }
            else {
                item.peers = stillFailed;
                item.timestamp = Date.now();
            }
        }
        // 移除已成功的
        for (let i = processed.length - 1; i >= 0; i--) {
            this.failedReportsQueue.splice(processed[i], 1);
        }
    }
    sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
    async submitImprovements(taskId, improvements) {
        const feedbackMsg = {
            type: 'feedback',
            from: this.peerId,
            taskId,
            payload: JSON.stringify({ taskId, improvements }),
            timestamp: Date.now()
        };
        const peers = p2pNetwork.getPeers();
        for (const peer of peers) {
            await p2pNetwork.sendMessage(peer, 'feedback', JSON.stringify(feedbackMsg));
        }
    }
    setAutoSendThreshold(threshold) {
        this.autoSendThreshold = threshold;
    }
    setAutonomousMode(enabled) {
        this.autonomousMode = enabled;
    }
    isAutonomousMode() {
        return this.autonomousMode;
    }
}
