import 'dart:io';
import 'dart:async';
import 'kr_log_util.dart';

/// 真正的节点延迟测试工具
class KRLatencyTester {
  /// TCP 连接测试延迟（真实测试）
  /// 返回延迟毫秒数，失败返回 65535
  static Future<int> testTcpLatency({
    required String host,
    required int port,
    Duration timeout = const Duration(seconds: 5),
  }) async {
    Socket? socket;
    final stopwatch = Stopwatch();

    try {
      KRLogUtil.kr_i('🔌 开始测试: $host:$port', tag: 'LatencyTester');

      stopwatch.start();

      // 尝试 TCP 连接
      socket = await Socket.connect(
        host,
        port,
        timeout: timeout,
      );

      stopwatch.stop();

      final latency = stopwatch.elapsedMilliseconds;

      KRLogUtil.kr_i('✅ 测试成功: $host:$port - ${latency}ms', tag: 'LatencyTester');

      return latency;

    } on SocketException catch (e) {
      stopwatch.stop();
      KRLogUtil.kr_w('❌ 连接失败: $host:$port - ${e.message}', tag: 'LatencyTester');
      return 65535;

    } on TimeoutException catch (e) {
      stopwatch.stop();
      KRLogUtil.kr_w('⏱️ 连接超时: $host:$port - $e', tag: 'LatencyTester');
      return 65535;

    } catch (e) {
      stopwatch.stop();
      KRLogUtil.kr_e('❌ 测试异常: $host:$port - $e', tag: 'LatencyTester');
      return 65535;

    } finally {
      // 确保关闭连接
      try {
        await socket?.close();
      } catch (e) {
        // 忽略关闭错误
      }
    }
  }

  /// 批量测试多个节点延迟（并发测试）
  /// 返回 Map<节点tag, 延迟ms>
  static Future<Map<String, int>> testMultipleNodes({
    required List<MapEntry<String, SocketAddress>> nodes,
    int concurrency = 10,  // 并发数
    Duration timeout = const Duration(seconds: 5),
  }) async {
    final results = <String, int>{};
    final List<List<MapEntry<String, SocketAddress>>> batches = [];

    // 分批处理
    for (int i = 0; i < nodes.length; i += concurrency) {
      batches.add(
        nodes.sublist(i, i + concurrency > nodes.length ? nodes.length : i + concurrency)
      );
    }

    KRLogUtil.kr_i('📊 开始批量测试: ${nodes.length} 个节点，分 ${batches.length} 批，每批 $concurrency 个', tag: 'LatencyTester');

    int completedCount = 0;

    // 逐批测试
    for (int batchIndex = 0; batchIndex < batches.length; batchIndex++) {
      final batch = batches[batchIndex];

      KRLogUtil.kr_i('📦 测试第 ${batchIndex + 1}/${batches.length} 批（${batch.length} 个节点）', tag: 'LatencyTester');

      // 并发测试当前批次
      final futures = batch.map((node) async {
        final tag = node.key;
        final address = node.value;

        final latency = await testTcpLatency(
          host: address.host,
          port: address.port,
          timeout: timeout,
        );

        completedCount++;

        if (completedCount % 5 == 0 || completedCount == nodes.length) {
          KRLogUtil.kr_i('📈 测试进度: $completedCount/${nodes.length}', tag: 'LatencyTester');
        }

        return MapEntry(tag, latency);
      }).toList();

      // 等待当前批次完成
      final batchResults = await Future.wait(futures);

      // 收集结果
      for (final result in batchResults) {
        results[result.key] = result.value;
      }
    }

    // 统计结果
    final successCount = results.values.where((latency) => latency < 65535).length;
    final failCount = results.length - successCount;

    KRLogUtil.kr_i('✅ 批量测试完成', tag: 'LatencyTester');
    KRLogUtil.kr_i('📊 成功: $successCount, 失败: $failCount', tag: 'LatencyTester');

    // 显示延迟最低的前3个
    final successNodes = results.entries
        .where((e) => e.value < 65535)
        .toList()
      ..sort((a, b) => a.value.compareTo(b.value));

    if (successNodes.isNotEmpty) {
      KRLogUtil.kr_i('🏆 延迟最低的前3个节点:', tag: 'LatencyTester');
      for (int i = 0; i < 3 && i < successNodes.length; i++) {
        KRLogUtil.kr_i('  ${i + 1}. ${successNodes[i].key}: ${successNodes[i].value}ms', tag: 'LatencyTester');
      }
    }

    return results;
  }
}

/// 节点地址信息
class SocketAddress {
  final String host;
  final int port;

  SocketAddress(this.host, this.port);

  @override
  String toString() => '$host:$port';
}
