import 'dart:convert';
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';

class KRNodeList {
  final List<KrNodeListItem> list;
  final String subscribeId;
  final String startTime;
  final String expireTime;
  final bool isTryOut; // 是否是试用订阅

  const KRNodeList({
    required this.list,
    this.subscribeId = "0",
    this.startTime = "",
    this.expireTime = "",
    this.isTryOut = false,
  });

  factory KRNodeList.fromJson(Map<String, dynamic> json) {
    try {
      // 新的 API 返回格式: {"list": [{"id": 24, "is_try_out": true, "nodes": [...]}]}
      final List<dynamic>? listData = json['list'] as List<dynamic>?;

      if (listData == null || listData.isEmpty) {
        KRLogUtil.kr_w('节点列表为空', tag: 'NodeList');
        return const KRNodeList(list: []);
      }

      // 尝试找到与请求参数 id 匹配的订阅项
      // 如果 json 中有 subscribeId，则查找匹配项；否则使用第一个
      Map<String, dynamic>? subscribeData;

      final String? requestSubscribeId = json['subscribeId']?.toString();
      if (requestSubscribeId != null && requestSubscribeId.isNotEmpty) {
        // 查找 id 匹配的订阅项
        try {
          subscribeData = listData.firstWhere(
                  (item) => (item as Map<String, dynamic>)['id']?.toString() == requestSubscribeId,
              orElse: () => listData[0] as Map<String, dynamic>
          ) as Map<String, dynamic>;
          KRLogUtil.kr_i('✅ 找到匹配的订阅项: id=$requestSubscribeId', tag: 'NodeList');
        } catch (e) {
          KRLogUtil.kr_w('⚠️ 未找到匹配的订阅项，使用第一个', tag: 'NodeList');
          subscribeData = listData[0] as Map<String, dynamic>;
        }
      } else {
        // 如果没有提供 subscribeId，使用第一个
        subscribeData = listData[0] as Map<String, dynamic>;
      }

      final bool isTryOut = subscribeData['is_try_out'] as bool? ?? false;
      final List<dynamic>? nodesData = subscribeData['nodes'] as List<dynamic>?;

      KRLogUtil.kr_i('🔍 节点列表解析: subscribe_id=${subscribeData['id']}, is_try_out=$isTryOut, 节点数=${nodesData?.length ?? 0}', tag: 'NodeList');
      KRLogUtil.kr_i('📊 所有订阅项数量: ${listData.length}', tag: 'NodeList');

      return KRNodeList(
        list: nodesData?.map((e) => KrNodeListItem.fromJson(e as Map<String, dynamic>)).toList() ?? [],
        subscribeId: subscribeData['id']?.toString() ?? "0",
        startTime: subscribeData['start_time']?.toString() ?? "",
        expireTime: subscribeData['expire_time']?.toString() ?? "",
        isTryOut: isTryOut,
      );
    } catch (err) {
      KRLogUtil.kr_e('KRNodeList解析错误: $err', tag: 'NodeList');
      return const KRNodeList(list: []);
    }
  }
}

class KrNodeListItem {
  final int id;
  String name;
  final String uuid;
  final String protocol;
  final String relayMode;
  final String relayNode;
  final String serverAddr;
  final int port; // 端口字段
  final String method; // 加密方法（用于Shadowsocks等）
  final String protocols; // 协议配置JSON字符串（新API格式）
  final int speedLimit;
  final List<String> tags;
  final int traffic;
  final double trafficRatio;
  final int upload;
  final String city;
  final String config;
  final String country;
  final int createdAt;
  final int download;
  final String startTime;
  final String expireTime;
  final double latitude;
  final double latitudeCountry;
  final double longitude;
  final double longitudeCountry;

  KrNodeListItem({
    required this.id,
    required this.name,
    required this.uuid,
    required this.protocol,
    this.relayMode = '',
    this.relayNode = '',
    required this.serverAddr,
    this.port = 0, // 默认值
    this.method = '', // 默认空字符串
    this.protocols = '', // 默认空字符串
    required this.speedLimit,
    required this.tags,
    required this.traffic,
    required this.trafficRatio,
    required this.upload,
    required this.city,
    required this.config,
    required this.country,
    this.createdAt = 0,
    required this.download,
    required this.startTime,
    required this.expireTime,
    required this.latitude,
    required this.latitudeCountry,
    required this.longitude,
    required this.longitudeCountry,
  });

  factory KrNodeListItem.fromJson(Map<String, dynamic> json) {
    try {
      // 支持新旧两种API格式
      // 最新格式: protocols 字段包含协议配置数组
      // 新格式: address, port, method（直接字段）
      // 旧格式: server_addr, config 中包含 port
      final serverAddr = json['address']?.toString() ?? json['server_addr']?.toString() ?? '';
      int port = _parseIntSafely(json['port']);
      String method = json['method']?.toString() ?? ''; // 加密方法（Shadowsocks等）
      final protocols = json['protocols']?.toString() ?? ''; // 协议配置JSON

      // 🔧 打印原始节点 JSON（用于调试）
      // KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'NodeList');
      // KRLogUtil.kr_i('📥 收到节点 API 原始数据:', tag: 'NodeList');
      // KRLogUtil.kr_i('节点名称: ${json['name']}', tag: 'NodeList');
      // KRLogUtil.kr_i('协议类型: ${json['protocol']}', tag: 'NodeList');
      // KRLogUtil.kr_i('完整 JSON:', tag: 'NodeList');
      // KRLogUtil.kr_i(jsonEncode(json), tag: 'NodeList');

      // 🔧 如果有 protocols 字段，从中解析 cipher（但不覆盖顶层的 port）
      if (protocols.isNotEmpty) {
        try {
          final protocolsList = jsonDecode(protocols) as List;
          final currentProtocol = json['protocol']?.toString().toLowerCase() ?? '';

          // KRLogUtil.kr_i('📋 protocols 字段内容 (${protocolsList.length} 个协议):', tag: 'NodeList');
          for (var i = 0; i < protocolsList.length; i++) {
            // KRLogUtil.kr_i('  协议 $i: ${jsonEncode(protocolsList[i])}', tag: 'NodeList');
          }

          if (protocolsList.isNotEmpty) {
            // 🔧 修复：查找与当前协议类型匹配的配置，而不是直接使用第一个
            Map<String, dynamic>? matchedProtocolConfig;

            // 尝试找到协议类型匹配的配置
            for (var protocolConfig in protocolsList) {
              final configMap = protocolConfig as Map<String, dynamic>;
              // 🔧 修复：API 使用的字段名是 'type'，不是 'protocol'
              final protocolType = (configMap['type'] ?? configMap['protocol'])?.toString().toLowerCase() ?? '';

              // 检查是否匹配（支持 shadowsocks/ss, vmess, vless, trojan 等）
              if (protocolType == currentProtocol ||
                  (currentProtocol == 'shadowsocks' && protocolType == 'ss') ||
                  (currentProtocol == 'ss' && protocolType == 'shadowsocks')) {
                matchedProtocolConfig = configMap;
                // KRLogUtil.kr_i('🎯 找到匹配的协议配置: $protocolType', tag: 'NodeList');
                break;
              }
            }

            // 如果没找到匹配的，使用第一个配置（兼容旧API）
            final targetProtocol = matchedProtocolConfig ?? (protocolsList[0] as Map<String, dynamic>);

            // 🔧 关键修复：只在顶层没有 port 字段时，才使用 protocols 中的端口
            // 这样可以保留顶层的正确端口（如 53441），不被 protocols 数组中的端口（如 287）覆盖
            if (port == 0 && targetProtocol['port'] != null) {
              port = _parseIntSafely(targetProtocol['port']);
              // KRLogUtil.kr_i('✅ 从 protocols 解析端口: $port', tag: 'NodeList');
            } else {
              // KRLogUtil.kr_i('✅ 保留顶层端口: $port (protocols中的端口: ${targetProtocol['port']})', tag: 'NodeList');
            }

            // 提取 cipher（加密方法）
            if (targetProtocol['cipher'] != null && targetProtocol['cipher'].toString().isNotEmpty) {
              method = targetProtocol['cipher'].toString();
              // KRLogUtil.kr_i('✅ 从 protocols 解析 cipher: $method', tag: 'NodeList');
            }
          }
        } catch (e) {
          KRLogUtil.kr_w('⚠️ 解析 protocols 字段失败: $e', tag: 'NodeList');
        }
      }
      // KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'NodeList');

      return KrNodeListItem(
        id: _parseIntSafely(json['id']),
        name: json['name']?.toString() ?? '',
        uuid: json['uuid']?.toString() ?? '',
        protocol: json['protocol']?.toString() ?? '',
        relayMode: json['relay_mode']?.toString() ?? '',
        relayNode: json['relay_node']?.toString() ?? '',
        serverAddr: serverAddr,
        port: port,
        method: method,
        protocols: protocols,
        speedLimit: _parseIntSafely(json['speed_limit']),
        tags: _parseStringList(json['tags']),
        traffic: _parseIntSafely(json['traffic']),
        trafficRatio: _parseDoubleSafely(json['traffic_ratio']),
        upload: _parseIntSafely(json['upload']),
        city: json['city']?.toString() ?? '',
        config: json['config']?.toString() ?? '',
        country: json['country']?.toString() ?? '',
        createdAt: _parseIntSafely(json['created_at']),
        download: _parseIntSafely(json['download']),
        startTime: json['start_time']?.toString() ?? '',
        expireTime: json['expire_time']?.toString() ?? '',
        latitude: _parseDoubleSafely(json['latitude']),
        latitudeCountry: _parseDoubleSafely(json['latitude_country']),
        longitude: _parseDoubleSafely(json['longitude']),
        longitudeCountry: _parseDoubleSafely(json['longitude_country']),
      );
    } catch (err) {
      KRLogUtil.kr_e('KrNodeListItem解析错误: $err', tag: 'NodeList');
      return KrNodeListItem(
        id: 0,
        name: '',
        uuid: '',
        protocol: '',
        serverAddr: '',
        port: 0,
        method: '',
        protocols: '',
        speedLimit: 0,
        tags: [],
        traffic: 0,
        trafficRatio: 0,
        upload: 0,
        city: '',
        config: '',
        country: '',
        download: 0,
        startTime: '',
        expireTime: '',
        latitude: 0.0,
        latitudeCountry: 0.0,
        longitude: 0.0,
        longitudeCountry: 0.0,
      );
    }
  }

  // 添加安全解析工具方法
  static int _parseIntSafely(dynamic value) {
    if (value == null) return 0;
    if (value is int) return value;
    if (value is String) return int.tryParse(value) ?? 0;
    return 0;
  }

  static double _parseDoubleSafely(dynamic value) {
    if (value == null) return 0.0;
    if (value is double) return value;
    if (value is int) return value.toDouble();
    if (value is String) return double.tryParse(value) ?? 0.0;
    return 0.0;
  }

  static List<String> _parseStringList(dynamic value) {
    if (value == null) return [];
    if (value is List) {
      return value.map((e) => e?.toString() ?? '').toList();
    }
    return [];
  }
}
