import 'dart:io';

import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../../../common/LogHelper.dart';
import '../../../data/model/NodeMode.dart';
import '../../../global_controller/GlobalController.dart';
import '../../../network/api_service.dart';
enum NodeDisplayStrategy {
  All,
  LeastUsers,
  SelectedFirst,
}

class NodeController extends GetxController {
  //TODO: Implement NodeController

  final count = 0.obs;
  var isLoading = false.obs;
  var nodesToShow = <NodeMode>[].obs;
  var nodeModes = <NodeMode>[];
  var selectedIndex = (-1).obs;
  var errorMsg = ''.obs;
  final selectedNode = Rx<NodeMode?>(null);
  var pingResults = <int, String>{}.obs;
  //final selectedNodeId = (-1).obs;
  final isLoadingMap = <int, bool>{}.obs;
  var displayStrategy = Rx<NodeDisplayStrategy>(NodeDisplayStrategy.All);
  late final GlobalController globalController ;
  // Future<void> fetchNodes() async {
  //   try {
  //     isLoading.value = true;
  //     nodeModes.clear();
  //     nodeModes = await ApiService().getNode("/api/client/v4/nodes?vless=1");
  //     nodesToShow.value = nodeModes;
  //     LogHelper().d(nodeModes.toList());
  //     loadSelectedNode();
  //   } catch (e) {
  //     errorMsg.value = e.toString();
  //   } finally {
  //     isLoading.value = false;
  //   }
  // }


  Future<void> tcpPing(NodeMode node) async {
    int? nodeId = node.id;

    if (nodeId != null) {
      isLoadingMap[nodeId] = true;  // 开始ping时设置为true
      isLoadingMap.refresh();      // 通知观察者

      final stopwatch = Stopwatch()..start();
      Socket? socket;
      try {
        socket = await Socket.connect(node.host!, node.port!, timeout: const Duration(seconds: 3));
        final elapsed = stopwatch.elapsedMilliseconds;
        pingResults[nodeId] = '${elapsed}ms';  // 使用普通的映射赋值
        pingResults.refresh();                // 通知观察者
        socket.destroy();
      } catch (e) {
        pingResults[nodeId] = 'Error';        // 使用普通的映射赋值
        pingResults.refresh();                // 通知观察者
      }

      isLoadingMap[nodeId] = false; // ping结束后设置为false
      isLoadingMap.refresh();       // 通知观察者
    }
  }
  void pingAllNodes() async {
    for (var node in nodeModes) {
       tcpPing(node);  // 这里用了 await 使其串行 ping，若希望并行可移除 await
    }
  }

  Future<void> pingSingleNode(NodeMode node) async {

    await tcpPing(node);

  }


  void selectNode(NodeMode node) {
    selectedNode.value = node;
    _storeSelectedNode(node);
    //selectedIndex.value = nodeModes.indexWhere((item) => item.id == node.id);
  }

  Future<void> _storeSelectedNode(NodeMode node) async {
    final prefs = await SharedPreferences.getInstance();
    // 为简化起见，我们只存储node的ID，但您可以根据需要存储更多信息
    prefs.setInt('selectedNodeId', node.id!);
  }

  Future<void> loadSelectedNode() async {
    final prefs = await SharedPreferences.getInstance();
    final selectedNodeId = prefs.getInt('selectedNodeId');
    if (selectedNodeId != null) {
      //selectedIndex.value = nodeModes.indexWhere((item) => item.id == selectedNodeId);
      selectedNode.value = nodeModes.firstWhere((node) => node.id == selectedNodeId);
    }
  }

  //自动选择人数最小的线路
  NodeMode selectBestNode(List<NodeMode> nodes) {
    return nodes.where((node) => node.countryCode == 'HK') //筛选地区是HK的节点
        .reduce((value, element) =>
    value.onlineUsers! < element.onlineUsers! ? value : element); //选择人数最小的
  }

  void selectMinOnlineUsersNodeInRegion(String region) {
    List<NodeMode> nodesInRegion = nodeModes.where((node) => node.countryCode == region).toList();
    if (nodesInRegion.isNotEmpty) {
      NodeMode? minNode = nodesInRegion.reduce((curr, next) => curr.onlineUsers! <= next.onlineUsers! ? curr : next);
      if (minNode != null) {
        selectNode(minNode);
      }
    }
  }

  void filterNodesWithLeastUsersInHK() {
    displayStrategy.value = NodeDisplayStrategy.LeastUsers;
    updateNodesToDisplay();
  }



  void filterNodesByRegion(String region) {
    nodesToShow.value = nodeModes.where((node) => node.countryCode == region).toList();
    updateNodesToDisplay();
  }

  void showAllNodes() {
    displayStrategy.value = NodeDisplayStrategy.All;
    updateNodesToDisplay();
   // nodesToShow.value = List.from(nodeModes);
  }
  void showSelectedFirst() {
    displayStrategy.value = NodeDisplayStrategy.SelectedFirst;
    updateNodesToDisplay();
    // 如果需要，可以添加其他逻辑。
  }

  void updateNodesToDisplay() {
    List<NodeMode> nodes = List.from(nodeModes);

    switch (displayStrategy.value) {
      case NodeDisplayStrategy.LeastUsers:
        List<NodeMode> filteredNodes = nodeModes.where((node) => node.countryCode == "hk" && node.onlineUsers != null).toList();

        if (filteredNodes.isNotEmpty) {
          int? minUsers = filteredNodes.map((node) => node.onlineUsers!).reduce((curr, next) => curr < next ? curr : next);
          nodes = nodes.where((node) => node.onlineUsers == minUsers && node.countryCode == "hk").toList();
          selectNode(nodes.first);
        } else {
          // Handle the case where no nodes match the criteria. Maybe display a message or use a fallback.
          nodes = []; // Empty list or some fallback
        }

        break;
      case NodeDisplayStrategy.SelectedFirst:

        break;
      case NodeDisplayStrategy.All:
      // // 将选中的节点移动到前面
      //   if (selectedNode.value != null) {
      //     nodes.removeWhere((node) => node.id == selectedNode.value?.id);
      //     nodes.insert(0, selectedNode.value!);
      //   }
        break;
      default:
      // 不需要额外的处理，因为nodes已经包含所有节点。
        break;
    }

    nodesToShow.value = nodes; // 使用 assignAll() 方法触发更新
  }


  @override
  void onInit() {
    super.onInit();
    //fetchNodes();

    globalController = Get.put(GlobalController());
    nodeModes =  globalController.nodeModes;
    nodesToShow.value = nodeModes;
  }

  @override
  void onReady() {
    super.onReady();
  }

  @override
  void onClose() {
    super.onClose();
  }

  void increment() => count.value++;
}
