import 'package:equatable/equatable.dart';

/// Classe de base pour tous les échecs
abstract class Failure extends Equatable {
  final String message;
  final String? code;
  final bool isRetryable;
  final String? userFriendlyMessage;

  const Failure(
    this.message, [
    this.code,
    this.isRetryable = false,
    this.userFriendlyMessage,
  ]);

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

  /// Get user-friendly message for display in UI
  String getUserMessage() => userFriendlyMessage ?? message;

  @override
  String toString() => 'Failure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec serveur
class ServerFailure extends Failure {
  const ServerFailure(
    super.message, [
    super.code,
    super.isRetryable = true, // Server errors are retryable
    super.userFriendlyMessage = 'Le serveur rencontre un problème. Veuillez réessayer.',
  ]);

  @override
  String toString() => 'ServerFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec de cache
class CacheFailure extends Failure {
  const CacheFailure(super.message, [super.code]);

  @override
  String toString() => 'CacheFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec de réseau
class NetworkFailure extends Failure {
  const NetworkFailure(
    super.message, [
    super.code,
    super.isRetryable = true, // Network errors are retryable
    super.userFriendlyMessage = 'Pas de connexion Internet. Vérifiez votre réseau.',
  ]);

  @override
  String toString() => 'NetworkFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec d'authentification
class AuthFailure extends Failure {
  const AuthFailure(super.message, [super.code]);

  @override
  String toString() => 'AuthFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec de validation
class ValidationFailure extends Failure {
  const ValidationFailure(
    super.message, [
    super.code,
    super.isRetryable = false, // Validation errors are not retryable
    super.userFriendlyMessage,
  ]);

  @override
  String toString() => 'ValidationFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec de permission
class PermissionFailure extends Failure {
  const PermissionFailure(super.message, [super.code]);

  @override
  String toString() => 'PermissionFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec de données non trouvées
class NotFoundFailure extends Failure {
  const NotFoundFailure(
    super.message, [
    super.code,
    super.isRetryable = false, // Not found errors are not retryable
    super.userFriendlyMessage,
  ]);

  @override
  String toString() => 'NotFoundFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec non autorisé (401)
class UnauthorizedFailure extends Failure {
  const UnauthorizedFailure(
    super.message, [
    super.code,
    super.isRetryable = false, // Auth errors are not retryable
    super.userFriendlyMessage = 'Votre session a expiré. Veuillez vous reconnecter.',
  ]);

  @override
  String toString() => 'UnauthorizedFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec interdit (403)
class ForbiddenFailure extends Failure {
  const ForbiddenFailure(
    super.message, [
    super.code,
    super.isRetryable = false, // Forbidden errors are not retryable
    super.userFriendlyMessage = 'Vous n\'avez pas les permissions nécessaires.',
  ]);

  @override
  String toString() => 'ForbiddenFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Échec inattendu
class UnexpectedFailure extends Failure {
  const UnexpectedFailure(super.message, [super.code]);

  @override
  String toString() => 'UnexpectedFailure: $message${code != null ? ' (Code: $code)' : ''}';
}

/// Fonctionnalité non implémentée
class NotImplementedFailure extends Failure {
  const NotImplementedFailure(
    super.message, [
    super.code,
    super.isRetryable = false, // Not implemented features are not retryable
    super.userFriendlyMessage =
        'Cette fonctionnalité sera bientôt disponible. Nous travaillons dessus !',
  ]);

  @override
  String toString() =>
      'NotImplementedFailure: $message${code != null ? ' (Code: $code)' : ''}';
}
