import 'dart:async';
import 'dart:ui';

import 'package:fis_common/index.dart';
import 'package:fis_common/js_plateform/js_platform.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/services/vinnoServer.m.dart';
import 'package:fis_vid/common/env.dart';
import 'package:fis_ui/define.dart';
import 'package:fis_ui/utils/sizer/sizer.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flyinsono/architecture/config/config.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/storage/shared_storage.dart';
import 'package:flyinsono/architecture/theme.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_common/web/web_asset_bundle.dart';
import 'package:fis_theme/theme.dart';
import 'package:flyinsono/js_platform/listener.dart';
import 'package:flyinsono/lab/env/env.dart';
import 'package:flyinsono/managers/index.dart';
import 'package:flyinsono/managers/interfaces/network_error_handler.dart';
import 'package:flyinsono/notifications/notifications.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'architecture/app_parameters.dart';
import 'architecture/config/model.dart';
import 'architecture/define.dart';
import 'architecture/event_bus.dart';
import 'architecture/router/index.dart';
import 'architecture/services/entity/local_setting.dart';
import 'architecture/services/index.dart';
import 'architecture/services/modules/local_setting_configurations.dart';
import 'architecture/utils/web_parameter_helpler.dart';
import 'package:universal_html/html.dart' as html;
import 'package:universal_html/js.dart' as js;

import 'managers/interfaces/permission.dart';
import 'managers/interfaces/server_config.dart';
import 'pages/consultation_dialogs/consulation_popup_listening.dart';
import 'package:fis_measure/process/workspace/rpc_bridge.dart';
import 'package:fis_jsonrpc/notifications/core/interface/connection.dart';

/// 全局设置
class Global {
  static AssetBundle? _assetBundle;
  static bool? _isVastionSlave = false;

  /// 缩放比例
  // ignore: non_constant_identifier_names
  static double SCALE_RATIO = 1.0;

  /// 缩放比例还原值
  // ignore: non_constant_identifier_names
  static double SCALE_RATIO_BACK = 1.0;

  /// 配置
  static ConfigService get config => ConfigService.ins;

  /// 资源包
  static AssetBundle get assetBundle => _assetBundle!;

  static bool get isVStationSlave => _isVastionSlave!;

  /// 初始化
  static Future<void> init() async {
    print('Global init start');
    WidgetsFlutterBinding.ensureInitialized();
    // await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);

    if (FPlatform.isAndroid) {
      final baseStyle = window.platformBrightness == Brightness.light
          ? SystemUiOverlayStyle.dark
          : SystemUiOverlayStyle.light;
      SystemUiOverlayStyle systemUiOverlayStyle = baseStyle.copyWith(
        statusBarColor: Colors.transparent,
      );
      // SystemUiOverlayStyle(statusBarColor: Colors.transparent);
      SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
    }

    // 禁用横屏
    await SystemChrome.setPreferredOrientations(
      [
        DeviceOrientation.portraitUp, // 竖屏 Portrait 模式
        DeviceOrientation.portraitDown,
        // DeviceOrientation.landscapeLeft, // 横屏 Landscape 模式
        // DeviceOrientation.landscapeRight,
      ],
    );

    // 禁用Hash路由
    // if (kIsWeb) setUrlStrategy(PathUrlStrategy());
    // if (kIsWeb) setPathUrlStrategy();

    // 日志
    if (kReleaseMode) {
      // 生产环境
      Get.isLogEnable = false;
    } else {
      // debug/profile 环境
      logger.setMinimumLevel(LogLevel.Degbug);
    }
    await logger.init();

    // 资源包
    _initAssetBundle();

    // 应用参数
    await AppParameters.load();

    Sizer.init();

    // FUI初始化
    FWidget.init(maxWebMobileWidth: 600);

    // Loading工具
    PromptBox.init();

    /// 共享存储
    await Get.putAsync<SharedStorageService>(() => SharedStorageService.init());

    // 消息中心
    notificationCenter; //触发消息中心实例创建

    // rpc; // 触发rpc init，读取配置文件需要调用PlatformService

    // 状态
    await Store.init();

    // 配置
    final config = await ConfigService.init();
    Get.put(config);
    print('currentAddress:${config.data.server.current}');

    // rpc服务
    _initRpc();
    rpc.platform.setRpcUrl(gateway);

    print('Global set  fRootBundle');
    // 主题和资源下载地址
    // fRootBundle.setResourcePath("${rpc.currentHostAddress}:9001/static/themes");
    fRootBundle.setResourcePath("http://${AppParameters.data.themeSourceRoot}");

    // 依赖注入
    await initServices();

    // 初始化测量库rpc桥【要保证 rpc 和 Store 已经初始化】
    Get.put(RPCBridge(rpc, Store.user.token));

    FManagerGuide.setup();

    // 国际化
    await _initI18n();

    print('Global set theme start');
    // 主题
    final theme = AppTheme(themeMode: ThemeMode.system);
    await FTheme.init(theme);
    Get.put(theme);
    print('Global set theme end');

    ///初始化路由
    initRouter();

    ///获取启动参数
    if (ParameterHelper.parasmeters.isEmpty)
      ParameterHelper.getAppStartParameters();

    // 监听应用级生命周期事件
    WidgetsBinding.instance.addObserver(_LifecycleEventHandler());

    if (FPlatform.isMacOS || FPlatform.isWindows) {
      VidDataHostEnv.setPlatformGetter(() => rpc.platform);
    }

    ///会诊呼叫弹窗监听
    ConsulationPopup.startListening();

    ///初始化分布式服务器
    final data = config.data;
    if (data.server.current.isNullOrEmpty ||
        Global.config.data.server.current == DefaultServerName) {
      if (kIsLab) {
        _updateRpcHostPath("http://127.0.0.1:8303");
      } else {
        await initServerSetting();
      }
      logger.i('init flyinsono server end');
    }

    _initWindowConfig();
    _getFisLanguage();
    //_initWindowLanguage();

    logger.i('ConsulationPopup startListening');

    //await Get.find<IPermissionManager>().checkMediaPermission();
    if (!kIsLab) {
      Get.find<IServerConfigManager>().initAllServerConfig(0);
    }
    if (FPlatform.isAndroid) {
      Get.find<IPermissionManager>().requestInstallPackagesPermission();
    }
    if (FPlatform.isWindows) {
      print('Currwnt environment:Windows');

      ///Todo:finlay 获取当前环境是否是推车
      await CartSystemPlatform.getIsCartSystemVersion();
      await CartSystemPlatform.getIsCartSystemVersionWithOldPlatform();

      //启动时，不通知魔盒服务器地址
      // if (config.data.server.current.isNotNullOrEmpty) {
      //   ///Todo:finlay  通知windows魔盒服务地址
      //   var uri = Uri.parse(config.data.server.current!);
      //   await CartSystemPlatform.synchServerAddressToSonopost(
      //       uri.host, uri.port.toString());
      // }
    }

    /// 是否自动登录
    /// 未设置自动登录并且有token
    /// 非纯网页端 退出登录
    ///  !ParameterHelper.parasmeters.keys.contains("page") 表示非第二窗口
    if (!Store.user.isAutoLogin &&
        Store.user.token.isNotEmpty &&
        !FPlatform.isPureWeb &&
        !ParameterHelper.parasmeters.keys.contains("page")) {
      Store.user.handelLogOut();
    }
    if (FPlatform.isWindows && kIsLab) {
      _isVastionSlave = await rpc.platform.isVStaionSlave();
    }
    disableRightClick();
    print('Global init end');
  }

  /// 初始化资源包
  static void _initAssetBundle() {
    if (kIsWeb) {
      final jsVersion = js.context["serviceWorkerVersion"];
      String version = jsVersion?.toString() ??
          "debug_${DateTime.now().millisecondsSinceEpoch}";
      _assetBundle = WebPlatformAssetBundle(
        rootPath: js.context["STATIC_ROOT"]!.toString(),
        version: version,
      );
    } else {
      _assetBundle = rootBundle;
    }
  }

  static void disableRightClick() {
    html.document.addEventListener('contextmenu', (event) {
      event.preventDefault();
    });
  }

  static void _initRpc() {
    _updateRpcHostPath(gateway);
    // _updateRpcHostPath("http://api2.flyinsono.com");
    //监听服务地址更新
    bus.on(
      bus.Keys.SERVER_ADDRESS_CHANGED,
      (arg) {
        _updateRpcHostPath(arg);
        Future.delayed(
          Duration(milliseconds: 100),
          () {
            // 等rpc先处理再获取最新服务地址
            // TODO: 更改静态资源路径
            fRootBundle.setResourcePath(
                "${rpc.currentHostAddress}:9001/static/themes");
          },
        );
      },
    );
  }

  ///重新加载配置
  static Future<void> reloadConfigService() async {
    final newConfig = await ConfigService.reload();
    Get.put(newConfig);
    final fullAddress = gateway;
    print('newConfig:${newConfig.data.server.current}');
    print("reloadConfigService: " + fullAddress);
    bus.emit(bus.Keys.SERVER_ADDRESS_CHANGED, fullAddress);
  }

  static String get gateway =>
      config.data.server.current ?? AppParameters.data.serverGateway;

  /// 是否需要移除logo
  static bool get isRemoveLogo => AppParameters.data.removeLogoDomains
      .contains(html.window.location.hostname ?? "");

  static void _updateRpcHostPath(String hostPath) {
    Uri uri = Uri.parse(hostPath);
    rpc.setServerHost("${uri.host}:${uri.port}", uri.scheme == 'https');
    rpc.clearCache();
  }

  // 国际化
  static Future<void> _initI18n() async {
    FI18n.setAssetBundle(assetBundle);

    final curLocale = Store.app.locale;

    var bookOptions = [
      FTrKeybookOption.ChineseOption,
      FTrKeybookOption.EnglishOption,
      FTrKeybookOption.RussianOption,
      FTrKeybookOption.SpanishOption,
      FTrKeybookOption.RomaniaOption,
      // FTrKeybookOption(
      //   const Locale("de", "DE"),
      //   () async {
      //     final timeSign = DateTime.now().millisecondsSinceEpoch;
      //     final path =
      //         '${fRootBundle.resourcePath}/lightness/txt/de_DE.json?v=$timeSign';
      //     final response = await fhttp.get<String>(path);
      //     final json = response.data;
      //     final FTrKeybook book = FTrKeybook.createFromJson(json ?? "");
      //     return book;
      //   },
      // ),
    ];

    await FI18n.init((locale) => Get.updateLocale(locale), bookOptions);
    await FI18n.load(curLocale);

    Get.put(FI18n.ins);

    // 监听外部对Flutter的通知
    JsPlatformListener().run();
  }

  ///初始化分布式服务器配置
  static Future<void> initServerSetting() async {
    logger.i('开始获取最快服务器');
    List<ServerInfoDTO>? result = [];
    result = await getServerInfoListAsync();
    if (result == null) {
      var servers = config.data.flyinsonoServers;
      if (servers.isEmpty) {
        servers = AppParameters.data.flyinsonoServers;
      }
      bool updateResult = false;
      for (var server in servers) {
        if (server != AppParameters.data.serverGateway) {
          _updateRpcHostPath(server);
          result = await getServerInfoListAsync();
          if (result != null) {
            updateResult = true;
            break;
          }
        }
      }

      ///如果所有尝试都失败，择继续使用默认地址
      if (!updateResult) {
        _updateRpcHostPath(AppParameters.data.serverGateway);
      }
    }
    if (result != null && result.first.host.isNotNullOrEmpty) {
      for (var i in result) {
        logger.i('最快服务器列表：${i.host}');
      }
      logger.i('当前服务器：${config.data.server.current}');
      if (config.data.server.current != result.first.host!) {
        String url = _getFullAddressFromServerResult(result.first.host!);
        logger.i('切换服务器：$url');
        _updateRpcHostPath(url);
      }
      List<String> flyinsonoServers = [];
      for (var s in result) {
        flyinsonoServers.add(s.host ?? '');
      }
      config.data.flyinsonoServers = flyinsonoServers;
      config.save();
    }
  }

  static String _getFullAddressFromServerResult(String url) {
    if (url.startsWith("http") == true) {
      return url;
    }
    final defaultProtocol = Uri.parse(AppParameters.data.serverGateway).scheme;
    return "$defaultProtocol://$url";
  }

  static Future<List<ServerInfoDTO>?> getServerInfoListAsync() async {
    try {
      logger.i('开始向：${rpc.currentHostAddress} 获取最快服务器');
      return await rpc.vinnoServer
          .getServerInfoListAsync(QueryServerInfoRequest());
    } catch (e) {
      logger.e('getServerInfoListAsync', e);
      return null;
    }
  }

  static Future<void> _initWindowConfig() async {
    try {
      ///本地配置缓存服务
      var localSettingService = Get.find<LocalSettingService>();
      await localSettingService.init();
      if (FPlatform.isMacOS || FPlatform.isWindows) {
        var isUseSecondWindow = LocalSetting.ins.isUseSecondWindow;
        if (ParameterHelper.parasmeters.containsKey('page')) {
          LocalSetting.ins.isUseSecondWindow = true;
        } else if (isUseSecondWindow == null) {
          var count = await rpc.platform.getWindowsNum();
          LocalSetting.ins.isUseSecondWindow = count > 1;
          localSettingService.save();
        }
      }
      if (FPlatform.isPureWeb) {
        Store.app.enableNewTab = LocalSetting.ins.isUseSecondWindow ?? true;
      }
    } catch (e) {
      logger.e('_initWindowsCount ex:');
    }
  }

  static Future<void> initLanguageByPlatform() async {
    ///如果是第二窗口，则获取LanguageCode
    if (ParameterHelper.parasmeters.length == 0) {
      return;
    }
    if (FPlatform.isWindows || FPlatform.isMacOS) {
      var res = await rpc.platform.getLanguageCodeAsync();
      if (res.isNotEmpty && res.contains('-')) {
        var lans = res.split('-');
        var newLocale = Locale(lans[0], lans[1]);
        if (newLocale != Store.app.locale) {
          if (newLocale == CHINESE_LOCALE) {
            _setLocalLanguagse(CHINESE_LOCALE);
          } else if (newLocale == ENGLISH_LOCALE) {
            _setLocalLanguagse(ENGLISH_LOCALE);
          }
        }
      }
    }
  }

  static Future<void> _getFisLanguage() async {
    if (FPlatform.isWindows || FPlatform.isMacOS) {
      var newResult = await _initLocalByFis();
      print('_initLocalByFis value:' + newResult.toString());
      if (newResult != null && newResult != i18nBook.locale.toCodeString("-")) {
        var lans = newResult.split('-');
        Store.app.updateLocale(Locale(lans[0], lans[1]));
      }
    }
  }

  static Future<String?> _initLocalByFis() async {
    var res = await JSPlateForm.getLanguageCode();
    if (res.isNotEmpty && res.contains('-')) {
      return res;
    }
    return null;
  }

  static void listenWsConnection() {
    notificationCenter.connection?.statusChanged
        .addListener(_onWsConnectionStatusChanged);
  }

  static void unlistenWsConnection() {
    notificationCenter.connection?.statusChanged
        .removeListener(_onWsConnectionStatusChanged);
  }

  static Future<void> _onWsConnectionStatusChanged(
      _, ConnectionStatus e) async {
    if (e != ConnectionStatus.connected) {
      return;
    }
    if (Get.isRegistered<INetworkErrorHandlerManager>()) {
      var networkErrorHandlerManager = Get.find<INetworkErrorHandlerManager>();

      if (networkErrorHandlerManager.isNetworkInterruption) {
        networkErrorHandlerManager.onNetworkInterruption.emit('', false);
        networkErrorHandlerManager.isNetworkInterruption = false;
      }
    }
  }
}

Future<void> _setLocalLanguagse(Locale newLocale) async {
  Store.app.setBusy(i18nBook.auth.switching.t);
  await Store.app.updateLocale(
    newLocale,
    updateApp: true,
    saveImmediately: true,
  );
  Store.app.cancelBusy();
}

extension GlobalNumExtensions on num {
  /// 原始尺寸
  double get ors => Global.SCALE_RATIO_BACK * (ScreenUtil().setSp(this));
}

class _LifecycleEventHandler extends WidgetsBindingObserver {
  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    switch (state) {
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
        await onDetached();
        break;
      case AppLifecycleState.resumed:
        await onResumed();
        break;
    }
  }

  Future<void> onResumed() async {
    if (Store.user.isLogin) {
      // 检查ws连接
      if (notificationCenter.isRunning == false) {
        notificationCenter.start();
      } else {
        final wsConnection = notificationCenter.connection!;
        if (wsConnection.isKeepAlive == false &&
            wsConnection.isConnected == false) {
          wsConnection.connect();
        }
      }
    }
  }

  Future<void> onDetached() async {
    await Store.persistent();
  }
}

///全局全屏事件，隐藏左边的操作栏和顶部的状态栏
class GlobalFullScreenEvent {
  static final StreamController<bool> _controller =
      StreamController<bool>.broadcast();
  static Stream<bool> get stream => _controller.stream;
  static void send(bool value) {
    _controller.add(value);
  }
}
