import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../../../../core/utils/logger.dart';
import 'unified_feed_event.dart';
import 'unified_feed_state.dart';
import '../../domain/entities/feed_item.dart';
import '../../data/repositories/feed_repository.dart';

/// BLoC Centralisé pour le mur d'actualité (DRY).
/// Aucune logique graphique, juste la gestion d'états.
@injectable
class UnifiedFeedBloc extends Bloc<UnifiedFeedEvent, UnifiedFeedState> {
  final FeedRepository _repository;

  UnifiedFeedBloc(this._repository) : super(UnifiedFeedInitial()) {
    on<LoadFeedRequested>(_onLoadFeedRequested);
    on<FeedLoadMoreRequested>(_onLoadMoreRequested);
    on<ClearLoadMoreError>(_onClearLoadMoreError);
    on<FeedItemLiked>(_onFeedItemLiked);
  }

  void _onClearLoadMoreError(ClearLoadMoreError event, Emitter<UnifiedFeedState> emit) {
    if (state is UnifiedFeedLoaded) {
      emit((state as UnifiedFeedLoaded).copyWith(loadMoreErrorMessage: null));
    }
  }

  Future<void> _onLoadFeedRequested(LoadFeedRequested event, Emitter<UnifiedFeedState> emit) async {
    if (!event.isRefresh) {
      emit(UnifiedFeedLoading());
    }
    
    try {
      final items = await _repository.getFeed(page: 0, size: 10);
      
      // On suppose qu'on n'a pas atteint la fin si on a reçu la taille max demandée (10)
      final hasReachedMax = items.length < 10;
      
      emit(UnifiedFeedLoaded(items: items, hasReachedMax: hasReachedMax));
    } catch (e) {
      emit(UnifiedFeedError('Erreur de chargement du flux: $e'));
    }
  }

  Future<void> _onLoadMoreRequested(FeedLoadMoreRequested event, Emitter<UnifiedFeedState> emit) async {
    if (state is UnifiedFeedLoaded) {
      final currentState = state as UnifiedFeedLoaded;
      if (currentState.hasReachedMax || currentState.isFetchingMore) return;

      emit(currentState.copyWith(isFetchingMore: true));
      
      try {
        final nextPage = (currentState.items.length / 10).floor();
        final moreItems = await _repository.getFeed(page: nextPage, size: 10);

        emit(currentState.copyWith(
          items: List.of(currentState.items)..addAll(moreItems),
          hasReachedMax: moreItems.isEmpty,
          isFetchingMore: false,
        ));
      } catch (e, st) {
        AppLogger.error('UnifiedFeedBloc: chargement supplémentaire échoué', error: e, stackTrace: st);
        emit(currentState.copyWith(
          isFetchingMore: false,
          loadMoreErrorMessage: 'Impossible de charger plus',
        ));
      }
    }
  }

  void _onFeedItemLiked(FeedItemLiked event, Emitter<UnifiedFeedState> emit) {
    if (state is UnifiedFeedLoaded) {
      final currentState = state as UnifiedFeedLoaded;
      final updatedItems = currentState.items.map((item) {
        if (item.id == event.itemId) {
          return FeedItem(
            id: item.id,
            type: item.type,
            authorName: item.authorName,
            authorAvatarUrl: item.authorAvatarUrl,
            createdAt: item.createdAt,
            content: item.content,
            likesCount: item.isLikedByMe ? item.likesCount - 1 : item.likesCount + 1,
            commentsCount: item.commentsCount,
            isLikedByMe: !item.isLikedByMe,
            customActionLabel: item.customActionLabel,
            actionUrlTarget: item.actionUrlTarget,
          );
        }
        return item;
      }).toList();

      emit(currentState.copyWith(items: updatedItems));
    }
  }
}
