import 'dart:async';
import 'dart:developer';

import 'package:bloc/bloc.dart';
import 'package:chucker_flutter/chucker_flutter.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/widgets.dart';
import 'package:frontend_eccp_mobile/app/core/config/app_flavor.dart';
import 'package:frontend_eccp_mobile/app/core/di/injection.dart';
import 'package:frontend_eccp_mobile/app/core/navigation/app_resume_once.dart';
import 'package:frontend_eccp_mobile/app/core/navigation/settings_navigator.dart';
import 'package:frontend_eccp_mobile/app/core/notification/fcm_service.dart';
import 'package:frontend_eccp_mobile/app/core/services/bottom_sheet_service.dart';
import 'package:frontend_eccp_mobile/app/core/services/crashlytics_service.dart';
import 'package:frontend_eccp_mobile/app/core/services/location_permission_service.dart';
import 'package:frontend_eccp_mobile/app/core/utils/session_manager.dart';
import 'package:frontend_eccp_mobile/app/core/widgets/bottomsheet/app_bottom_sheet.dart';
import 'package:frontend_eccp_mobile/app/core/widgets/bottomsheet/appbottomsheet_controller.dart';
import 'package:frontend_eccp_mobile/modules/auth/login/data/model/user_session.dart';

class AppBlocObserver extends BlocObserver {
  const AppBlocObserver();

  @override
  void onChange(BlocBase<dynamic> bloc, Change<dynamic> change) {
    super.onChange(bloc, change);
    log('onChange(${bloc.runtimeType}, $change)');
  }

  @override
  void onError(BlocBase<dynamic> bloc, Object error, StackTrace stackTrace) {
    log('onError(${bloc.runtimeType}, $error, $stackTrace)');
    super.onError(bloc, error, stackTrace);
  }
}

Future<void> initSession() async {
  final session = getIt<UserSession>();

  final token = await SessionManager.getToken();
  final user = await SessionManager.getUser();

  if (token != null && user != null) {
    session
      ..token = token
      ..user = user;
  }
}

Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
  FlutterError.onError = (details) {
    log(details.exceptionAsString(), stackTrace: details.stack);
  };
  WidgetsFlutterBinding.ensureInitialized();

  await configureDependencies();
  await Firebase.initializeApp();
  await CrashlyticsService.init();
  await FcmService.init();
  await initSession();

  Bloc.observer = const AppBlocObserver();

  log('Running flavor: ${Flavor.name}');
  if (!Flavor.isProd) {
    ChuckerFlutter.showOnRelease = true;
    ChuckerFlutter.showNotification = false;
    ChuckerFlutter.isDebugMode = true;
  }
  BottomSheetService.configure(
    noInternetBuilder: (context) => AppBottomSheet(
      controller: AppBottomSheetController(),
      icon: 'assets/images/img-no-internet.png',
      title: 'Eh, jaringannya hilang...',
      subTitle:
          'Harap periksa kembali jaringan internetmu, coba lagi beberapa saat ya!',
      primaryText: 'Baik, dimengerti',
      onPrimaryPressed: () {
        Navigator.pop(context);
      },
    ),
    serverErrorBuilder: (ctx) => AppBottomSheet(
      controller: AppBottomSheetController(),
      title: 'Mohon maaf kami sedang ada gangguan!',
      primaryText: 'Baik, dimengerti',
      icon: 'assets/images/img-server-error.png',
      subTitle:
          'Saat ini permintaan kamu belum dapat diproses, coba lagi beberapa saat lagi ya!\nJika berlanjut, hubungi CS.',
      onPrimaryPressed: () {
        Navigator.pop(ctx);
      },
    ),
    notFoundBuilder: (ctx) => AppBottomSheet(
      controller: AppBottomSheetController(),
      title: 'Opps, kamu tersesat',
      primaryText: 'Baik, dimengerti',
      icon: 'assets/images/img-not-found.png',
      subTitle:
          'Mari kembali ke jalur semula, coba lagi beberapa saat lagi ya!\nJika berlanjut, hubungi CS.',
      onPrimaryPressed: () {
        Navigator.pop(ctx);
      },
    ),
    sessionExpiredBuilder: (ctx) => AppBottomSheet(
      controller: AppBottomSheetController(),
      title: 'Sesi Berakhir',
      primaryText: 'Login Ulang',
      icon: 'assets/images/img-server-error.png',
      subTitle: 'Silakan login ulang untuk melanjutkan.',
      onPrimaryPressed: () {
        Navigator.pop(ctx);
      },
    ),

    locationPermissionBuilder:
        (
          ctx, {
          required onOpenSettings,
          VoidCallback? onRequestNow,
        }) {
          return AppBottomSheet(
            controller: AppBottomSheetController(),
            title: 'Permintaan Akses Lokasi',
            primaryText: 'Buka Pengaturan',
            icon: 'assets/images/img-location-permission.png',
            subTitle:
                'E-CPP ingin meminta akses lokasi kamu agar paket yang diberikan lebih cocok untukmu!',
            onPrimaryPressed: () async {
              final resumeFut = waitRecheckOnNextResume(() async {
                if (await LocationPermissionService.recheckGranted()) {
                  onOpenSettings();
                }
              });

              await SettingsNavigator.openAppSettings();
              await resumeFut;
              if (!ctx.mounted) return;
              Navigator.pop(ctx);
            },
            // onSecondary: onRequestNow,
          );
        },
  );

  runApp(await builder());
}
