import 'dart:async';
import 'dart:developer' as dev;
import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:puzzleweave/ads/applovin_ads_controller.dart';
import 'package:puzzleweave/app_lifecycle/app_lifecycle.dart';
import 'package:puzzleweave/audio/jc_audio_controller.dart';
import 'package:puzzleweave/firebase/firebase_options.dart';
import 'package:puzzleweave/homepage/home_screen.dart';
import 'package:puzzleweave/l10n/app_localizations.dart';
import 'package:puzzleweave/models/data.dart';
import 'package:puzzleweave/models/items.dart';
import 'package:puzzleweave/persistence/persistence.dart';
import 'package:puzzleweave/play/board_play.dart';
import 'package:puzzleweave/remote_config/remote_config.dart';
import 'package:puzzleweave/settings/settings_controller.dart';
import 'package:puzzleweave/utils/utils.dart';

import 'config/config.dart' as cfg;
import 'config/device.dart';

Logger _log = Logger('main.dart');

final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

void main() async {
  // Subscribe to log messages.
  Logger.root.onRecord.listen((record) {
    dev.log(
      record.message,
      time: record.time,
      level: record.level.value,
      name: record.loggerName,
      zone: record.zone,
      error: record.error,
      stackTrace: record.stackTrace,
    );
  });

  WidgetsFlutterBinding.ensureInitialized();

  // 强制竖屏
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);

  // 进入全屏沉浸式， 隐藏底部导航以及状态栏
  if (Platform.isAndroid) {
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
  }

  SystemChrome.setSystemUIOverlayStyle(
    const SystemUiOverlayStyle(
      statusBarColor: Colors.transparent, // <-- SEE HERE
      statusBarIconBrightness: Brightness.dark, //<-- For Android SEE HERE (dark icons)
      statusBarBrightness: Brightness.light, //<-- For iOS SEE HERE (dark icons)
    ),
  );

  ////////////////////// firebase relate ///////////////////////////////

  if (!kIsWeb && (Platform.isAndroid)) {
    try {
      await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

      FlutterError.onError = (errorDetails) {
        FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
      };

      // Pass all uncaught asynchronous errors
      // that aren't handled by the Flutter framework to Crashlytics.
      PlatformDispatcher.instance.onError = (error, stack) {
        final errorStr = error.toString();

        // 1. 扩展网络/环境类异常的拦截范围
        final bool isEnvironmentIssue =
            error is SocketException ||
            error is HttpException ||
            error is HandshakeException ||
            errorStr.contains('ClientException') ||
            errorStr.contains('SocketException') ||
            errorStr.contains('HandshakeException') ||
            errorStr.contains('Failed host lookup') ||
            errorStr.contains('Network is unreachable') ||
            errorStr.contains('Connection timed out') ||
            errorStr.contains('Connection closed') || // 补充：上个日志提到的错误
            errorStr.contains('Connection reset') || // 补充：被对方重置
            errorStr.contains('Unable to connect');

        if (isEnvironmentIssue) {
          _log.warning('已拦截环境异常: $errorStr');
          FirebaseCrashlytics.instance.log('Env Error (Ignored): $errorStr');
          return true;
        }

        // 2. 拦截插件缺失类异常
        if (error is MissingPluginException) {
          _log.warning('插件未找到: $errorStr');
          return true;
        }

        // 3. 剩下的才是逻辑错误（如 Null Check, Range Error）
        // 改为 fatal: false，避免降低 Google Play 的“崩溃率评分”
        _log.severe('未处理的逻辑错误', error, stack);
        FirebaseCrashlytics.instance.recordError(error, stack, fatal: false);

        return true;
      };
    } catch (e) {
      debugPrint("Firebase couldn't be initialized: $e");
    }
  }

  //本地参数存储初始化
  await Persistence().initialize();

  // 远程参数初始化
  await RemoteConfig().initialize();

  // 记录程序运行时间
  Persistence().lastRunTime = DateTime.now();

  Directory baseDir = await getApplicationDocumentsDirectory();

  // 首次运行， 将json写入
  if (Persistence().firstRun) {
    final json = await loadJSONFromAsset('assets/builtin/${cfg.Config.firstId}.json');
    await saveJson('work/${cfg.Config.firstId}.json', json);
  }

  runApp(MyApp(baseDir: baseDir));
}

class MyApp extends StatelessWidget {
  final Directory baseDir;
  const MyApp({super.key, required this.baseDir});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    cfg.Config config = cfg.Config(context, baseDir);
    return AppLifecycleObserver(
      child: MultiProvider(
        providers: [
          Provider<Data>(lazy: false, create: (context) => Data(persistence: Persistence())..loadDataFromPersistence()),
          Provider<SettingsController>(lazy: false, create: (context) => SettingsController(persistence: Persistence())..loadStateFromPersistence()),
          // ProxyProvider2<SettingsController, ValueNotifier<AppLifecycleState>, AudioController>(
          //   lazy: false,
          //   create: (context) => AudioController()..initialize(),
          //   update: (context, settings, lifecycleNotifier, audio) {
          //     if (audio == null) throw ArgumentError.notNull();
          //     audio.attachSettings(settings);
          //     audio.attachLifecycleNotifier(lifecycleNotifier);
          //     return audio;
          //   },
          //   dispose: (context, audio) => audio.dispose(),
          // ),
          ProxyProvider2<SettingsController, ValueNotifier<AppLifecycleState>, JcAudioController>(
            lazy: false,
            create: (context) => JcAudioController()..initialize(),
            update: (context, settings, lifecycleNotifier, audio) {
              if (audio == null) throw ArgumentError.notNull();
              audio.attachSettings(settings);
              audio.attachLifecycleNotifier(lifecycleNotifier);
              return audio;
            },
            dispose: (context, audio) => audio.dispose(),
          ),

          Provider<ApplovinAdsController>(create: (context) => ApplovinAdsController(context)),
          Provider<cfg.Config>(lazy: false, create: (context) => config),
          Provider<Device>(lazy: false, create: (context) => config.device),
        ],

        child: Prepare(
          child: MaterialApp(
            key: GlobalKey(),
            title: 'Jigsort Solitaire',
            // initialRoute: firstRun ? '/play' : '/', // 首次游戏直接进入游戏页面，而不是合集页
            initialRoute: '/', // 统一先到HomeScreen， 再根据情况跳转到相应页面
            navigatorObservers: [routeObserver],
            routes: {
              '/': (context) => const HomeScreen(),
              // '/': (context) => const GalleryScreen(),
              '/play': (context) => BoardPlay(
                item: AssetItem(
                  cfg.Config.firstId,
                  '',
                  2000,
                  3000,
                  3,
                  false,
                  'assets/builtin/${cfg.Config.firstId}.jpeg',
                  'assets/builtin/${cfg.Config.firstId}.jpeg',
                ),
                firstRun: true,
              ),
            },
            theme: ThemeData(
              // textTheme: GoogleFonts.nunitoSansTextTheme(Theme.of(context).textTheme),
              brightness: Brightness.light,
              primaryColor: Colors.green,
              primarySwatch: Colors.blue,
            ),

            ///多语言设置
            localizationsDelegates: AppLocalizations.localizationsDelegates,
            supportedLocales: AppLocalizations.supportedLocales,

            /// 设置默认语言为英语
            localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) {
              var result = supportedLocales.where((element) => element.languageCode == locale?.languageCode);
              if (result.isNotEmpty) {
                Device.locale = locale!;
                _log.info('当前语言(支持)：${Device.locale!.countryCode}-${Device.locale!.languageCode}');
                return locale;
              }
              Device.locale = const Locale('en');
              _log.info('当前语言(默认)：${Device.locale!.countryCode}-${Device.locale!.languageCode}');
              return Device.locale;
            },
          ),
        ),
      ),
    );
  }
}

class Prepare extends StatefulWidget {
  final Widget child;
  const Prepare({super.key, required this.child});

  @override
  State<Prepare> createState() => _PrepareState();
}

class _PrepareState extends State<Prepare> {
  @override
  void initState() {
    super.initState();
    loadDeviceInfo();
  }

  /// 获取android平台信息，用户判断是否低端机
  loadDeviceInfo() async {
    DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
    if (Platform.isAndroid) {
      try {
        context.read<Device>().androidDeviceInfo = await deviceInfoPlugin.androidInfo;
      } catch (e) {}
    }
  }

  @override
  Widget build(BuildContext context) {
    // applovin max 没有类似的api可以获取banner高度，以下代码注释掉
    //Update ad banner size
    // AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(
    //   MediaQuery.of(context).size.width.truncate(),
    // ).then((value) {
    //   if (value != null) {
    //     context.read<Device>().bannerHeight = value.height.toDouble();
    //   }
    // }).catchError((err) {
    //   //todo
    // });

    return widget.child;
  }
}
