import 'package:dio/dio.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';

class CrashlyticsInterceptor extends Interceptor {
  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    FirebaseCrashlytics.instance.recordError(
      err,
      err.stackTrace,
      reason: _getErrorReason(err),
      information: _getErrorInformation(err),
      fatal: false,
    );

    super.onError(err, handler);
  }

  String _getErrorReason(DioException err) {
    final statusCode = err.response?.statusCode;

    if (statusCode != null) {
      return 'HTTP $statusCode Error: ${err.requestOptions.uri.path}';
    }

    switch (err.type) {
      case DioExceptionType.connectionTimeout:
        return 'Connection Timeout';
      case DioExceptionType.sendTimeout:
        return 'Send Timeout';
      case DioExceptionType.receiveTimeout:
        return 'Receive Timeout';
      case DioExceptionType.connectionError:
        return 'Connection Error';
      case DioExceptionType.cancel:
        return 'Request Cancelled';
      default:
        return 'Network Error: ${err.type.name}';
    }
  }

  List<String> _getErrorInformation(DioException err) {
    return [
      'URL: ${err.requestOptions.uri}',
      'Method: ${err.requestOptions.method}',
      'Status Code: ${err.response?.statusCode ?? 'N/A'}',
      'Error Type: ${err.type.name}',
      'Message: ${err.message ?? 'No message'}',
      // Tambahan
      'Request Data: ${_sanitizeData(err.requestOptions.data)}',
      'Response Body: ${err.response?.data ?? 'No response'}',
      'Headers: ${err.requestOptions.headers.entries.where((e) => e.key.toLowerCase() != 'authorization').toList()}',
    ];
  }

  /// Hindari log data sensitif
  dynamic _sanitizeData(dynamic data) {
    if (data == null) return 'No data';
    if (data is Map) {
      final sanitized = Map.from(data);
      const sensitiveKeys = [
        'password',
        'token',
        'secret',
        'pin',
        'card_number',
      ];
      for (final key in sensitiveKeys) {
        if (sanitized.containsKey(key)) {
          sanitized[key] = '***';
        }
      }
      return sanitized;
    }
    return data;
  }
}
