enum EventCategory { tournament, pickup }

class Event {
  const Event({
    required this.id,
    required this.title,
    required this.description,
    required this.date,
    required this.location,
    required this.registrationDeadline,
    required this.teamsRegistered,
    required this.maxTeams,
    this.category = EventCategory.pickup,
    this.imageUrl,
    this.isCancelled = false,
  });

  final String id;
  final String title;
  final String description;
  final DateTime date;
  final String location;
  final DateTime registrationDeadline;
  final int teamsRegistered;
  final int maxTeams;
  final EventCategory category;
  final String? imageUrl;
  final bool isCancelled;

  Event copyWith({
    String? id,
    String? title,
    String? description,
    DateTime? date,
    String? location,
    DateTime? registrationDeadline,
    int? teamsRegistered,
    int? maxTeams,
    EventCategory? category,
    String? imageUrl,
    bool? isCancelled,
  }) {
    return Event(
      id: id ?? this.id,
      title: title ?? this.title,
      description: description ?? this.description,
      date: date ?? this.date,
      location: location ?? this.location,
      registrationDeadline: registrationDeadline ?? this.registrationDeadline,
      teamsRegistered: teamsRegistered ?? this.teamsRegistered,
      maxTeams: maxTeams ?? this.maxTeams,
      category: category ?? this.category,
      imageUrl: imageUrl ?? this.imageUrl,
      isCancelled: isCancelled ?? this.isCancelled,
    );
  }

  factory Event.fromJson(Map<String, dynamic> data) {
    return Event(
      id: (data['id'] as String?) ?? '',
      title: (data['title'] as String?) ?? '',
      description: (data['description'] as String?) ?? '',
      date: _parseDate(data['event_date']) ?? DateTime.now(),
      location: (data['location'] as String?) ?? '',
      registrationDeadline:
          _parseDate(data['registration_deadline']) ?? DateTime.now(),
      teamsRegistered: (data['teams_registered'] as num?)?.toInt() ?? 0,
      maxTeams: (data['max_teams'] as num?)?.toInt() ?? 0,
      category: (data['category'] as String?) == 'tournament'
          ? EventCategory.tournament
          : EventCategory.pickup,
      imageUrl: data['image_url'] as String?,
      isCancelled: _parseBool(data['is_cancelled']),
    );
  }

  Map<String, Object?> toJson() {
    return <String, Object?>{
      'title': title,
      'description': description,
      'event_date': date.toIso8601String(),
      'location': location,
      'registration_deadline': registrationDeadline.toIso8601String(),
      'max_teams': maxTeams,
      'category': category.name,
      'image_url': imageUrl,
      'is_cancelled': isCancelled ? 1 : 0,
    };
  }

  static DateTime? _parseDate(Object? v) {
    if (v is String && v.isNotEmpty) return DateTime.tryParse(v);
    return null;
  }

  static bool _parseBool(Object? v) {
    if (v is bool) return v;
    if (v is int) return v != 0;
    if (v is String) return v == '1' || v.toLowerCase() == 'true';
    return false;
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Event &&
        other.id == id &&
        other.title == title &&
        other.description == description &&
        other.date == date &&
        other.location == location &&
        other.registrationDeadline == registrationDeadline &&
        other.teamsRegistered == teamsRegistered &&
        other.maxTeams == maxTeams &&
        other.category == category &&
        other.imageUrl == imageUrl &&
        other.isCancelled == isCancelled;
  }

  @override
  int get hashCode => Object.hash(
        id, title, description, date, location,
        registrationDeadline, teamsRegistered, maxTeams,
        category, imageUrl, isCancelled,
      );

  @override
  String toString() => 'Event(id: $id, title: $title, date: $date)';
}
