import 'package:dartz/dartz.dart';

/// 실패 처리를 위한 추상 클래스
abstract class Failure {
  final String message;
  final String? code;
  
  const Failure({
    required this.message,
    this.code,
  });
  
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Failure &&
          runtimeType == other.runtimeType &&
          message == other.message &&
          code == other.code;
  
  @override
  int get hashCode => message.hashCode ^ code.hashCode;
}

/// 서버 실패
class ServerFailure extends Failure {
  final int? statusCode;
  final Map<String, dynamic>? errors;
  final dynamic originalError;
  
  const ServerFailure({
    required super.message,
    super.code,
    this.statusCode,
    this.errors,
    this.originalError,
  });
}

/// 캐시 실패
class CacheFailure extends Failure {
  const CacheFailure({
    required super.message,
    super.code,
  });
}

/// 네트워크 실패
class NetworkFailure extends Failure {
  final dynamic originalError;
  
  const NetworkFailure({
    required super.message,
    super.code,
    this.originalError,
  });
}

/// 인증 실패
class AuthenticationFailure extends Failure {
  final dynamic originalError;
  
  const AuthenticationFailure({
    required super.message,
    super.code,
    this.originalError,
  });
}

/// 권한 실패
class AuthorizationFailure extends Failure {
  final dynamic originalError;
  
  const AuthorizationFailure({
    required super.message,
    super.code,
    this.originalError,
  });
}

/// 유효성 검사 실패
class ValidationFailure extends Failure {
  final Map<String, List<String>>? fieldErrors;
  final Map<String, dynamic>? errors; // 기존 코드와 호환성을 위해 추가
  final dynamic originalError; // 원본 에러 정보
  
  const ValidationFailure({
    required super.message,
    super.code,
    this.fieldErrors,
    this.errors,
    this.originalError,
  });
}

/// 리소스 찾을 수 없음 실패
class NotFoundFailure extends Failure {
  final String? resourceType;
  final String? resourceId;
  
  const NotFoundFailure({
    required super.message,
    super.code,
    this.resourceType,
    this.resourceId,
  });
}

/// 중복 리소스 실패
class DuplicateFailure extends Failure {
  final String? field;
  final String? value;
  
  const DuplicateFailure({
    required super.message,
    super.code,
    this.field,
    this.value,
  });
}

/// 비즈니스 로직 실패
class BusinessFailure extends Failure {
  const BusinessFailure({
    required super.message,
    super.code,
  });
}

/// 알 수 없는 실패
class UnknownFailure extends Failure {
  final dynamic originalError;
  
  const UnknownFailure({
    required super.message,
    super.code,
    this.originalError,
  });
}

/// AuthFailure는 AuthenticationFailure의 별칭
typedef AuthFailure = AuthenticationFailure;

/// PermissionFailure는 AuthorizationFailure의 별칭  
typedef PermissionFailure = AuthorizationFailure;

/// 타입 정의
typedef FutureEither<T> = Future<Either<Failure, T>>;
typedef FutureVoid = FutureEither<void>;