/// WebShell 核心库：为 H5 壳应用提供 WebView 引擎、原生桥接与平台服务。
library;

import 'dart:async';
import 'dart:convert';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:yx_app_upgrade_flutter/yx_app_upgrade_flutter.dart';

export 'package:yx_app_upgrade_flutter/yx_app_upgrade_flutter.dart'
    show AppUpgradeVersion;

// ── 配置 ──
part 'src/config/shell_environment.dart';
part 'src/config/url_resolver.dart';

// ── 引擎 ──
part 'src/engine/compatibility.dart';
part 'src/engine/recovery.dart';

// ── 桥接 ──
part 'src/bridge/bridge_protocol.dart';
part 'src/bridge/bridge_actions.dart';
part 'src/bridge/legacy_camera_compat.dart';

// ── 服务 ──
part 'src/services/config_service.dart';
part 'src/services/media_service.dart';
part 'src/services/navigation_service.dart';
part 'src/services/permission_service.dart';
part 'src/services/upgrade_service.dart';

// ── 界面 ──
part 'src/testing/test_hooks.dart';
part 'src/ui/error_overlay.dart';
part 'src/ui/launch_overlay.dart';
part 'src/ui/progress_bar.dart';
part 'src/ui/shell_app.dart';
part 'src/ui/shell_page.dart';
part 'src/ui/unsupported_platform_page.dart';

// ── 全局环境 ──
late ShellEnvironment _env;

Color get _shellAccentColor => _env.accentColor;
Color get _shellBackgroundColor => _env.backgroundColor;
Color get _shellTextColor => _env.textColor;
Color get _shellMutedTextColor => _env.mutedTextColor;
List<DeviceOrientation> get _shellPreferredOrientations =>
    _env.preferredOrientations ??
    const <DeviceOrientation>[
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ];

// ── 入口 ──

/// 启动壳应用的唯一入口。
/// 各品牌应用的 `main.dart` 调用此函数，并传入自己的 [ShellEnvironment]。
Future<void> runShellApp(ShellEnvironment environment) async {
  WidgetsFlutterBinding.ensureInitialized();
  _env = environment;

  final upgradeConfigUrl = await _applyBootstrapConfig();
  ShellUpgradeService.instance.setupConfigUrl(upgradeConfigUrl);

  _initializeUrls();
  await SystemChrome.setPreferredOrientations(_shellPreferredOrientations);
  await _enterImmersiveMode();
  runApp(const ShellApp());
}

/// 返回最终确定的 upgradeConfigUrl。
Future<String?> _applyBootstrapConfig() async {
  String? bootstrapConfigUrl;
  String? upgradeConfigUrl;

  // 1. 读取本地 Asset 启动配置
  final bootstrapAsset = _env.bootstrapConfigAsset;
  if (bootstrapAsset != null && bootstrapAsset.isNotEmpty) {
    debugPrint('WebShell 正在读取本地启动配置: $bootstrapAsset');
    final localConfig = await ShellBootstrapConfigService.loadDefaultConfig(
      bootstrapAsset,
    );
    if (localConfig != null) {
      _mergeBootstrapConfig(localConfig, source: '本地启动配置');
      bootstrapConfigUrl = localConfig.bootstrapConfigUrl?.trim();
      upgradeConfigUrl = localConfig.upgradeConfigUrl?.trim();
    }
  }

  // 2. 如果本地配置指定了远程启动配置 URL，则获取远程配置并覆盖
  if (bootstrapConfigUrl != null && bootstrapConfigUrl.isNotEmpty) {
    debugPrint('WebShell 正在获取远程启动配置: $bootstrapConfigUrl');
    final remoteConfig = await ShellBootstrapConfigService.fetchConfig(
      bootstrapConfigUrl,
    );
    if (remoteConfig != null) {
      _mergeBootstrapConfig(remoteConfig, source: '远程启动配置');
      // 远程配置可以覆盖升级地址
      if (remoteConfig.upgradeConfigUrl?.trim().isNotEmpty == true) {
        upgradeConfigUrl = remoteConfig.upgradeConfigUrl!.trim();
      }
    }
  }

  return upgradeConfigUrl;
}

void _mergeBootstrapConfig(
  ShellBootstrapConfig config, {
  required String source,
}) {
  final initialUrl = config.initialUrl?.trim();
  final preferredOrientations = config.preferredOrientations;

  if (initialUrl != null && initialUrl.isNotEmpty) {
    debugPrint('WebShell $source 覆盖了初始地址: $initialUrl');
  }
  if (preferredOrientations != null) {
    debugPrint(
      'WebShell $source 覆盖了首屏方向: '
      '${preferredOrientations.map((item) => item.name).join(', ')}',
    );
  }

  _env = _env.copyWith(
    initialUrl: initialUrl != null && initialUrl.isNotEmpty
        ? initialUrl
        : _env.initialUrl,
    preferredOrientations: preferredOrientations ?? _env.preferredOrientations,
  );
}

Future<void> _enterImmersiveMode() async {
  await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
  SystemChrome.setSystemUIOverlayStyle(
    const SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      statusBarIconBrightness: Brightness.light,
      statusBarBrightness: Brightness.dark,
      systemNavigationBarColor: Colors.black,
      systemNavigationBarDividerColor: Colors.black,
      systemNavigationBarIconBrightness: Brightness.light,
    ),
  );
}

bool _supportsEmbeddedWebView({
  bool isWeb = kIsWeb,
  TargetPlatform? platform,
}) {
  if (isWeb) {
    return false;
  }

  final target = platform ?? defaultTargetPlatform;
  return target == TargetPlatform.android;
}
