import 'package:comwell_key_app/base/base_cubit.dart';
import 'package:comwell_key_app/overview/cubit/overview_state.dart';
import 'package:comwell_key_app/overview/models/booking.dart';
import 'package:comwell_key_app/overview/models/bookings.dart';
import 'package:comwell_key_app/overview/repository/overview_repository.dart';
import 'package:comwell_key_app/share/share_booking_repository.dart';

class OverviewCubit extends BaseCubit<OverviewState> {
  final OverviewRepository _overviewRepository;
  final ShareBookingRepository _shareBookingRepository;

  bool _bookingsLoaded = false;

  OverviewCubit(
    this._overviewRepository,
    this._shareBookingRepository,
  ) : super(const OverviewState()) {
    fetchBookings();
  }

  Future<void> fetchBookings() async {
    try {
      safeEmit(state.copyWith(isLoading: true));
      final bookings = await _overviewRepository.fetchAllBookingsForUser();
      _bookingsLoaded = true;
      safeEmit(state.copyWith(bookings: bookings));
    } catch (e, st) {
      logError(e, st);
      safeEmit(state.copyWith(errorType: OverviewStateError.error));
    } finally {
      safeEmit(state.copyWith(isLoading: false));
    }
  }

  Future<void> addBooking(Booking newBooking) async {
    final updatedBookingsObject = Bookings(
      current: [...state.bookings.current, newBooking],
      past: state.bookings.past,
      cancelled: state.bookings.cancelled,
    );
    safeEmit(state.copyWith(bookings: updatedBookingsObject));
  }

  Booking? getCheckedInBooking() {
    try {
      return state.bookings.current.firstWhere(
        (booking) => booking.reservationStatus == ReservationStatus.checkedin,
      );
    } catch (_) {
      return null;
    }
  }

  Future<Booking?> findBooking(String bookingReference, String lastName) async {
    try {
      final booking = await _overviewRepository.findBooking(bookingReference, lastName);
      if (booking != null) {
        addBooking(booking); // Add the found booking to the current list
        return booking;
      } else if (_bookingsLoaded) {
        safeEmit(state.copyWith(errorType: OverviewStateError.noBookingsFound));
      } else {
        safeEmit(
          state.copyWith(
            bookings: Bookings.emptyValue,
            errorType: OverviewStateError.noBookingsFound,
          ),
        );
      }
    } catch (e, st) {
      logError(e, st);
      safeEmit(state.copyWith(errorType: OverviewStateError.error));
    } finally {
      safeEmit(state.copyWith(isLoading: false));
    }
    return null;
  }

  Future<void> findBookingById(String bookingId) async {
    try {
      safeEmit(state.copyWith(isLoading: true));
      final bookings = await _overviewRepository.fetchAllBookingsForUser();
      safeEmit(state.copyWith(bookings: bookings));
    } catch (e, st) {
      logError(e, st);
      safeEmit(state.copyWith(errorType: OverviewStateError.error));
    } finally {
      safeEmit(state.copyWith(isLoading: false));
    }
  }

  Future<void> removeGuestsFromBooking(
    String hmsConfirmationNumber,
    String hotelCode,
    int guestId,
  ) async {
    try {
      safeEmit(state.copyWith(isLoading: true));
      await _shareBookingRepository.removeGuestsFromBooking(
        hmsConfirmationNumber,
        hotelCode,
        guestId,
      );
      final bookings = await _overviewRepository.fetchAllBookingsForUser();
      safeEmit(state.copyWith(bookings: bookings));
    } catch (e, st) {
      logError(e, st);
      safeEmit(state.copyWith(errorType: OverviewStateError.error));
    } finally {
      safeEmit(state.copyWith(isLoading: false));
    }
  }
}