import 'package:auto_route/auto_route.dart';
import 'package:flutter/foundation.dart';
import 'package:telnow_mobile_new/app_router.gr.dart';
import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
import 'package:telnow_mobile_new/src/injector/injector.dart';
import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
import 'package:telnow_mobile_new/src/utils/U.dart';

@AutoRouterConfig(replaceInRouteName: 'Screen|Page,Route')
class AppRouter extends RootStackRouter {
  AppRouter({super.navigatorKey});
  final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();

  @override
  RouteType get defaultRouteType => RouteType.material(); //.cupertino, .adaptive ..etc

  @override
  List<AutoRoute> get routes => [
    AutoRoute(path: '/qr', page: NewQrRoute.page, guards: qrGuards, initial: true),
    AutoRoute(path: '/change-code/:pid', page: ChangeCodeRoute.page),
    AutoRoute(path: '/end-session', page: EndSessionRoute.page),
    AutoRoute(
        path: '/app/:pid', page: HomeGuardRoute.page, guards: appGuards,
        children: [
          AutoRoute(path: 'login', page: LoginRoute.page, guards: loginGuards, initial: true),
          //TODO: tambah pengecekan sv disini
          AutoRoute(path: 'landing-page', page: LandingRoute.page,),
          AutoRoute(path: 'loginme', page: AutoLoginRoute.page, guards: loginGuards),
          AutoRoute(path: 'license', page: ErrorRoute.page),
          AutoRoute(
              path: 'menu', page: AppResponsive.page, guards: menuGuards,
              children: [
                AutoRoute(path: 'home', page: HomeResponsive.page, initial: true),
                AutoRoute(path: 'history', page: HistoryResponsive.page),
                AutoRoute(path: 'account', page: AccountResponsive.page),
              ]
          ),
        ]
    ),
  ];

  List<AutoRouteGuard> get qrGuards => [
    AutoRouteGuard.simple((resolver, router) async{
      Parameters param = resolver.route.queryParams;
      router.removeLast();
      if (!kIsWeb && U.getAccessCode() != null && param.isEmpty) {
        router.pushPath('/app/${Uri.encodeComponent(U.getAccessCode()!)}');
      } else{
        // FlutterNativeSplash.remove();
        resolver.next();
      }
    })
  ];

  List<AutoRouteGuard> get appGuards => [
    AutoRouteGuard.simple((resolver, router) async{
      RouteMatch<dynamic> vRedirector = resolver.route;
      String? rawPid = '';
      String? pid = '';
      bool stb = false;

      if(vRedirector.params.isNotEmpty){
        rawPid = vRedirector.params.getString('pid');
      }

      try {
        pid = Uri.decodeComponent(rawPid);
      } catch (e) {
        debugPrint("err : $e");
        stb = true;
      }

      if (pid == null || stb) {
        router.pushPath("/qr?new=true");
      }

      if(vRedirector.fragment != '' && U.getAccessCode() != null){
        await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyBaseUrl);
        await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessCode);
        await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keySerialCode);
        await _sharedPreferencesManager.clearKey(SharedPreferencesManager.version);
      }

      if (U.getAccessCode() == null) {
        await _sharedPreferencesManager.putString(SharedPreferencesManager.keyBaseUrl, U.rewriteUrl(vRedirector.fragment));
        await _sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessCode, pid!);
        await _sharedPreferencesManager.putString(SharedPreferencesManager.keySerialCode, 'P-$pid}');
        try {
          var ver = await U.reloadLicense();
          await _sharedPreferencesManager.putInt(SharedPreferencesManager.version, ver['version']);

          rawPid = Uri.encodeComponent(pid);
        } catch (error) {
          await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyBaseUrl);
          await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessCode);
          await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keySerialCode);
          await _sharedPreferencesManager.clearKey(SharedPreferencesManager.version);
          router.pushPath("/qr?new=true");
        }
      } else if(_isNewAccessCode(rawPid, U.getAccessCode()!)){
        router.pushPath("/change-code/$rawPid");
        return;
      } else {
        if (_sharedPreferencesManager.getInt(SharedPreferencesManager.version) == null){
          try {
            var ver = await U.reloadLicense();
            await _sharedPreferencesManager.putInt(SharedPreferencesManager.version, ver['version']);
          } catch (e) {
            debugPrint('Error get2: ${e.toString()}');
            await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyBaseUrl);
            await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessCode);
            await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keySerialCode);
            await _sharedPreferencesManager.clearKey(SharedPreferencesManager.version);
            router.pushPath("/qr?new=true");
          }
        }
      }

      // FlutterNativeSplash.remove();
      resolver.next();
    })
  ];

  List<AutoRouteGuard> get loginGuards => [
    AutoRouteGuard.simple((resolver, router) async{
      if(resolver.route.fragment.contains("/")){
        if(resolver.route.fragment.split("/")[1] == 'landing'){
          await resolver.redirectUntil(LandingRoute());
        }
      }

      router.removeLast();
      if (!_isValidVersion()) {
        router.pushPath('/app/${Uri.encodeComponent(U.getAccessCode()!)}/license');
      } else if (_isLoggedIn()) {
        !kIsWeb? router.pushAndPopUntil(AppResponsive(), predicate: (_) => false) : router.pushPath('/app/${Uri.encodeComponent(U.getAccessCode()!)}/menu');
      } else if(router.currentUrl.contains('/loginme') && resolver.routeName != AutoLoginRoute.name){
        await resolver.redirectUntil(AutoLoginRoute());
      } else{
        resolver.next();
      }
    })
  ];

  List<AutoRouteGuard> get menuGuards => [
    AutoRouteGuard.simple((resolver, router) async{
      router.removeLast();
      if (!_isValidVersion()) {
        router.pushPath('/app/${Uri.encodeComponent(U.getAccessCode()!)}/license');
      } else if (!_isLoggedIn()) {
        router.pushPath('/app/${Uri.encodeComponent(U.getAccessCode()!)}/login');
      } else{
        resolver.next();
      }
    })
  ];


  bool _isLoggedIn() {
    bool? isTokenExist = _sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyAccessToken);
    String? token = _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken);
    bool? isLoggedIn = _sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyIsLogin);

    return isLoggedIn! && isTokenExist! && token != null;
  }

  bool _isValidVersion() {
    return ApiAuthProvider().currentVersion == U.getVersion();
  }

  bool _isNewAccessCode(String pid, String savedPid) {
    try{
      return U.decodeBase64Url(pid) == U.decodeBase64Url(Uri.decodeComponent(savedPid)) ? false : true;
    } catch (e){
      return false;
    }
  }
}