import 'package:equatable/equatable.dart'; import '../../models/activity.dart'; /// Base class for all activity-related states abstract class ActivityState extends Equatable { const ActivityState(); @override List get props => []; } /// Initial state when no activities have been loaded class ActivityInitial extends ActivityState { const ActivityInitial(); } /// State when activities are being loaded class ActivityLoading extends ActivityState { const ActivityLoading(); } /// State when activities are being searched class ActivitySearching extends ActivityState { const ActivitySearching(); } /// State when activities have been loaded successfully class ActivityLoaded extends ActivityState { final List activities; final List filteredActivities; final String? activeFilter; final double? minRating; final bool showVotedOnly; const ActivityLoaded({ required this.activities, required this.filteredActivities, this.activeFilter, this.minRating, this.showVotedOnly = false, }); @override List get props => [ activities, filteredActivities, activeFilter, minRating, showVotedOnly, ]; /// Creates a copy of the current state with optional modifications ActivityLoaded copyWith({ List? activities, List? filteredActivities, String? activeFilter, double? minRating, bool? showVotedOnly, }) { return ActivityLoaded( activities: activities ?? this.activities, filteredActivities: filteredActivities ?? this.filteredActivities, activeFilter: activeFilter ?? this.activeFilter, minRating: minRating ?? this.minRating, showVotedOnly: showVotedOnly ?? this.showVotedOnly, ); } /// Gets activities by category List getActivitiesByCategory(String category) { return activities .where((activity) => activity.category == category) .toList(); } /// Gets top rated activities List getTopRatedActivities({int limit = 10}) { final sorted = List.from(activities); sorted.sort((a, b) { final aScore = a.totalVotes; final bScore = b.totalVotes; if (aScore != bScore) { return bScore.compareTo(aScore); } return (b.rating ?? 0).compareTo(a.rating ?? 0); }); return sorted.take(limit).toList(); } } /// State when search results are available class ActivitySearchResults extends ActivityState { final List searchResults; final String query; final bool isLoading; final Activity? newlyAddedActivity; const ActivitySearchResults({ required this.searchResults, required this.query, this.isLoading = false, this.newlyAddedActivity, }); @override List get props => [ searchResults, query, isLoading, newlyAddedActivity, ]; /// Creates a copy with optional modifications ActivitySearchResults copyWith({ List? searchResults, String? query, bool? isLoading, Activity? newlyAddedActivity, }) { return ActivitySearchResults( searchResults: searchResults ?? this.searchResults, query: query ?? this.query, isLoading: isLoading ?? this.isLoading, newlyAddedActivity: newlyAddedActivity ?? this.newlyAddedActivity, ); } } /// State when an operation has completed successfully class ActivityOperationSuccess extends ActivityState { final String message; final String? operationType; const ActivityOperationSuccess(this.message, {this.operationType}); @override List get props => [message, operationType]; } /// State when an error has occurred class ActivityError extends ActivityState { final String message; final String? errorCode; final dynamic error; const ActivityError(this.message, {this.errorCode, this.error}); @override List get props => [message, errorCode, error]; } /// State when voting is in progress class ActivityVoting extends ActivityState { final String activityId; final List activities; const ActivityVoting({required this.activityId, required this.activities}); @override List get props => [activityId, activities]; } /// State when activity is being updated class ActivityUpdating extends ActivityState { final String activityId; final List activities; const ActivityUpdating({required this.activityId, required this.activities}); @override List get props => [activityId, activities]; } /// State when activities are being added in batch class ActivityBatchAdding extends ActivityState { final List activitiesToAdd; final int progress; final int total; const ActivityBatchAdding({ required this.activitiesToAdd, required this.progress, required this.total, }); @override List get props => [activitiesToAdd, progress, total]; /// Gets the progress as a percentage double get progressPercentage => total > 0 ? progress / total : 0.0; } /// State when an activity has been successfully added class ActivityAdded extends ActivityState { final Activity activity; final String message; const ActivityAdded({required this.activity, required this.message}); @override List get props => [activity, message]; } /// State when an activity has been successfully deleted class ActivityDeleted extends ActivityState { final String activityId; final String message; const ActivityDeleted({required this.activityId, required this.message}); @override List get props => [activityId, message]; } /// State when vote has been successfully recorded class ActivityVoteRecorded extends ActivityState { final String activityId; final int vote; final String userId; const ActivityVoteRecorded({ required this.activityId, required this.vote, required this.userId, }); @override List get props => [activityId, vote, userId]; }