import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:travel_mate/services/error_service.dart';
import 'account_event.dart';
import 'account_state.dart';
import '../../repositories/account_repository.dart';
import '../../models/account.dart';

class AccountBloc extends Bloc<AccountEvent, AccountState> { 
  final AccountRepository _repository;
  StreamSubscription? _accountsSubscription;
  final _errorService = ErrorService();

  AccountBloc(this._repository) : super(AccountInitial()) {
    on<LoadAccountsByUserId>(_onLoadAccountsByUserId);
    on<_AccountsUpdated>(_onAccountsUpdated);
    on<CreateAccount>(_onCreateAccount);
    on<CreateAccountWithMembers>(_onCreateAccountWithMembers);
  }

  Future<void> _onLoadAccountsByUserId(
    LoadAccountsByUserId event,
    Emitter<AccountState> emit,
  ) async {    
    try {
      emit(AccountLoading());
      await _accountsSubscription?.cancel();
      _accountsSubscription = _repository.getAccountByUserId(event.userId).listen(
        (accounts) {
          add(_AccountsUpdated(accounts));
        },
        onError: (error) {
          add(_AccountsUpdated([], error: error.toString()));
        },
      );
    } catch (e, stackTrace) {
      _errorService.logError(e.toString(), stackTrace);
      emit(AccountError(e.toString()));
    }
  }

  Future<void> _onAccountsUpdated(
    _AccountsUpdated event,
    Emitter<AccountState> emit,
  ) async {
    if (event.error != null) {
      _errorService.logError(event.error!, StackTrace.current);
      emit(AccountError(event.error!));
    } else {
      emit(AccountsLoaded(event.accounts));
    }
  }

  Future<void> _onCreateAccount(
    CreateAccount event,
    Emitter<AccountState> emit,
  ) async {
    try {
      emit(AccountLoading());
      final accountId = await _repository.createAccountWithMembers(
        account: event.account,
        members: [],
      );
      emit(AccountOperationSuccess('Compte créé avec succès. ID: $accountId'));
    } catch (e, stackTrace) {
      _errorService.logError(e.toString(), stackTrace);
      emit(AccountError('Erreur lors de la création du compte: ${e.toString()}'));
    }
  }

  Future<void> _onCreateAccountWithMembers(
    CreateAccountWithMembers event,
    Emitter<AccountState> emit,
  ) async {
    try{
      emit(AccountLoading());
      final accountId = await _repository.createAccountWithMembers(
        account: event.account,
        members: event.members,
      );
      emit(AccountOperationSuccess('Compte créé avec succès. ID: $accountId'));
    } catch (e, stackTrace) {
      _errorService.logError(e.toString(), stackTrace);
      emit(AccountError('Erreur lors de la création du compte: ${e.toString()}'));
    }
  }

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

class _AccountsUpdated extends AccountEvent {
  final List<Account> accounts;
  final String? error;

  const _AccountsUpdated(this.accounts, {this.error});

  @override
  List<Object?> get props => [accounts, error];
}