import 'dart:async';
import '../../core.dart';

typedef RefreshTokenCallback = Future<String?> Function();
class AppInterceptor extends Interceptor {
  final RefreshTokenCallback refreshTokenCallback;
  Completer<String?>? _refreshCompleter;

  AppInterceptor({required this.refreshTokenCallback});


  @override
  Future<void> onError(DioException err, ErrorInterceptorHandler handler) async {
    if (err.response?.statusCode == 401 && !ApiHandler.isRefreshing) {
      ApiHandler.cancelAllRequests("Token expired - refreshing");

      if (_refreshCompleter == null) {
        _refreshCompleter = Completer<String?>();
        ApiHandler.isRefreshing = true;

        try {
          final newToken = await refreshTokenCallback();
          if (newToken == null) throw Exception("Refresh failed");

          ApiHandler.reset();
          _refreshCompleter?.complete(newToken);
        } catch (e) {
          _refreshCompleter?.completeError(e);
          if (!ApiHandler.isRedirecting) {
            ApiHandler.isRedirecting = true;
            ApiHandler.cancelAllRequests("Cancel All Requests - Unauthorized");
            if (Get.currentRoute != '/Auth') {
              Get.offAllNamed('/Auth');
            }
          }
        } finally {
          ApiHandler.isRefreshing = false;
          _refreshCompleter = null;
        }
      }

      try {
        final newToken = await _refreshCompleter!.future;
        if (newToken != null) {
          final opts = err.requestOptions;
          opts.headers['Authorization'] = 'Bearer $newToken';

          final dio = Dio();
          final cloneReq = await dio.fetch(opts);
          handler.resolve(cloneReq);
          return;
        }
      } catch (_) {
        handler.reject(err);
      }
    } else if (err.type == DioExceptionType.cancel) {
      handler.next(err);
    } else {
      handler.next(err);
    }
  }
}