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

/// 壳应用的启动配置模型。
class ShellBootstrapConfig {
  /// 远程或本地配置指定的首页地址。
  final String? initialUrl;

  /// 应用首屏锁定方向；`null` 表示沿用宿主默认配置。
  final List<DeviceOrientation>? preferredOrientations;

  /// 可选的远程启动配置地址（用于动态覆盖本地配置）。
  final String? bootstrapConfigUrl;

  /// 可选的远程升级配置地址。
  final String? upgradeConfigUrl;

  ShellBootstrapConfig({
    this.initialUrl,
    this.preferredOrientations,
    this.bootstrapConfigUrl,
    this.upgradeConfigUrl,
  });

  factory ShellBootstrapConfig.fromJson(Map<String, dynamic> json) {
    return ShellBootstrapConfig(
      initialUrl: json['initialUrl']?.toString(),
      preferredOrientations: _parsePreferredOrientations(
        json['preferredOrientations'] ?? json['orientations'],
      ),
      bootstrapConfigUrl: json['bootstrapConfigUrl']?.toString(),
      upgradeConfigUrl: json['upgradeConfigUrl']?.toString(),
    );
  }

  static List<DeviceOrientation>? _parsePreferredOrientations(Object? value) {
    if (value is! List) {
      return null;
    }
    if (value.isEmpty) {
      return const <DeviceOrientation>[];
    }

    final orientations = <DeviceOrientation>[];
    for (final item in value) {
      final orientation = _parseDeviceOrientation(item?.toString());
      if (orientation != null && !orientations.contains(orientation)) {
        orientations.add(orientation);
      }
    }
    return orientations.isEmpty ? null : orientations;
  }

  static DeviceOrientation? _parseDeviceOrientation(String? raw) {
    final normalized = raw?.trim();
    if (normalized == null || normalized.isEmpty) {
      return null;
    }

    return switch (normalized) {
      'portraitUp' ||
      'DeviceOrientation.portraitUp' => DeviceOrientation.portraitUp,
      'portraitDown' ||
      'DeviceOrientation.portraitDown' => DeviceOrientation.portraitDown,
      'landscapeLeft' ||
      'DeviceOrientation.landscapeLeft' => DeviceOrientation.landscapeLeft,
      'landscapeRight' ||
      'DeviceOrientation.landscapeRight' => DeviceOrientation.landscapeRight,
      _ => null,
    };
  }
}

/// 负责读取本地默认启动配置，并获取远程启动配置。
class ShellBootstrapConfigService {
  static const String _cacheKey = 'webshell_bootstrap_config_cache';

  /// 从本地 asset 读取默认启动配置。
  static Future<ShellBootstrapConfig?> loadDefaultConfig(
    String assetPath,
  ) async {
    try {
      final content = await rootBundle.loadString(assetPath);
      return _parseConfigString(content);
    } catch (e) {
      debugPrint('读取 WebShell 本地启动配置失败: $e');
      return null;
    }
  }

  /// 获取并解析远程启动配置。如果网络请求失败，则尝试返回本地缓存。
  static Future<ShellBootstrapConfig?> fetchConfig(String url) async {
    try {
      final uri = Uri.tryParse(url);
      if (uri == null) {
        return _loadFromCache();
      }

      final response = await http.get(uri).timeout(const Duration(seconds: 10));
      if (response.statusCode == 200) {
        final content = utf8.decode(response.bodyBytes);
        final prefs = await SharedPreferences.getInstance();
        await prefs.setString(_cacheKey, content);
        return _parseConfigString(content);
      }
      return _loadFromCache();
    } catch (e) {
      debugPrint('获取 WebShell 启动配置失败(网络异常/超时)，尝试读取缓存: $e');
      return _loadFromCache();
    }
  }

  /// 从本地缓存读取上次成功获取的启动配置。
  static Future<ShellBootstrapConfig?> _loadFromCache() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final cachedContent = prefs.getString(_cacheKey);
      if (cachedContent != null && cachedContent.isNotEmpty) {
        debugPrint('成功读取到本地缓存的 WebShell 启动配置');
        return _parseConfigString(cachedContent);
      }
    } catch (e) {
      debugPrint('读取 WebShell 启动配置缓存失败: $e');
    }
    return null;
  }

  /// 解析字符串格式的 JSON 启动配置。
  static ShellBootstrapConfig? _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 ShellBootstrapConfig.fromJson(data);
      }
    } catch (e) {
      debugPrint('解析 WebShell 启动配置异常: $e');
    }
    return null;
  }
}
