import 'package:equatable/equatable.dart';
import '../../models/activity.dart';

/// Base class for all activity-related events
abstract class ActivityEvent extends Equatable {
  const ActivityEvent();

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

/// Event to load activities for a specific trip
class LoadActivities extends ActivityEvent {
  final String tripId;

  const LoadActivities(this.tripId);

  @override
  List<Object> get props => [tripId];
}

/// Event to load trip activities without resetting search results
class LoadTripActivitiesPreservingSearch extends ActivityEvent {
  final String tripId;

  const LoadTripActivitiesPreservingSearch(this.tripId);

  @override
  List<Object> get props => [tripId];
}

/// Event to search activities using Google Places API
class SearchActivities extends ActivityEvent {
  final String tripId;
  final String destination;
  final ActivityCategory? category;
  final int? maxResults;
  final int? offset;
  final bool reset;
  final bool appendToExisting;

  const SearchActivities({
    required this.tripId,
    required this.destination,
    this.category,
    this.maxResults,
    this.offset,
    this.reset = false,
    this.appendToExisting = false,
  });

  @override
  List<Object?> get props => [
    tripId,
    destination,
    category,
    maxResults,
    offset,
    reset,
    appendToExisting,
  ];
}

/// Event to search activities using coordinates directly (bypasses geocoding)
class SearchActivitiesWithCoordinates extends ActivityEvent {
  final String tripId;
  final double latitude;
  final double longitude;
  final ActivityCategory? category;
  final int? maxResults;
  final int? offset;
  final bool reset;
  final bool appendToExisting;

  const SearchActivitiesWithCoordinates({
    required this.tripId,
    required this.latitude,
    required this.longitude,
    this.category,
    this.maxResults,
    this.offset,
    this.reset = false,
    this.appendToExisting = false,
  });

  @override
  List<Object?> get props => [
    tripId,
    latitude,
    longitude,
    category,
    maxResults,
    offset,
    reset,
    appendToExisting,
  ];
}

/// Event to search activities by text query
class SearchActivitiesByText extends ActivityEvent {
  final String tripId;
  final String destination;
  final String query;

  const SearchActivitiesByText({
    required this.tripId,
    required this.destination,
    required this.query,
  });

  @override
  List<Object> get props => [tripId, destination, query];
}

class UpdateActivityDate extends ActivityEvent {
  final String tripId;
  final String activityId;
  final DateTime? date;

  const UpdateActivityDate({
    required this.tripId,
    required this.activityId,
    this.date,
  });

  @override
  List<Object?> get props => [tripId, activityId, date];
}

/// Event to add a single activity to the trip
class AddActivity extends ActivityEvent {
  final Activity activity;

  const AddActivity(this.activity);

  @override
  List<Object> get props => [activity];
}

/// Event to add multiple activities at once
class AddActivitiesBatch extends ActivityEvent {
  final List<Activity> activities;

  const AddActivitiesBatch(this.activities);

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

/// Event to vote for an activity
class VoteForActivity extends ActivityEvent {
  final String activityId;
  final String userId;
  final int vote; // 1 for positive, -1 for negative, 0 to remove vote

  const VoteForActivity({
    required this.activityId,
    required this.userId,
    required this.vote,
  });

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

/// Event to delete an activity
class DeleteActivity extends ActivityEvent {
  final String activityId;

  const DeleteActivity(this.activityId);

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

/// Event to filter activities
class FilterActivities extends ActivityEvent {
  final String? category;
  final double? minRating;
  final bool? showVotedOnly;

  const FilterActivities({this.category, this.minRating, this.showVotedOnly});

  @override
  List<Object?> get props => [category, minRating, showVotedOnly];
}

/// Event to refresh activities
class RefreshActivities extends ActivityEvent {
  final String tripId;

  const RefreshActivities(this.tripId);

  @override
  List<Object> get props => [tripId];
}

/// Event to clear search results
class ClearSearchResults extends ActivityEvent {
  const ClearSearchResults();
}

/// Event to update activity details
class UpdateActivity extends ActivityEvent {
  final Activity activity;

  const UpdateActivity(this.activity);

  @override
  List<Object> get props => [activity];
}

/// Event to toggle favorite status
class ToggleActivityFavorite extends ActivityEvent {
  final String activityId;
  final String userId;

  const ToggleActivityFavorite({
    required this.activityId,
    required this.userId,
  });

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

/// Event to restore cached search results
class RestoreCachedSearchResults extends ActivityEvent {
  final List<Activity> searchResults;

  const RestoreCachedSearchResults({required this.searchResults});

  @override
  List<Object?> get props => [searchResults];
}

/// Event to remove an activity from search results
class RemoveFromSearchResults extends ActivityEvent {
  final String activityId;

  const RemoveFromSearchResults({required this.activityId});

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

/// Event to add an activity and remove it from search results in one action
class AddActivityAndRemoveFromSearch extends ActivityEvent {
  final Activity activity;
  final String googleActivityId;

  const AddActivityAndRemoveFromSearch({
    required this.activity,
    required this.googleActivityId,
  });

  @override
  List<Object> get props => [activity, googleActivityId];
}
