import db from '../../config/database';
import { logger } from '../../utils/logger';
import { RedisService } from '../../utils/RedisService';
import { DIDHandshakeService } from '../security/DIDHandshakeService';

export interface FederatedNode {
  nodeId: string;
  did: string;
  endpoint: string;
  publicKey: string;
  status: 'ONLINE' | 'OFFLINE' | 'SUSPENDED';
  trustScore: number;
  lastSeen: Date;
}

/**
 * [SOV_NET_01] 基于 DID 的节点身份发现与握手协议 (Handshake)
 * @description 核心逻辑：管理 Crawlful Hub 联邦网络中的节点身份。
 * 支持通过 DID 进行去中心化身份验证与握手，建立节点间的信任链路。
 * 联动 [DIDHandshakeService] 确保通信的主权安全。
 */
export class FederatedNodeService {
  private static readonly NODE_REGISTRY_TABLE = 'cf_federated_nodes';
  private static readonly NODE_CACHE_PREFIX = 'sov_net:node:';

  /**
   * 初始化节点注册表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.NODE_REGISTRY_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.NODE_REGISTRY_TABLE} table...`);
      await db.schema.createTable(this.NODE_REGISTRY_TABLE, (table) => {
        table.string('node_id', 64).primary();
        table.string('did', 128).notNullable().unique();
        table.string('endpoint', 255).notNullable();
        table.text('public_key').notNullable();
        table.string('status', 16).defaultTo('ONLINE');
        table.float('trust_score').defaultTo(1.0);
        table.timestamp('last_seen').defaultTo(db.fn.now());
        table.timestamp('created_at').defaultTo(db.fn.now());
      });
      logger.info(`✅ Table ${this.NODE_REGISTRY_TABLE} created`);
    }
  }

  /**
   * 注册/发现新节点并执行 DID 握手
   * @param nodeInfo 节点基础信息
   */
  static async discoverNode(nodeInfo: Partial<FederatedNode>): Promise<boolean> {
    logger.info(`[SovNet] Discovering node: ${nodeInfo.nodeId} at ${nodeInfo.endpoint}`);

    try {
      // 1. 执行 DID 握手验证身份
      const handshakeResult = await DIDHandshakeService.performHandshake({
        targetDid: nodeInfo.did!,
        targetEndpoint: nodeInfo.endpoint!,
        expectedPublicKey: nodeInfo.publicKey!
      });

      if (!handshakeResult.success) {
        logger.error(`[SovNet] Handshake failed for node ${nodeInfo.nodeId}`);
        return false;
      }

      // 2. 存储/更新节点信息
      await db(this.NODE_REGISTRY_TABLE).insert({
        node_id: nodeInfo.nodeId,
        did: nodeInfo.did,
        endpoint: nodeInfo.endpoint,
        public_key: nodeInfo.publicKey,
        status: 'ONLINE',
        last_seen: new Date()
      }).onConflict('node_id').merge();

      // 3. 写入缓存
      await RedisService.set(`${this.NODE_CACHE_PREFIX}${nodeInfo.nodeId}`, JSON.stringify(nodeInfo), 3600);

      logger.info(`[SovNet] Node ${nodeInfo.nodeId} verified and registered.`);
      return true;
    } catch (err: any) {
      logger.error(`[SovNet] Node discovery error: ${err.message}`);
      return false;
    }
  }

  /**
   * 获取所有活跃节点
   */
  static async getActiveNodes(): Promise<FederatedNode[]> {
    return await db(this.NODE_REGISTRY_TABLE).where({ status: 'ONLINE' });
  }

  /**
   * 记录节点心跳
   */
  static async recordHeartbeat(nodeId: string) {
    await db(this.NODE_REGISTRY_TABLE)
      .where({ node_id: nodeId })
      .update({ last_seen: new Date(), status: 'ONLINE' });
  }
}
