import 'dart:async';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
import 'package:aitrainer_app/util/session.dart';
import 'package:aitrainer_app/view/account.dart';
import 'package:aitrainer_app/view/custom_exercise_page.dart';
import 'package:aitrainer_app/view/customer_bodytype_page.dart';
import 'package:aitrainer_app/view/customer_fitness_page.dart';
import 'package:aitrainer_app/view/customer_goal_page.dart';
import 'package:aitrainer_app/view/customer_modify_page.dart';
import 'package:aitrainer_app/view/customer_welcome_page.dart';
import 'package:aitrainer_app/view/exercise_control_page.dart';
import 'package:aitrainer_app/view/exercise_type_description.dart';
import 'package:aitrainer_app/view/gdpr.dart';
import 'package:aitrainer_app/view/login.dart';
import 'package:aitrainer_app/view/exercise_new_page.dart';
import 'package:aitrainer_app/view/menu_page.dart';
import 'package:aitrainer_app/view/registration.dart';
import 'package:aitrainer_app/view/settings.dart';
import 'package:aitrainer_app/widgets/home.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:sentry/sentry.dart';
import 'bloc/account/account_bloc.dart';
import 'bloc/menu/menu_bloc.dart';
import 'bloc/session/session_bloc.dart';
import 'bloc/settings/settings_bloc.dart';

final SentryClient _sentry = new SentryClient(dsn: 'https://5fac40cbfcfb4c15aa80c7a8638d7310@o418565.ingest.sentry.io/5322520');

/// Whether the VM is running in debug mode.
///
/// This is useful to decide whether a report should be sent to sentry. Usually
/// reports from dev mode are not very useful, as these happen on developers'
/// workspaces rather than on users' devices in production.
bool get isInDebugMode {
  bool inDebugMode = false;
  assert(inDebugMode = true);
  return inDebugMode;
}

/// Reports [error] along with its [stackTrace] to Sentry.io.
Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
  print('Caught error: $error');

  // Errors thrown in development mode are unlikely to be interesting. You can
  // check if you are running in dev mode using an assertion and omit sending
  // the report.
  if (isInDebugMode) {
    print(stackTrace);
    print('In dev mode. Not sending report to Sentry.io.');
    return;
  }

  print('Reporting to Sentry.io...');

  final SentryResponse response = await _sentry.captureException(
    exception: error,
    stackTrace: stackTrace,
  );

  if (response.isSuccessful) {
    print('Success! Event ID: ${response.eventId}');
  } else {
    print('Failed to report to Sentry.io: ${response.error}');
  }
}

Future<Null> main() async {
  // This captures errors reported by the Flutter framework.
  FlutterError.onError = (FlutterErrorDetails details) async {
    if (isInDebugMode) {
      // In development mode simply print to console.
      FlutterError.dumpErrorToConsole(details);
    } else {
      // In production mode report to the application zone to report to
      // Sentry.
      Zone.current.handleUncaughtError(details.exception, details.stack);
    }
  };

  // This creates a [Zone] that contains the Flutter application and stablishes
  // an error handler that captures errors and reports them.
  //
  // Using a zone makes sure that as many errors as possible are captured,
  // including those thrown from [Timer]s, microtasks, I/O, and those forwarded
  // from the `FlutterError` handler.
  //
  // More about zones:
  //
  // - https://api.dartlang.org/stable/1.24.2/dart-async/Zone-class.html
  // - https://www.dartlang.org/articles/libraries/zones
  runZonedGuarded<Future<Null>>(() async {
    runApp(
        MultiBlocProvider(
          providers: [
            BlocProvider<SessionBloc>(
              create: (BuildContext context) => SessionBloc(session: Session()),
            ),
            BlocProvider<MenuBloc>(
              create: (BuildContext context) => MenuBloc( menuTreeRepository: MenuTreeRepository()),
            ),
            BlocProvider<SettingsBloc>(
              create: (BuildContext context) => SettingsBloc(),
            ),
            BlocProvider<AccountBloc>(
              create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
            ),
          ],

          child:  AitrainerApp(),
        )
    );
  }, (error, stackTrace) async {
    await _reportError(error, stackTrace);
  });
}


class AitrainerApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    return MaterialApp(
      localizationsDelegates: [
        // ... app-specific localization delegate[s] here
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', "US"), // English
        const Locale('hu', "HU"), // Hungarian
        // ... other locales the app supports
      ],
      localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) {
        //myLocale = deviceLocale ;
        // here you make your app language similar to device language ,
        // but you should check whether the localization is supported by your app
        Locale realSupportedLocale = Locale('en', "US");
        supportedLocales.forEach((supportedLocale) {
          if ( locale != null && supportedLocale != null &&
              supportedLocale.countryCode == locale.countryCode ) {
            realSupportedLocale = supportedLocale;
          }
        });
        if ( locale != null && realSupportedLocale.countryCode != locale.countryCode ) {
          print ("Locale " + locale.countryCode + " not supported on this device :(");
        }
        return realSupportedLocale;
      },
      routes: {
        'home': (context) => AitrainerHome(),
        'customerModifyPage': (context) => CustomerModifyPage(),
        'customerGoalPage': (context) => CustomerGoalPage(),
        'customerFitnessPage': (context) => CustomerFitnessPage(),
        'customerBodyTypePage': (context) => CustomerBodyTypePage(),
        'customerWelcomePage': (context) => CustomerWelcomePage(),
        'exerciseNewPage': (context) => ExerciseNewPage(),
        'exerciseCustomPage': (context) => CustomExercisePage(),
        'exerciseControlPage': (context) => ExerciseControlPage(),
        'login': (context) => LoginPage(),
        'registration': (context) => RegistrationPage(),
        'gdpr': (context) => Gdpr(),
        'menu_page': (context) => MenuPage(),
        'account': (context) => AccountPage(),
        'settings': (context) => SettingsPage(),
        'exerciseTypeDescription': (context) => ExerciseTypeDescription(),
      },
      initialRoute: 'home',
      title: 'Aitrainer',
      theme: ThemeData(
        brightness: Brightness.light,
        //primarySwatch: Colors.transparent,
        fontFamily: 'Arial',
        textTheme: TextTheme(
          bodyText1: TextStyle(fontSize: 14.0),
        )
      ),
      home: AitrainerHome(),

    );
  }
}