import 'dart:convert';

import 'package:baseproject/core/common/index.dart';
import 'package:baseproject/core/constants/index.dart';
import 'package:baseproject/features/presentation/app/view/app.dart';
import 'package:baseproject/features/route/route_goto.dart';
import 'package:baseproject/features/usecases/index.dart';
import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';

class CustomInterceptor extends InterceptorsWrapper {
  int retryCount = 0;
  @override
  // ignore: avoid_void_async
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
    final String token = LocalStoreManager.getString(StorageKey.tokenUser);
    if (token.isNotEmpty) options.headers["Authorization"] = "Bearer $token";

    final String method = options.method.toLowerCase();
    if (method == 'get' || method == 'put') {
      // xử lý double request đá .0
      // options.queryParameters.forEach((String key, dynamic value) {
      //   if (value != null && value is double && Utils.getDecimal(value) == 0) {
      //     options.queryParameters[key] = value.toInt();
      //   }
      // });
    }

    return super.onRequest(options, handler);
  }

  @override
  // ignore: always_specify_types
  onResponse(Response response, ResponseInterceptorHandler handler) {
    if (response.data.runtimeType.toString().toLowerCase() == "string") {
      response.data = json.decode(response.data);
    }
    try {
      if (response.data["result"] != null) {
        response.data = response.data["result"];
      }
    } catch (_) {}

    if (retryCount > 0) {
      retryCount = 0;
    }
    return super.onResponse(response, handler);
  }

  @override
  onError(DioError err, ErrorInterceptorHandler handler) async {
    if (retryCount < 3) {
      await Future.delayed(Duration(milliseconds: retryCount * 500));
      if ((err.response?.statusCode == 403 || err.response?.statusCode == 401)) {
        retryCount++;
        final Dio dio = GetIt.I();
        final RequestOptions options = err.requestOptions;
        dio.lock();
        dio.interceptors.requestLock.lock();
        dio.interceptors.responseLock.lock();

        // Refresh token
        final UserUseCases sessionRepository = GetIt.I();
        final bool token = await sessionRepository.tryRefreshToken();
        if (!token) {
          dio.unlock();
          dio.interceptors.requestLock.unlock();
          dio.interceptors.responseLock.unlock();
          // ignore: use_build_context_synchronously
          gotoLogin(navigatorKey.currentState!.context);
        } else {
          dio.unlock();
          dio.interceptors.requestLock.unlock();
          dio.interceptors.responseLock.unlock();
          options.headers = <String, dynamic>{
            "Content-type": "application/json",
            "Authorization": "Bearer ${LocalStoreManager.getString(StorageKey.tokenUser)}"
          };

          try {
            final response = await dio.fetch<dynamic>(options);
            return handler.resolve(response);
          } catch (e) {
            return handler.next(err);
          }
        }
      }
    }

    final dynamic errorData = err.response?.data;
    //&& err.response?.statusCode == 400
    // if (errorData != null && errorData["responseException"] != null) {
    //   final dynamic temp = errorData["responseException"]["exceptionMessage"];
    //   try {
    //     if (temp != null && temp["error"] != null) {
    //       err.response?.data = temp["error"];
    //     } else {
    //       err.response?.data = temp;
    //     }
    //   } catch (e) {
    //     err.response?.data = temp;
    //   }
    // }

    return super.onError(err, handler);
  }
}
