/// 네트워크 관련 예외 클래스들
///
/// 모든 네트워크 오류를 명확하게 분류하고 처리합니다.

/// 네트워크 예외 기본 클래스
abstract class NetworkException implements Exception {
  final String message;
  final int? statusCode;
  final dynamic originalError;

  const NetworkException({
    required this.message,
    this.statusCode,
    this.originalError,
  });

  @override
  String toString() =>
      '$runtimeType: $message${statusCode != null ? ' (HTTP $statusCode)' : ''}';
}

/// 연결 타임아웃 예외
class ConnectionTimeoutException extends NetworkException {
  const ConnectionTimeoutException({
    String message = '서버 연결 시간이 초과되었습니다',
    dynamic originalError,
  }) : super(message: message, originalError: originalError);
}

/// 네트워크 연결 없음 예외
class NoInternetException extends NetworkException {
  const NoInternetException({
    String message = '인터넷 연결을 확인해주세요',
    dynamic originalError,
  }) : super(message: message, originalError: originalError);
}

/// 서버 오류 예외 (5xx)
class ServerException extends NetworkException {
  const ServerException({
    required String message,
    required int statusCode,
    dynamic originalError,
  }) : super(
         message: message,
         statusCode: statusCode,
         originalError: originalError,
       );
}

/// 클라이언트 오류 예외 (4xx)
class ClientException extends NetworkException {
  const ClientException({
    required String message,
    required int statusCode,
    dynamic originalError,
  }) : super(
         message: message,
         statusCode: statusCode,
         originalError: originalError,
       );
}

/// 파싱 오류 예외
class ParseException extends NetworkException {
  const ParseException({required String message, dynamic originalError})
    : super(message: message, originalError: originalError);
}

/// API 키 오류 예외
class ApiKeyException extends NetworkException {
  const ApiKeyException({String message = 'API 키가 설정되지 않았습니다'})
    : super(message: message);
}

/// 재시도 횟수 초과 예외
class MaxRetriesExceededException extends NetworkException {
  const MaxRetriesExceededException({
    String message = '최대 재시도 횟수를 초과했습니다',
    dynamic originalError,
  }) : super(message: message, originalError: originalError);
}

/// Rate Limit (429) 예외
class RateLimitException extends NetworkException {
  final String? retryAfter;

  const RateLimitException({
    String message = '너무 많은 요청으로 인해 차단되었습니다. 잠시 후 다시 시도해주세요.',
    this.retryAfter,
    dynamic originalError,
  }) : super(message: message, statusCode: 429, originalError: originalError);

  @override
  String toString() {
    final base = super.toString();
    if (retryAfter != null) {
      return '$base (재시도 가능: $retryAfter초 후)';
    }
    return base;
  }
}
