// ignore_for_file: unnecessary_null_comparison

import 'dart:convert';

import 'package:byod/bloc/category_selection.dart';
import 'package:byod/bloc/check_voucher.dart';
import 'package:byod/bloc/member_info.dart';
import 'package:byod/bloc/order_bloc.dart';
import 'package:byod/bloc/search_menu.dart';
import 'package:byod/ui/no_route.dart';
import 'package:byod/ui/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_strategy/url_strategy.dart';
import 'package:uuid/uuid.dart';
import 'package:web_browser_detect/web_browser_detect.dart';

import 'bloc/branch_exist.dart';
import 'bloc/fav_selected_bar.dart';
import 'bloc/feedback_option.dart';
import 'bloc/feedback_select.dart';
import 'bloc/filter_menu.dart';
import 'bloc/menu_selected_bar.dart';
import 'bloc/order_detail_variant.dart';
import 'bloc/order_variant_temporary.dart';
import 'bloc/order_variant_value.dart';
import 'bloc/search_active.dart';
import 'bloc/view_bill.dart';
import 'package:flutter/services.dart' as bundle_root;

import 'bloc/voucher_list.dart';

late SharedPreferences prefs;
bool isExcelso = false;
bool isResponsive = false;
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
String defaultTitle = 'Ravintola - BYOD';
bool debug = false; // set true pada config.json jika ingin ada log print
String browserName = 'Wrong platform';
String browserVersion = '';

//** Version Build Number */
const int majorVersion = 1;
const int minorVersion = 2;
//** Version Build Number */

void main() async {
  final browser = Browser.detectOrNull();
  browserName = browser?.browser ?? 'Wrong platform';
  browserVersion = browser?.version ?? 'Wrong platform';
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
  setPathUrlStrategy();
  WidgetsFlutterBinding.ensureInitialized();
  prefs = await SharedPreferences.getInstance();

  configLoading();

  loadAssetConfig().then((value) {
    runApp(MyApp(
      title: value,
    ));
  });
}

//easy loading
void configLoading() {
  EasyLoading.instance
    ..displayDuration = const Duration(milliseconds: 2000)
    ..indicatorType = EasyLoadingIndicatorType.fadingCircle
    ..loadingStyle = EasyLoadingStyle.dark
    ..indicatorSize = 45.0
    ..radius = 10.0
    ..progressColor = Colors.yellow
    ..backgroundColor = Colors.green
    ..indicatorColor = Colors.yellow
    ..textColor = Colors.yellow
    ..maskColor = Colors.blue.withOpacity(0.5)
    ..userInteractions = true
    ..dismissOnTap = false;
}

Future<String> loadAssetConfig() async {
  String title;

  try {
    String datas = await bundle_root.rootBundle.loadString('config.json');
    var jsoDecode = jsonDecode(datas);
    title = jsoDecode['title'].toString();
    isResponsive = jsoDecode['isResponsive'];
    debug = jsoDecode['debug'];
    if (title == null) {
      return defaultTitle;
    } else {
      return title;
    }
  } catch (e) {
    return defaultTitle;
  }
}

// ignore: must_be_immutable
class MyApp extends StatelessWidget {
  // String myUrl, param, brand, tn, role, cashierName, toViewBill;
  String title;
  MyApp({
    Key? key,
    required this.title,
  }) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    //** UUID */
    const uuidInit = Uuid();
    var uuid = uuidInit.v4();
    //** UUID */

    //** Check Session ID */
    String currentSessionId = prefs.getString('sessionId') ?? '';
    String sessionId;
    if (currentSessionId != '') {
      sessionId = currentSessionId;
    } else {
      sessionId = uuid;
    }
    //** Check Session ID */

    String paramStrg = '';
    String brandStrg = '';
    String tnStrg = '';
    String roleStrg = 'customer';
    String toBill = '';
    String cashierNameStrg = '';
    String tokenUser = '';

    return MultiBlocProvider(
      providers: [
        BlocProvider(create: (_) => OrdersBloc()),
        BlocProvider(create: (_) => BranchExist()),
        // BlocProvider(create: (_) => CategoryMenu()),
        BlocProvider(create: (_) => OrderVariantTemporaryBloc()),
        BlocProvider(create: (_) => OrderVariantValueBloc()),
        BlocProvider(create: (_) => OrderDetailVariant()),
        BlocProvider(create: (_) => SearchMenu()),
        BlocProvider(create: (_) => VoucherCheck()),
        BlocProvider(create: (_) => CategorySelection()),
        BlocProvider(create: (_) => MemberInfoBloc()),
        BlocProvider(create: (_) => ViewBillBloc()),
        BlocProvider(create: (_) => FeedBackOptionBloc()),
        BlocProvider(create: (_) => FeedbackSelect()),
        BlocProvider(create: (_) => FilterMenuBloc()),
        BlocProvider(create: (_) => VoucherListBloc()),
        BlocProvider(create: (_) => FavSelectedBar()),
        BlocProvider(create: (_) => MenuSelectedBar()),
        BlocProvider(create: (_) => SearchActive()),
      ],
      child: MaterialApp(
          title: (title == null) ? defaultTitle : title,
          builder: EasyLoading.init(),
          debugShowCheckedModeBanner: false,
          onGenerateRoute: (routes) {
            var uri = Uri.parse(routes.name!);
            if (uri.pathSegments.isEmpty) {
              return MaterialPageRoute(
                  builder: (context) => NoRoute(
                        identification: 'emptyUri',
                      ));
            } else if (uri.pathSegments.length == 3) {
              brandStrg = uri.pathSegments.first;
              paramStrg = uri.pathSegments[1];
              tnStrg = uri.pathSegments[2];

              return MaterialPageRoute(
                  builder: (_) => Splash(
                      param: paramStrg,
                      brand: brandStrg,
                      tn: tnStrg,
                      role: roleStrg,
                      cashierName: cashierNameStrg,
                      toBill: toBill,
                      sessionId: sessionId,
                      token: tokenUser));
            } else if (uri.pathSegments.length == 4) {
              brandStrg = uri.pathSegments.first;
              paramStrg = uri.pathSegments[1];
              tnStrg = uri.pathSegments[2];
              if (uri.pathSegments[3] == 'go') {
                toBill = 'go';
              } else if (uri.pathSegments[3].length == 32) {
                // its uuid or not

                tokenUser = uri.pathSegments[3];
                isExcelso = true;
              }
              return MaterialPageRoute(
                  builder: (_) => Splash(
                      param: paramStrg,
                      brand: brandStrg,
                      tn: tnStrg,
                      role: roleStrg,
                      cashierName: cashierNameStrg,
                      toBill: toBill,
                      sessionId: sessionId,
                      token: tokenUser));
            } else if (uri.pathSegments.length == 5) {
              brandStrg = uri.pathSegments.first;
              paramStrg = uri.pathSegments[1];
              tnStrg = uri.pathSegments[2];
              if (uri.pathSegments[3] == 'cashier') {
                // roleStrg = 'cashier';
                roleStrg = 'customer';
                cashierNameStrg = uri.pathSegments[4];
              } else if (uri.pathSegments[3].length == 32 &&
                  uri.pathSegments[4] == 'go') {
                tokenUser = uri.pathSegments[3];
                isExcelso = true;
                toBill = 'go';
              }
              return MaterialPageRoute(
                  builder: (_) => Splash(
                      param: paramStrg,
                      brand: brandStrg,
                      tn: tnStrg,
                      role: roleStrg,
                      cashierName: cashierNameStrg,
                      toBill: toBill,
                      sessionId: sessionId,
                      token: tokenUser));
            }
            return null;
          }),
    );
  }
}
