import 'dart:convert';
import 'package:get/get.dart';
import 'package:naiyouwl/app/bean/clash_core.dart';
import 'package:naiyouwl/app/bean/connect.dart';
import 'package:naiyouwl/app/bean/rule.dart';
import 'package:naiyouwl/app/common/LogHelper.dart';

import 'package:naiyouwl/app/utils/system_proxy.dart';
import 'package:web_socket_channel/io.dart';

import 'package:http/http.dart' as http;
class CoreController extends GetxController {
  // late final dio  = Dio(BaseOptions(
  //      baseUrl: 'http://127.0.0.1:9799',
  // ));

  var ip = "127.0.0.1";
  var url = "";
  var client = http.Client();
  var headers = Map<String,String>();
  late final LogHelper _logger = LogHelper();
  var version = ClashCoreVersion(premium: true, version: '').obs;
  var address = ''.obs;
  var secret = ''.obs;
  var config = ClashCoreConfig(
    port: 0,
    socksPort: 0,
    redirPort: 0,
    tproxyPort: 0,
    mixedPort: 0,
    allowLan: false,
    bindAddress: '',
    mode: 'rule',
    logLevel: '',
    ipv6: false,
  ).obs;

  var ruleProvider = RuleProvider(providers: {}).obs;
  var rule = Rule(rules: []).obs;

  CoreController(){
    // dio.interceptors.add(LogInterceptor(
    //   request: true,
    //   requestBody: true,
    //   responseBody: true,
    //   error: true,
    //   logPrint: _logger.d, // 使用 Logger 插件打印日志
    // ));
   //dio.interceptors.add(FriendlyErrorInterceptor());
  }

  SystemProxyConfig get proxyConfig {
    final mixedPort = config.value.mixedPort == 0 ? null : config.value.mixedPort;
    final httpPort = mixedPort ?? config.value.port;
    final httpsPort = mixedPort ?? config.value.port;
    final socksPort = mixedPort ?? config.value.socksPort;
    return SystemProxyConfig(
      http: httpPort == 0 ? null : '127.0.0.1:$httpPort',
      https: httpsPort == 0 ? null : '127.0.0.1:$httpsPort',
     socks: socksPort == 0 ? null : '127.0.0.1:$socksPort',
    );
  }

  setApi(String apiAddress, String apiSecret) {
    address.value = apiAddress;
    secret.value = apiSecret;
    // dio.close(force: true);
    url = "${address.value}";
    headers["Authorization"] = 'Bearer ${secret.value}';
    //client.head(Uri.http(url,'info'))
    // dio.options.baseUrl = 'http://${address.value}';
    // print("dio baseUrl api ${dio.options.baseUrl}");
    // dio.options.headers['Authorization'] = 'Bearer ${secret.value}';
  }

  Future<dynamic> fetchHello() async {
    try {
      var ut = Uri.parse('http://$url/info');
      final res = await  client.get(ut,headers: headers);
      if(res.statusCode == 200) {
        var jsonResponse =
        jsonDecode(res.body) as Map<String, dynamic>;
        return jsonResponse;
      }
    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('Client fetchHello Exception: ${e.message}');
      return null;
    } on Exception catch (e) {
      // 处理其他类型的异常
      print('Exception: $e');
      return null;
    }
  }

  Future<ClashCoreVersion?> updateVersion() async {
    try {
      var ut = Uri.parse('http://$url/version');
      final res = await  client.get(ut,headers: headers);
      if(res.statusCode == 200) {
        var jsonResponse =
        jsonDecode(res.body) as Map<String, dynamic>;
        version.value = ClashCoreVersion.fromJson(jsonResponse);
        return version.value;
      }

    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('Client updateVersion Exception: ${e.message}');
      return null;
    } on Exception catch (e) {
      // 处理其他类型的异常
      print('Exception: $e');
      return null;
    }
    return null;
  }

  Future<void> updateConfig() async {

    try {
      var ut = Uri.parse('http://$url/configs');
      final res = await  client.get(ut,headers: headers);
      print("updateConfig ---- ${res.statusCode}");
      if(res.statusCode == 200) {
        var jsonResponse =
        jsonDecode(res.body) as Map<String, dynamic>;
        config.value = ClashCoreConfig.fromJson(jsonResponse);
      }

    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('Client updateConfig Exception: ${e.message}');

    } on Exception catch (e) {
      // 处理其他类型的异常
      print('Exception updateConfig: $e');

    }
  }

  Future<void> fetchConfigUpdate(Map<String, dynamic> config) async {
    try {

      ///configs
      ///
      // {"mode":"global"}
      //请求 URL:
      // http://127.0.0.1:9799/configs
      // 请求方法:
      // PATCH
      var ut = Uri.parse('http://$url/configs');
      final res = await client.patch(ut, headers: headers, body: jsonEncode(config));
      print("fetchConfigUpdate ---- ${res.statusCode}");
      if (res.statusCode == 204) {
        print("配置更新成功");
      } else {
        print("配置更新失败，状态码: ${res.statusCode}");
      }
      // var jsonResponse =
      // jsonDecode(res.body) as Map<String, dynamic>;
      // print(jsonResponse);
      await updateConfig();
    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('Client fetchConfigUpdate Exception: ${e.message}');

    } on Exception catch (e) {
      // 处理其他类型的异常
      print('Exception fetchConfigUpdate: $e');

    }
  }

  Future<void> changeConfig(String configPath) async{
    for (var i = 0 ; i< 5; i++) {

      try {
        final body = json.encode({
          "path": configPath
        });
        var ut = Uri.parse('http://$url/configs');
        final res = await  client.put(ut,body:body,headers: headers);
        print("changeConfig ---- ${res.statusCode}");
        if(res.statusCode == 204)
        {
          await updateConfig();
          break;
        }
      } on http.ClientException catch (e) {
        // 处理客户端异常，例如没有网络连接
        print('Client changeConfig Exception: ${e.message}');
        continue;
      } on Exception catch (e) {
        // 处理其他类型的异常
        print('Exception changeConfig : $e');

        continue;
      }
    }
  }

  // type updateConfigRequest struct {
  // 	Path    string `json:"path"`
  // 	Payload string `json:"payload"`
  // }
  // https://github.com/Dreamacro/clash/blob/c231fd14666d6ea05d6a75eaba6db69f9eee5ae9/hub/route/configs.go#L95
  // Future<void> fetchReloadConfig(Map<String, String> config) async {
  //   print("fetchReloadConfig $config");
  //   await dio.put('/configs', data: config);
  // }

  Future<void> fetchCloseConnections(String id) async {
    //await dio.delete('/connections/${Uri.encodeComponent(id)}');
    try {
      var ut = Uri.parse('http://$url/connections/${Uri.encodeComponent(id)}');

      final res = await  client.delete(ut,headers: headers);
      print("fetchCloseConnections ---- ${res.statusCode}");
      if(res.statusCode == 204){
        var jsonResponse =
        jsonDecode(res.body) as Map<String, dynamic>;
        print(jsonResponse);
        await updateConfig();
      }

    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('Client fetchCloseConnections Exception: ${e.message}');

    } on Exception catch (e) {
      // 处理其他类型的异常
      print('Exception: $e');

    }
  }

  IOWebSocketChannel fetchConnectionsWs() {
    return IOWebSocketChannel.connect(
      Uri.parse('ws://${address.value}/connections'),
      headers: headers,
    );
  }

  Future updateRuleProvider() async {
    // final res = await dio.get('/providers/rules');
    // ruleProvider.value = RuleProvider.fromJson(res.data);
    // ruleProvider.refresh();

    try {

      var ut = Uri.parse('http://$url/poviders/rules');
      final res = await  client.get(ut,headers: headers);
      if(res.statusCode == 200){
        var jsonResponse =
        jsonDecode(res.body) as Map<String, dynamic>;
        ruleProvider.value = RuleProvider.fromJson(jsonResponse);
        ruleProvider.refresh();
      }

    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('Client updateRuleProvider Exception: ${e.message}');

    } on Exception catch (e) {
      // 处理其他类型的异常
      print('Exception: $e');

    }
  }

  Future updateRule() async {
    // final res = await dio.get('/rules');
    // rule.value = Rule.fromJson(res.data);
    // rule.refresh();

    try {

      var ut = Uri.parse('http://$url/rules');
      final res = await  client.get(ut,headers: headers);
      if(res.statusCode == 200){
        var jsonResponse =
        jsonDecode(res.body) as Map<String, dynamic>;
        rule.value = Rule.fromJson(jsonResponse);
        rule.refresh();
      }

    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('Client updateRule Exception: ${e.message}');

    } on Exception catch (e) {
      // 处理其他类型的异常
      print('Exception: $e');

    }
  }

  // Future<void> fetchRuleProviderUpdate(String name) async {
  //   await dio.put('/providers/rules/${Uri.encodeComponent(name)}');
  // }

  // Future<Proxie> fetchProxie() async {
  //   final res = await dio.get('/proxies');
  //   return Proxie.fromJson(res.data);
  // }

  // Future<ProxieProvider> fetchProxieProvider() async {
  //   final res = await dio.get('/providers/proxies');
  //   return ProxieProvider.fromJson(res.data);
  // }

  // Future<void> fetchProxieProviderHealthCheck(String provider) async {
  //   await dio.get('/providers/proxies/${Uri.encodeComponent(provider)}/healthcheck');
  // }

  Future<void> fetchSetProxieGroup(String group, String value) async {
    try {
      // 构建请求体
      final body = json.encode({
        'name': value // 确认 value 是正确的代理名称
      });

      // 构建 URL，确保 group 是正确的代理组名称
      var ut = Uri.parse('http://$url/proxies/${Uri.encodeComponent(group)}');

      // 发起 PUT 请求，选择代理
      final ret = await client.put(ut, body: body, headers: headers);

      // 输出返回的状态码，确保请求成功
      print("fetchSetProxieGroup ${ret.statusCode}");

      // 检查状态码，确保请求成功
      if (ret.statusCode == 200) {
        print('Proxy group updated successfully.');
      } else {
        print('Failed to update proxy group: ${ret.statusCode}');
      }

    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('fetchSetProxieGroup ClientException: ${e.message}');
    } on Exception catch (e) {
      // 处理其他类型的异常
      print('fetchSetProxieGroup Exception: $e');
    }
  }
  //
  // Future<void> fetchProxieProviderUpdate(String name) async {
  //   await dio.put('/providers/proxies/${Uri.encodeComponent(name)}');
  // }

  // Future<int> fetchProxieDelay(String name) async {
  //   final query = {'timeout': 5000, 'url': 'http://www.gstatic.com/generate_204'};
  //   final res = await dio.get('/proxies/${Uri.encodeComponent(name)}/delay', queryParameters: query);
  //   return res.data['delay'] ?? 0;
  // }
  //
  Future<Connect?> fetchConnection() async {
    // final res = await dio.get('/connections');
    // if(res.data !=null){
    //  // LogHelper().d("没有连接");
    //   //return Connect();
    // }
    try {

      var ut = Uri.parse('http://$url/connections');
      final res = await  client.get(ut,headers: headers);
      if(res.statusCode == 200){
        var jsonResponse =
        jsonDecode(res.body) as Map<String, dynamic>;
        return Connect.fromJson(jsonResponse);

      }

    } on http.ClientException catch (e) {
      // 处理客户端异常，例如没有网络连接
      print('fetchConnection Exception: ${e.message}');
      return null;
    } on Exception catch (e) {
      // 处理其他类型的异常
      print('fetchConnection Exception: $e');
      return null;
    }

  }
}



