part of '../../core_app.dart';

/// 远程升级配置模型。
class ShellUpgradeConfig {
  final String? versionName;
  final int? version;
  final int? isForce;
  final String? remark;
  final String? filePath;
  final int? fileSize;

  ShellUpgradeConfig({
    this.versionName,
    this.version,
    this.isForce,
    this.remark,
    this.filePath,
    this.fileSize,
  });

  factory ShellUpgradeConfig.fromJson(Map<String, dynamic> json) {
    return ShellUpgradeConfig(
      versionName: json['versionName']?.toString(),
      version: json['version'] as int?,
      isForce: (json['isForce'] ?? json['isforce']) as int?,
      remark: json['remark']?.toString(),
      filePath: json['filePath']?.toString(),
      fileSize: json['fileSize'] as int?,
    );
  }
}

/// 管理壳应用的升级逻辑，依赖 `yx_app_upgrade_flutter`。
class ShellUpgradeService {
  static final ShellUpgradeService instance = ShellUpgradeService._();
  ShellUpgradeService._();

  String? _configUrl;

  /// 注入升级配置地址。
  void setupConfigUrl(String? configUrl) {
    _configUrl = configUrl?.trim();
  }

  /// 检查应用版本，若配置中有更新则会弹出升级弹窗。
  Future<void> checkVersion(
    BuildContext context, {
    bool showNoUpdateToast = false,
  }) async {
    final configUrl = _configUrl;
    if (configUrl == null || configUrl.isEmpty) {
      if (showNoUpdateToast) {
        _showToastFromBridge(context, {'message': '未配置升级地址'});
      }
      return;
    }

    final remoteConfig = await _fetchConfig(configUrl);
    if (remoteConfig == null) {
      if (showNoUpdateToast) {
        _showToastFromBridge(context, {'message': '未获取到版本配置'});
      }
      return;
    }

    UpgradeAuxiliaryUtils.instance.initiateVersionCheck( // coverage:ignore-line
      context,
      showNoUpdateToast: showNoUpdateToast,
      future: _createVersionResolver(remoteConfig), // coverage:ignore-line
    );
  }

  Future<AppUpgradeVersion?> Function(int upType) _createVersionResolver(
    ShellUpgradeConfig remoteConfig,
  ) {
    return (int upType) async {
      return _convertToAppUpgradeVersion(remoteConfig);
    };
  }

  Future<ShellUpgradeConfig?> _fetchConfig(String url) async {
    try {
      final uri = Uri.tryParse(url);
      if (uri == null) {
        return null;
      }
      debugPrint('WebShell 正在获取升级配置: $url');
      final response = await http.get(uri).timeout(const Duration(seconds: 10));
      if (response.statusCode != 200) {
        debugPrint('获取 WebShell 升级配置失败，状态码=${response.statusCode}');
        return null;
      }
      final content = utf8.decode(response.bodyBytes);
      return _parseConfigString(content);
    } catch (e) {
      debugPrint('获取 WebShell 升级配置失败(网络异常/超时): $e');
      return null;
    }
  }

  ShellUpgradeConfig? _parseConfigString(String content) {
    try {
      final dynamic jsonMap = jsonDecode(content);
      if (jsonMap is Map<String, dynamic>) {
        final data = jsonMap['data'] is Map<String, dynamic>
            ? jsonMap['data'] as Map<String, dynamic>
            : jsonMap;
        return ShellUpgradeConfig.fromJson(data);
      }
    } catch (e) {
      debugPrint('解析 WebShell 升级配置异常: $e');
    }
    return null;
  }

  /// 将远程 JSON 配置转换为升级弹窗所需的数据模型。
  AppUpgradeVersion? _convertToAppUpgradeVersion(ShellUpgradeConfig config) {
    if (config.version == null || config.versionName == null) {
      return null;
    }

    final apkSizeBytes = config.fileSize != null
        ? config.fileSize! * 1024
        : null;
    final filePath = (config.filePath != null && config.filePath!.isNotEmpty)
        ? config.filePath
        : null;

    return AppUpgradeVersion(
      versionName: config.versionName,
      versionBuildNumber: config.version,
      isForce: config.isForce == 1,
      updateContent: config.remark ?? '',
      downloadUrl: filePath,
      appStoreUrl: filePath,
      apkSize: apkSizeBytes,
      supportedMethods: [
        AppUpgradeMethod.browser,
        AppUpgradeMethod.inApp,
        AppUpgradeMethod.market,
      ],
    );
  }
}
