import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hive_ce_flutter/hive_flutter.dart';
import 'package:remever/app.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/env.dart';
import 'package:remever/i18n/strings.g.dart';
import 'package:remever/inject.dart';
import 'package:remever/router.dart';
import 'package:remever/services/logs/custom_history.dart';
import 'package:remever/services/warmup_service.dart';
import 'package:talker/talker.dart';
import 'package:talker_bloc_logger/talker_bloc_logger_observer.dart';
import 'package:talker_bloc_logger/talker_bloc_logger_settings.dart';

void _onError(Object error, StackTrace trace) {
  debugPrint('error ${error.toString()}');
  logger.logError('main _onError', error, trace);
}

void _flutterError(FlutterErrorDetails details) {
  debugPrint('error ${details.context}');
  logger.logError('main _flutterError', details.exception, details.stack);
}

bool _platformDispatcher(Object exception, StackTrace stackTrace) {
  if ('$exception'.toLowerCase().contains('dio')) return true;

  debugPrint('error ${exception.toString()}');
  logger.logError('main _platformDispatcher', exception, stackTrace);

  return true;
}

void main() {
  runZonedGuarded(() async {
    WidgetsFlutterBinding.ensureInitialized();

    await Hive.initFlutter();
    await configureDependencies();

    configureEnv();

    if (!kIsWeb) {
      await ScreenUtil.ensureScreenSize();
    }

    FlutterError.onError = _flutterError;
    PlatformDispatcher.instance.onError = _platformDispatcher;

    final Talker talker = Talker(
      history: CustomHistory(
        TalkerSettings(),
        history: await logger.getHistory(),
      ),
    );

    getIt.registerSingleton<AppRouter>(AppRouter());
    getIt.registerSingleton<Talker>(talker);

    await getIt<WarmupService>().firstStart();

    Bloc.observer = TalkerBlocObserver(
      talker: talker,
      settings: const TalkerBlocLoggerSettings(
        printCreations: true,
        printClosings: true,
      ),
    );

    runApp(TranslationProvider(child: const MyApp()));
  }, _onError);
}
