import 'package:dio/dio.dart';
import 'package:telnow_mobile_new/main.dart';
import 'package:telnow_mobile_new/src/injector/injector.dart';
import 'package:telnow_mobile_new/src/model/refreshtoken/refresh_token_body.dart';
import 'package:telnow_mobile_new/src/model/token/token.dart';
import 'package:telnow_mobile_new/src/layouts/components/template.dart';
import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
import 'package:telnow_mobile_new/src/utils/u.dart';

class DioLoggingInterceptors extends InterceptorsWrapper {
  final Dio _dio;
  final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();

  DioLoggingInterceptors(this._dio);

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
    if (options.headers.containsKey('requirestoken')) {
      await U.waitForRefreshAuth();
      options.headers.remove('requirestoken');
      String? accessToken = _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken);
      options.headers.addAll({'Authorization': 'Bearer $accessToken'});
    }

    super.onRequest(options, handler);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    super.onResponse(response,handler);
  }

  @override
  void onError(DioError dioError, ErrorInterceptorHandler handler) async {
    // print(dioError.response?.data.toString());
    // print(dioError.response?.realUri.toString());
    try {
      if (dioError.response?.statusCode == 401) {
        print("auth error");
        bool? checkRefreshCount = _sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyCountRefreshToken);
        int? refreshCount = _sharedPreferencesManager.getInt(SharedPreferencesManager.keyCountRefreshToken);
        if(checkRefreshCount! && refreshCount! > 4){
          handlingError(NavigationService.navigatorKey.currentContext, 3);
          return;
        }

        // if (dioError.response!.data.toString().contains("Invalid refresh token")) {
        //   handlingError(NavigationService.navigatorKey.currentContext, 3);
        // }
        if (dioError.response!.data.toString().contains("Access token expired")) {
          print("token expired");

          String? refreshToken = _sharedPreferencesManager.getString(SharedPreferencesManager.keyRefreshToken)!;
          RefreshTokenBody? refreshTokenBody = RefreshTokenBody('refresh_token', refreshToken);
          Token? token = await U.refreshAuth(refreshTokenBody);
          if (token != null) {
            RequestOptions? options = dioError.response?.requestOptions;
            options?.headers.addAll({'requirestoken': true});
            try {
              var r = await _dio.fetch(options!);
              handler.resolve(r);
              await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0);
              return;
            } catch (error2) {
              print(error2);
            }
          }
        }
        await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, refreshCount!+1);
      }
    } catch (error) {
      print("Error dio: ${error.toString()}");
      handlingError(NavigationService.navigatorKey.currentContext, 3);
    }
    super.onError(dioError, handler);
  }

//  @override
//  void onError(DioError dioError,ErrorInterceptorHandler handler) async {
//    print("<-- ${dioError.message} ${(dioError.response?.requestOptions != null ? (dioError.response.requestOptions.baseUrl + dioError.response.requestOptions.path) : 'URL')}");
//    print("${dioError.response != null ? dioError.response.data : 'Unknown Error'}");
//    print("<-- End error");
//
//    int responseCode = dioError.response?.statusCode;
//
//    try {
//      if(responseCode == 401 && (dioError.response != null && json.decode(dioError.response.data)['error'] == 'invalid_token_not_found')){
//        await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 4);
//      }
//    } catch (e) {
//      await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 4);
//    }
//
//    bool checkRefreshCount = _sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyCountRefreshToken);
//    int refreshCount = _sharedPreferencesManager.getInt(SharedPreferencesManager.keyCountRefreshToken);
//    if(checkRefreshCount && refreshCount > 4){
//      await _sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, '');
//      await _sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, '');
//      await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0);
//    }
//
//    String oldAccessToken = _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken);
//    if (oldAccessToken != '' && responseCode == 401 && _sharedPreferencesManager != null) {
//      _dio.interceptors.requestLock.lock();
//      _dio.interceptors.responseLock.lock();
//
//      String refreshToken = _sharedPreferencesManager.getString(SharedPreferencesManager.keyRefreshToken);
//      RefreshTokenBody refreshTokenBody = RefreshTokenBody('refresh_token', refreshToken);
//      ApiAuthRepository apiAuthRepository = ApiAuthRepository();
//
//      await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, refreshCount+1);
//print('try to refresh token: '+refreshCount.toString());
//      Token token = await apiAuthRepository.postRefreshAuth(refreshTokenBody);
//      if(token!=null){
//        await _sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken);
//        await _sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken);
//        await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0);
//
//        RequestOptions options = dioError.response?.requestOptions;
//        options.headers.addAll({'requirestoken': true});
//        _dio.interceptors.requestLock.unlock();
//        _dio.interceptors.responseLock.unlock();
//
//        _dio.fetch(options).then((r) => handler.resolve(r),
//          onError: (e) {
//            handler.reject(e);
//          },
//        );
//      }
//    } else {
//      super.onError(dioError,handler);
//    }
//  }
}