import 'dart:async';

import 'package:fis_common/logger/logger.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/utils/json_rpc_interceptor.dart';
import 'package:flyinsono/architecture/utils/web_parameter_helpler.dart';
import 'package:flyinsono/managers/interfaces/network_error_handler.dart';
import 'package:fis_common/index.dart';
import 'package:flyinsono/mock/mock.dart';
import 'package:get/get.dart';

import 'architecture/event_bus.dart';
import 'architecture/services/entity/local_setting.dart';
import 'architecture/utils/global_logout.dart';
import 'architecture/webapi/proxy.dart';

export 'architecture/webapi/proxy.dart';

final _webapi = WebApiProxy();

final _host = _ProxyHost();

/// JSON-RPC client proxy
JsonRpcProxy get rpc => _host.getProxy();

class _ProxyHost {
  // static const bool _useMock = false;
  // 演示临时开放
  bool _useMock = false;

  JsonRpcProxy? _proxy;

  /// JSON-RPC client
  JsonRpcProxy getProxy() {
    if (_proxy == null) {
      _init();
    }
    return _proxy!;
  }

  /// 重启代理
  ///
  /// [useMock] 是否开启Mock
  void reboot({bool useMock = false}) {
    _useMock = useMock;
    _buildProxy();
  }

  /// 初始化代理
  void _init() {
    _buildProxy();
    _listenServerHostChange();
  }

  /// 构建代理实例
  void _buildProxy() {
    ParameterHelper.getAppStartParameters();
    var parameters = ParameterHelper.parasmeters;
    var platformHost = "";
    print('AppStartParameters:$parameters');
    if (parameters.containsKey('page') &&
        parameters.containsKey('platformHost')) {
      if (parameters['page'] == 'measure' || parameters['page'] == 'report') {
        platformHost = parameters['platformHost'] ?? '';
        parameters.remove('platformHost');
      }
    }

    final originServerHost = _proxy?.currentHostAddress;
    JsonRpcProxy jsonRpcProxy;
    if (platformHost.isEmpty) {
      jsonRpcProxy = JsonRpcProxy();
    } else {
      jsonRpcProxy = JsonRpcProxy(host: null, platformHost: platformHost);
    }
    _proxy = _useMock ? JsonRpcMockProxy() : jsonRpcProxy;
    if (originServerHost != null && originServerHost.isNotEmpty) {
      _setRpcHost(_proxy!, originServerHost);
    }
    _proxy!.addInterceptor(_DefaultInterceptor());
    _proxy!.addInterceptor(JsonRpcExInterceptor());

    // 特殊设置
    _proxy!.platform.setTimeout(15 * 1000);
  }

  /// 监听服务地址变更
  void _listenServerHostChange() {
    bus.on(bus.Keys.SERVER_ADDRESS_CHANGED, (arg) {
      logger.i('EventBus - [${bus.Keys.SERVER_ADDRESS_CHANGED}]: $arg');
      _setRpcHost(rpc, arg);
      rpc.clearCache();
    });
  }

  static void _setRpcHost(JsonRpcProxy rpc, url) {
    final uri = Uri.parse(url);
    rpc.setServerHost("${uri.host}:${uri.port}", uri.scheme == "https");
  }
}

extension JsonRpcProxyHostControlExts on JsonRpcProxy {
  /// 重启代理
  ///
  /// [useMock] 是否开启Mock
  void reboot({bool useMock = false}) => _host.reboot(useMock: useMock);

  /// 演示使用
  bool get mocking => _host._useMock;
}

/// JSON-RPC 服务扩展
extension JsonRpcServiceExt on JsonRpcProxy {
  /// 存储WebAPI服务
  StorageWebApi get store => _webapi.storage;
}

class _DefaultInterceptor extends JsonRpcInterceptor {
  @override
  Future<JsonRpcRequest> onRequestTransmit(JsonRpcRequest request) async {
    // 以下示例：根据接口模拟高延迟
    // if (request.method == "CommonLoginAsync") {
    //   await Future.delayed(const Duration(milliseconds: 3000));
    // }
    return request;
  }

  @override
  Future onResponseResult(result) {
    if (Get.isRegistered<INetworkErrorHandlerManager>()) {
      var networkErrorHandlerManager = Get.find<INetworkErrorHandlerManager>();

      if (networkErrorHandlerManager.isNetworkInterruption) {
        networkErrorHandlerManager.onNetworkInterruption.emit('', false);
        networkErrorHandlerManager.isNetworkInterruption = false;
      }
    }
    return super.onResponseResult(result);
  }

  @override
  Future<JsonRpcServerError> onResponseError(JsonRpcServerError error) async {
    if (error.code == 2 || error.code == 1) {
      if (ParameterHelper.parasmeters.isNotEmpty &&
          ParameterHelper.parasmeters['token'] != null) {
        router.offAll(RouteNames.App.SecondSplash);
        rpc.platform.closeSlaveWindow();
        return error;
      }
      GlobalLogout.relogin();
      if ((FPlatform.isWindows || FPlatform.isMacOS) &&
          LocalSetting.ins.isUseSecondWindow!) {
        rpc.platform.tokenExpired();
      }
    }
    return error;
  }

  @override
  Future<JsonRpcNetworkException> onHttpRequestError(
      JsonRpcNetworkException error) async {
    final String message = error.message ?? '';
    if (message.contains('FHttpError ')) {
      if (Get.isRegistered<INetworkErrorHandlerManager>()) {
        // PromptBox.toast('网络连接出错，请稍后重试');
        var networkErrorHandlerManager =
            Get.find<INetworkErrorHandlerManager>();

        /// 502 不弹出网络异常
        if (!message.contains('[502]')) {
          networkErrorHandlerManager.onNetworkInterruption.emit('', true);
          networkErrorHandlerManager.isNetworkInterruption = true;
        }
      }
      // 处理 HTTP 响应错误
    }
    return error;
  }
}
