import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:travel_mate/models/trip.dart';
import 'trip_event.dart';
import 'trip_state.dart';
import '../../repositories/trip_repository.dart';


class TripBloc extends Bloc<TripEvent, TripState> {
  final TripRepository _repository;
  StreamSubscription? _tripsSubscription;
  String? _currentUserId;

  TripBloc(this._repository) : super(TripInitial()) {
    on<LoadTripsByUserId>(_onLoadTripsByUserId);
    on<TripCreateRequested>(_onTripCreateRequested);
    on<TripUpdateRequested>(_onTripUpdateRequested);
    on<TripDeleteRequested>(_onTripDeleteRequested);
    on<_TripsUpdated>(_onTripsUpdated);
    on<ResetTrips>(_onResetTrips);
  }

  Future<void> _onLoadTripsByUserId(
    LoadTripsByUserId event,
    Emitter<TripState> emit,
  ) async {
    emit(TripLoading());
    
    _currentUserId = event.userId;
    await _tripsSubscription?.cancel();

    _tripsSubscription = _repository.getTripsByUserId(event.userId).listen(
      (trips) {
        add(_TripsUpdated(trips));
      },
      onError: (error) {
        emit(TripError(error.toString()));
      },
    );
  }

  void _onTripsUpdated(
    _TripsUpdated event,
    Emitter<TripState> emit,
  ) {
    emit(TripLoaded(event.trips));
  }

  Future<void> _onTripCreateRequested(
    TripCreateRequested event,
    Emitter<TripState> emit,
  ) async {
    try {
      emit(TripLoading());
      
      final tripId = await _repository.createTrip(event.trip);
      
      emit(TripCreated(tripId: tripId));
      
      await Future.delayed(const Duration(milliseconds: 800));
      if (_currentUserId != null) {
        add(LoadTripsByUserId(userId: _currentUserId!));
      }
      
    } catch (e) {
      emit(TripError('Erreur lors de la création: $e'));
    }
  }

  Future<void> _onTripUpdateRequested(
    TripUpdateRequested event,
    Emitter<TripState> emit,
  ) async {
    try {
      await _repository.updateTrip(event.trip.id!, event.trip);
      emit(const TripOperationSuccess('Voyage mis à jour avec succès'));
      await Future.delayed(const Duration(milliseconds: 500));
      if (_currentUserId != null) {
        add(LoadTripsByUserId(userId: _currentUserId!));
      }
      
    } catch (e) {
      emit(TripError('Erreur lors de la mise à jour: $e'));
    }
  }

  Future<void> _onTripDeleteRequested(
    TripDeleteRequested event,
    Emitter<TripState> emit,
  ) async {
    try {
      await _repository.deleteTrip(event.tripId);
      
      emit(const TripOperationSuccess('Voyage supprimé avec succès'));
      
      await Future.delayed(const Duration(milliseconds: 500));
      if (_currentUserId != null) {
        add(LoadTripsByUserId(userId: _currentUserId!));
      }
      
    } catch (e) {
      emit(TripError('Erreur lors de la suppression: $e'));
    }
  }

  Future<void> _onResetTrips(
    ResetTrips event,
    Emitter<TripState> emit,
  ) async {
    await _tripsSubscription?.cancel();
    _currentUserId = null;
    emit(TripInitial());
  }

  @override
  Future<void> close() {
    _tripsSubscription?.cancel();
    return super.close();
  }
}

class _TripsUpdated extends TripEvent {
  final List<Trip> trips;

  const _TripsUpdated(this.trips);

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