import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import '../../../domain/entities/tour.dart';
import '../../../domain/entities/logistic_object.dart';
import '../../../domain/repositories/tour_repository.dart';
import '../../../core/errors/failures.dart';

part 'tour_event.dart';
part 'tour_state.dart';

class TourBloc extends Bloc<TourEvent, TourState> {
  final TourRepository repository;

  TourBloc({required this.repository}) : super(TourInitial()) {
    on<LoadTours>(_onLoadTours);
    on<SelectTour>(_onSelectTour);
    on<CompleteTour>(_onCompleteTour);
    on<SyncData>(_onSyncData);
    on<RefreshTours>(_onRefreshTours);
    on<LoadTourDetails>(_onLoadTourDetails);
  }

  Future<void> _onLoadTours(LoadTours event, Emitter<TourState> emit) async {
    emit(TourLoading());
    
    final result = await repository.getTours();
    
    result.fold(
      (failure) => emit(TourError(message: _mapFailureToMessage(failure))),
      (tours) {
        final openTours = tours.where((t) => t.state < 2).toList();
        final completedTours = tours.where((t) => t.state == 1).toList();
        
        emit(ToursLoaded(
          tours: openTours,
          completedTours: completedTours,
          allTours: tours,
        ));
      },
    );
  }

  Future<void> _onSelectTour(SelectTour event, Emitter<TourState> emit) async {
    final currentState = state;
    if (currentState is ToursLoaded) {
      emit(currentState.copyWith(selectedTour: event.tour));
    }
  }

  Future<void> _onCompleteTour(CompleteTour event, Emitter<TourState> emit) async {
    final currentState = state;
    if (currentState is ToursLoaded) {
      emit(TourLoading());
      
      final result = await repository.completeTour(event.tourId);
      
      result.fold(
        (failure) => emit(TourError(message: _mapFailureToMessage(failure))),
        (_) => add(const LoadTours()),
      );
    }
  }

  Future<void> _onSyncData(SyncData event, Emitter<TourState> emit) async {
    final currentState = state;
    if (currentState is ToursLoaded) {
      emit(currentState.copyWith(isSyncing: true));
      
      final result = await repository.syncData();
      
      result.fold(
        (failure) {
          emit(currentState.copyWith(isSyncing: false));
          emit(SyncError(message: _mapFailureToMessage(failure)));
        },
        (_) {
          emit(currentState.copyWith(isSyncing: false));
          add(const LoadTours());
        },
      );
    }
  }

  Future<void> _onRefreshTours(RefreshTours event, Emitter<TourState> emit) async {
    add(const LoadTours());
  }

  Future<void> _onLoadTourDetails(LoadTourDetails event, Emitter<TourState> emit) async {
    final currentState = state;
    if (currentState is ToursLoaded) {
      emit(currentState.copyWith(isLoadingDetails: true));
      
      final objectsResult = await repository.getObjectsByTour(event.tourId);
      final statsResult = await repository.getTourStatistics(event.tourId);
      
      objectsResult.fold(
        (failure) => emit(TourError(message: _mapFailureToMessage(failure))),
        (objects) {
          statsResult.fold(
            (failure) => emit(TourError(message: _mapFailureToMessage(failure))),
            (statistics) {
              emit(currentState.copyWith(
                selectedTourObjects: objects,
                selectedTourStats: statistics,
                isLoadingDetails: false,
              ));
            },
          );
        },
      );
    }
  }

  String _mapFailureToMessage(Failure failure) {
    return switch (failure) {
      ServerFailure _ => 'Serverfehler: ${failure.message}',
      NetworkFailure _ => 'Netzwerkfehler. Bitte überprüfen Sie Ihre Internetverbindung.',
      CacheFailure _ => 'Cachefehler: ${failure.message}',
      NotFoundFailure _ => 'Daten nicht gefunden',
      UnauthorizedFailure _ => 'Nicht autorisiert. Bitte melden Sie sich erneut an.',
      _ => 'Ein unerwarteter Fehler ist aufgetreten',
    };
  }
}
