import 'package:equatable/equatable.dart';

/// Base failure class for Clean Architecture
abstract class Failure extends Equatable {
  final String message;
  final String? code;

  const Failure(this.message, [this.code]);

  @override
  List<Object?> get props => [message, code];
}

/// Network failure
class NetworkFailure extends Failure {
  const NetworkFailure(String message, [String? code]) : super(message, code);
}

/// Server failure
class ServerFailure extends Failure {
  const ServerFailure(String message, [String? code]) : super(message, code);
}

/// Authentication failure
class AuthFailure extends Failure {
  const AuthFailure(String message, [String? code]) : super(message, code);
}

/// Validation failure
class ValidationFailure extends Failure {
  final Map<String, dynamic>? fieldErrors;

  const ValidationFailure(
    String message, [
    this.fieldErrors,
    String? code,
  ]) : super(message, code);

  @override
  List<Object?> get props => [message, code, fieldErrors];
}

/// Cache failure
class CacheFailure extends Failure {
  const CacheFailure(String message, [String? code]) : super(message, code);
}

/// Format failure
class FormatFailure extends Failure {
  const FormatFailure(String message, [String? code]) : super(message, code);
}

/// Unauthorized failure
class UnauthorizedFailure extends AuthFailure {
  const UnauthorizedFailure(String message, [String? code])
      : super(message, code);
}

/// Forbidden failure
class ForbiddenFailure extends Failure {
  const ForbiddenFailure(String message, [String? code]) : super(message, code);
}

/// Not found failure
class NotFoundFailure extends Failure {
  const NotFoundFailure(String message, [String? code]) : super(message, code);
}

/// Timeout failure
class TimeoutFailure extends NetworkFailure {
  const TimeoutFailure(String message, [String? code]) : super(message, code);
}

/// Connection failure
class ConnectionFailure extends NetworkFailure {
  const ConnectionFailure(String message, [String? code])
      : super(message, code);
}

/// Two-factor authentication required failure
class TwoFactorRequiredFailure extends AuthFailure {
  final String userId;
  final String twoFactorType;

  const TwoFactorRequiredFailure({
    required this.userId,
    required this.twoFactorType,
    String message = '2FA required',
    String? code,
  }) : super(message, code);

  @override
  List<Object?> get props => [message, code, userId, twoFactorType];
}

/// Unknown failure for unexpected errors
class UnknownFailure extends Failure {
  const UnknownFailure(String message, [String? code]) : super(message, code);
}
