/// 데이터 레이어 예외 클래스들
///
/// API, 데이터베이스, 파싱 관련 예외를 정의합니다.

import 'app_exceptions.dart';

/// API 예외 기본 클래스
abstract class ApiException extends DataException {
  final int? statusCode;

  const ApiException({
    required String message,
    this.statusCode,
    String? code,
    dynamic originalError,
  }) : super(message: message, code: code, originalError: originalError);

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

/// 네이버 API 예외
class NaverApiException extends ApiException {
  const NaverApiException({
    required String message,
    int? statusCode,
    String? code,
    dynamic originalError,
  }) : super(
         message: message,
         statusCode: statusCode,
         code: code,
         originalError: originalError,
       );
}

/// HTML 파싱 예외
class HtmlParsingException extends DataException {
  final String? url;

  const HtmlParsingException({
    required String message,
    this.url,
    dynamic originalError,
  }) : super(
         message: message,
         code: 'HTML_PARSE_ERROR',
         originalError: originalError,
       );

  @override
  String toString() {
    final base = super.toString();
    return url != null ? '$base (URL: $url)' : base;
  }
}

/// 데이터 변환 예외
class DataConversionException extends DataException {
  final String fromType;
  final String toType;

  const DataConversionException({
    required String message,
    required this.fromType,
    required this.toType,
    dynamic originalError,
  }) : super(
         message: message,
         code: 'DATA_CONVERSION_ERROR',
         originalError: originalError,
       );

  @override
  String toString() => '$runtimeType: $message ($fromType → $toType)';
}

/// 캐시 예외
class CacheException extends StorageException {
  const CacheException({
    required String message,
    String? code,
    dynamic originalError,
  }) : super(
         message: message,
         code: code ?? 'CACHE_ERROR',
         originalError: originalError,
       );
}

/// Hive 예외
class HiveException extends StorageException {
  const HiveException({
    required String message,
    String? code,
    dynamic originalError,
  }) : super(
         message: message,
         code: code ?? 'HIVE_ERROR',
         originalError: originalError,
       );
}

/// URL 처리 예외
class UrlProcessingException extends DataException {
  final String url;

  const UrlProcessingException({
    required String message,
    required this.url,
    String? code,
    dynamic originalError,
  }) : super(
         message: message,
         code: code ?? 'URL_PROCESSING_ERROR',
         originalError: originalError,
       );

  @override
  String toString() => '$runtimeType: $message (URL: $url)';
}

/// 잘못된 URL 형식 예외
class InvalidUrlException extends UrlProcessingException {
  const InvalidUrlException({required String url, String? message})
    : super(
        message: message ?? '올바르지 않은 URL 형식입니다',
        url: url,
        code: 'INVALID_URL',
      );
}

/// 지원하지 않는 URL 예외
class UnsupportedUrlException extends UrlProcessingException {
  const UnsupportedUrlException({required String url, String? message})
    : super(
        message: message ?? '지원하지 않는 URL입니다',
        url: url,
        code: 'UNSUPPORTED_URL',
      );
}
