import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_state.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
import 'package:syncrow_web/services/space_model_mang_api.dart';

class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
  final SpaceModelManagementApi api;
  final SpaceTreeBloc _spaceTreeBloc;

  SpaceModelBloc(
    this._spaceTreeBloc, {
    required this.api,
    required List<SpaceTemplateModel> initialSpaceModels,
  }) : super(SpaceModelLoaded(spaceModels: initialSpaceModels)) {
    on<CreateSpaceModel>(_onCreateSpaceModel);
    on<UpdateSpaceModel>(_onUpdateSpaceModel);
    on<DeleteSpaceModel>(_onDeleteSpaceModel);
  }

  Future<void> _onCreateSpaceModel(CreateSpaceModel event, Emitter<SpaceModelState> emit) async {
    final currentState = state;

    if (currentState is SpaceModelLoaded) {
      try {
        final projectUuid = await ProjectManager.getProjectUUID() ?? '';

        final newSpaceModel = await api.getSpaceModel(event.newSpaceModel.uuid ?? '', projectUuid);

        if (newSpaceModel != null) {
          final updatedSpaceModels = List<SpaceTemplateModel>.from(currentState.spaceModels)
            ..add(newSpaceModel);
          emit(SpaceModelLoaded(spaceModels: updatedSpaceModels));
        }
      } catch (e) {
        emit(SpaceModelError(message: e.toString()));
      }
    }
  }

  Future<void> _onUpdateSpaceModel(UpdateSpaceModel event, Emitter<SpaceModelState> emit) async {
    final currentState = state;
    if (currentState is SpaceModelLoaded) {
      try {
        final projectUuid = await ProjectManager.getProjectUUID() ?? '';

        final newSpaceModel = await api.getSpaceModel(event.spaceModelUuid, projectUuid);
        if (newSpaceModel != null) {
          final updatedSpaceModels = currentState.spaceModels.map((model) {
            return model.uuid == event.spaceModelUuid ? newSpaceModel : model;
          }).toList();
          _spaceTreeBloc.add(InitialEvent());
          emit(SpaceModelLoaded(spaceModels: updatedSpaceModels));
        }
      } catch (e) {
        emit(SpaceModelError(message: e.toString()));
      }
    }
  }

  Future<void> _onDeleteSpaceModel(DeleteSpaceModel event, Emitter<SpaceModelState> emit) async {
    final currentState = state;

    if (currentState is SpaceModelLoaded) {
      try {
        final projectUuid = await ProjectManager.getProjectUUID() ?? '';

        final deletedSuccessfully = await api.deleteSpaceModel(event.spaceModelUuid, projectUuid);

        if (deletedSuccessfully) {
          final updatedSpaceModels = currentState.spaceModels
              .where((model) => model.uuid != event.spaceModelUuid)
              .toList();
          _spaceTreeBloc.add(InitialEvent());
          emit(SpaceModelLoaded(spaceModels: updatedSpaceModels));
        }
      } catch (e) {
        emit(SpaceModelError(message: e.toString()));
      }
    }
  }
}
