'use strict';

const crypto = require('crypto');
const axios = require('axios');
const { validateSession } = require('./email-auth');

// ─── 常量 ───
const HANDSHAKE_EXPIRE_MS = 5 * 60 * 1000; // 5分钟
const HEARTBEAT_INTERVAL = 30 * 1000; // 30秒
const MAX_RETRIES = 3;

// ─── 握手状态存储 ───
const pendingHandshakes = new Map(); // token → { agentId, publicKey, createdAt }
const activeConnections = new Map(); // connectionId → { agentId, partnerId, heartbeatAt }

// ─── 错误代码 ───
const ERRORS = {
  INVALID_SESSION: { code: 'HS001', message: '无效会话' },
  INVALID_AGENT_ID: { code: 'HS002', message: '无效Agent ID' },
  HANDSHAKE_EXPIRED: { code: 'HS003', message: '握手过期' },
  ENCRYPTION_FAILED: { code: 'HS004', message: '加密失败' },
  DECRYPTION_FAILED: { code: 'HS005', message: '解密失败' },
  INVALID_SIGNATURE: { code: 'HS006', message: '无效签名' },
  CONNECTION_LOST: { code: 'HS007', message: '连接丢失' }
};

/**
 * 生成密钥对
 */
function generateKeyPair() {
  return crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: { type: 'spki', format: 'pem' },
    privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
  });
}

/**
 * 初始化握手
 * @param {string} token - 会话token
 * @param {string} agentId - Agent ID
 * @returns {{ handshakeId: string, publicKey: string }}
 */
function initHandshake(token, agentId) {
  if (!validateSession(token).valid) {
    throw ERRORS.INVALID_SESSION;
  }

  if (!agentId || typeof agentId !== 'string') {
    throw ERRORS.INVALID_AGENT_ID;
  }

  const handshakeId = crypto.randomBytes(16).toString('hex');
  const keyPair = generateKeyPair();

  pendingHandshakes.set(handshakeId, {
    agentId,
    publicKey: keyPair.publicKey,
    privateKey: keyPair.privateKey,
    createdAt: Date.now()
  });

  return { handshakeId, publicKey: keyPair.publicKey };
}

/**
 * 完成握手
 * @param {string} handshakeId - 握手ID
 * @param {string} partnerId - 对方Agent ID
 * @param {string} encryptedData - 加密数据
 * @returns {{ connectionId: string, partnerPublicKey: string }}
 */
function completeHandshake(handshakeId, partnerId, encryptedData) {
  const handshake = pendingHandshakes.get(handshakeId);
  if (!handshake) {
    throw ERRORS.INVALID_SESSION;
  }

  if (Date.now() - handshake.createdAt > HANDSHAKE_EXPIRE_MS) {
    pendingHandshakes.delete(handshakeId);
    throw ERRORS.HANDSHAKE_EXPIRED;
  }

  try {
    const decrypted = crypto.privateDecrypt(
      {
        key: handshake.privateKey,
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
      },
      Buffer.from(encryptedData, 'base64')
    ).toString('utf8');

    const { publicKey: partnerPublicKey } = JSON.parse(decrypted);

    const connectionId = crypto.randomBytes(16).toString('hex');
    activeConnections.set(connectionId, {
      agentId: handshake.agentId,
      partnerId,
      heartbeatAt: Date.now()
    });

    pendingHandshakes.delete(handshakeId);

    return { connectionId, partnerPublicKey };
  } catch (err) {
    console.error(`[Agent握手] 解密失败: ${err.message}`);
    throw ERRORS.DECRYPTION_FAILED;
  }
}

/**
 * 发送心跳
 * @param {string} connectionId - 连接ID
 */
function sendHeartbeat(connectionId) {
  const connection = activeConnections.get(connectionId);
  if (!connection) {
    throw ERRORS.INVALID_SESSION;
  }

  connection.heartbeatAt = Date.now();
}

/**
 * 清理过期握手和连接
 */
function cleanupExpired() {
  const now = Date.now();

  for (const [handshakeId, handshake] of pendingHandshakes.entries()) {
    if (now - handshake.createdAt > HANDSHAKE_EXPIRE_MS) {
      pendingHandshakes.delete(handshakeId);
    }
  }

  for (const [connectionId, connection] of activeConnections.entries()) {
    if (now - connection.heartbeatAt > HEARTBEAT_INTERVAL * 3) {
      activeConnections.delete(connectionId);
    }
  }
}

// 每1分钟清理一次
setInterval(cleanupExpired, 60 * 1000);

module.exports = {
  initHandshake,
  completeHandshake,
  sendHeartbeat,
  ERRORS
};