import 'package:chipin_blogpost/features/authentication/services/auth_service.dart';
import 'package:chipin_blogpost/features/events/models/attendee_model.dart';
import 'package:chipin_blogpost/features/events/models/event_model.dart';
import 'package:chipin_blogpost/features/events/services/event_service.dart';
import 'package:chipin_blogpost/features/events/widgets/event_card.dart';
import 'package:flutter/material.dart';

class JoinEventsScreen extends StatefulWidget {
  final EventService eventService;

  const JoinEventsScreen({required this.eventService});

  @override
  _JoinEventsScreenState createState() => _JoinEventsScreenState();
}

class _JoinEventsScreenState extends State<JoinEventsScreen> {
  Future<void> joinEvent(MyEventModel event) async {
    AttendeesModel myAttendeeModel = AttendeesModel(
      eventId: event.eventId,
      userId: currentUserId,
    );
    bool result = await EventService.joinEvent(myAttendeeModel);
    if (result) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Successfully joined event!'),
          duration: Duration(seconds: 2),
        ),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Failed to join event. Please try again.'),
          duration: Duration(seconds: 2),
        ),
      );
    }
  }

  List<MyEventModel> allEvents = [];
  String currentUserId = '';

  @override
  void initState() {
    super.initState();
    fetchAllEvents();
    getCurrentUserId();
  }

  Future<void> getCurrentUserId() async {
    currentUserId = await AuthService.getCreatorId();
  }

  Future<void> fetchAllEvents() async {
    try {
      List<MyEventModel> events = await EventService.getAllEvents();
      setState(() {
        allEvents = events;
      });
    } catch (error) {
      // Handle error
    }
  }

  @override
  Widget build(BuildContext context) {
    if (allEvents.isEmpty) {
      return const Center(
        child: Text('No events to join'),
      );
    } else {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Join Events'),
        ),
        body: ListView.builder(
          itemCount: allEvents.length,
          itemBuilder: (context, index) {
            MyEventModel event = allEvents[index];
            bool showJoinButton = event.creatorId != currentUserId;
            return EventCard(
              event: event,
              showJoinButton: showJoinButton,
              onJoinPressed: () => joinEvent(event),
            );
          },
        ),
      );
    }
  }
}

This code represents a screen in a mobile app where users can join events. Let's break it down step by step:

  1. We import necessary packages and classes that we will use in this code.
  2. We define a class called JoinEventsScreen which extends StatefulWidget. This means it represents a screen that can change its state (content) over time.
  3. The JoinEventsScreen class has a required parameter eventService of type EventService, which is passed when creating an instance of this class.
  4. Inside the JoinEventsScreen class, we define a private class called _JoinEventsScreenState, which extends State. This is the state class for the JoinEventsScreen.
  5. Inside the _JoinEventsScreenState class, we define a method called joinEvent. This method is called when a user wants to join an event. It takes an argument event of type MyEventModel, representing the event the user wants to join.
  6. In the joinEvent method, we create an instance of AttendeesModel using the event.eventId and currentUserId (a variable defined in the state class).
  7. We then call a method joinEvent from the EventService class, passing the myAttendeeModel instance we created. This method returns a boolean value indicating whether the joining was successful or not.
  8. Depending on the result of the join operation, we show a message to the user using a SnackBar. If the join was successful, we show a success message; otherwise, we show a failure message.
  9. We define two variables: allEvents, which is a list of MyEventModel objects, and currentUserId, which is a string representing the current user's ID.
  10. In the initState method, which is a lifecycle method called when the state is initialized, we call two methods: fetchAllEvents and getCurrentUserId. These methods are responsible for fetching all the events and getting the current user's ID, respectively.
  11. The getCurrentUserId method uses the AuthService class to get the current user's ID asynchronously.
  12. The fetchAllEvents method uses the EventService class to fetch all the events asynchronously. If the fetching is successful, we update the allEvents variable with the fetched events. If there is an error, we handle it by commenting out the error handling code for now.
  13. The build method is where we build the UI for the screen. If there are no events to join (i.e., allEvents is empty), we display a simple message saying "No events to join" in the center of the screen.
  14. If there are events to join, we return a Scaffold widget with an AppBar displaying the title "Join Events". The body of the Scaffold is a ListView.builder that dynamically builds a list of EventCard widgets based on the allEvents list. Each EventCard represents an event and has a join button that calls the joinEvent method when pressed.

That's a complete breakdown of the code. It defines a screen where users can view and join events, handles event joining logic, and displays appropriate messages to the user.