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<Object?> 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<Activity> activities;
  final List<Activity> 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<Object?> get props => [
    activities,
    filteredActivities,
    activeFilter,
    minRating,
    showVotedOnly,
  ];

  /// Creates a copy of the current state with optional modifications
  ActivityLoaded copyWith({
    List<Activity>? activities,
    List<Activity>? 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<Activity> getActivitiesByCategory(String category) {
    return activities
        .where((activity) => activity.category == category)
        .toList();
  }

  /// Gets top rated activities
  List<Activity> getTopRatedActivities({int limit = 10}) {
    final sorted = List<Activity>.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<Activity> 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<Object?> get props => [
    searchResults,
    query,
    isLoading,
    newlyAddedActivity,
  ];

  /// Creates a copy with optional modifications
  ActivitySearchResults copyWith({
    List<Activity>? 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<Object?> 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<Object?> get props => [message, errorCode, error];
}

/// State when voting is in progress
class ActivityVoting extends ActivityState {
  final String activityId;
  final List<Activity> activities;

  const ActivityVoting({required this.activityId, required this.activities});

  @override
  List<Object> get props => [activityId, activities];
}

/// State when activity is being updated
class ActivityUpdating extends ActivityState {
  final String activityId;
  final List<Activity> activities;

  const ActivityUpdating({required this.activityId, required this.activities});

  @override
  List<Object> get props => [activityId, activities];
}

/// State when activities are being added in batch
class ActivityBatchAdding extends ActivityState {
  final List<Activity> activitiesToAdd;
  final int progress;
  final int total;

  const ActivityBatchAdding({
    required this.activitiesToAdd,
    required this.progress,
    required this.total,
  });

  @override
  List<Object> 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<Object> 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<Object> 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<Object> get props => [activityId, vote, userId];
}
