import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:tugas_akhir_supabase/domain/entities/field.dart';
import 'package:tugas_akhir_supabase/domain/usecases/field_usecases.dart';

part 'field_event.dart';
part 'field_state.dart';

class FieldBloc extends Bloc<FieldEvent, FieldState> {
  final GetFields getFields;
  final CreateField createField;
  final UpdateField updateField;
  final DeleteField deleteField;

  FieldBloc({
    required this.getFields,
    required this.createField,
    required this.updateField,
    required this.deleteField,
  }) : super(FieldInitial()) {
    on<LoadFields>(_onLoadFields);
    on<AddField>(_onAddField);
    on<EditField>(_onEditField);
    on<RemoveField>(_onRemoveField);
  }

  Future<void> _onLoadFields(
    LoadFields event,
    Emitter<FieldState> emit,
  ) async {
    emit(FieldLoading());
    
    final result = await getFields(event.userId);
    
    result.fold(
      (failure) => emit(FieldError(message: failure.message)),
      (fields) => emit(FieldLoaded(fields: fields)),
    );
  }

  Future<void> _onAddField(
    AddField event,
    Emitter<FieldState> emit,
  ) async {
    emit(FieldOperationInProgress());
    
    final result = await createField(event.field);
    
    result.fold(
      (failure) => emit(FieldOperationFailure(message: failure.message)),
      (field) {
        if (state is FieldLoaded) {
          final currentFields = (state as FieldLoaded).fields;
          emit(FieldLoaded(fields: [...currentFields, field]));
        }
        emit(FieldOperationSuccess());
      },
    );
  }

  Future<void> _onEditField(
    EditField event,
    Emitter<FieldState> emit,
  ) async {
    emit(FieldOperationInProgress());
    
    final result = await updateField(event.field);
    
    result.fold(
      (failure) => emit(FieldOperationFailure(message: failure.message)),
      (updatedField) {
        if (state is FieldLoaded) {
          final currentFields = (state as FieldLoaded).fields;
          final updatedFields = currentFields.map((field) {
            return field.id == updatedField.id ? updatedField : field;
          }).toList();
          
          emit(FieldLoaded(fields: updatedFields));
        }
        emit(FieldOperationSuccess());
      },
    );
  }

  Future<void> _onRemoveField(
    RemoveField event,
    Emitter<FieldState> emit,
  ) async {
    emit(FieldOperationInProgress());
    
    final result = await deleteField(event.fieldId);
    
    result.fold(
      (failure) => emit(FieldOperationFailure(message: failure.message)),
      (success) {
        if (state is FieldLoaded) {
          final currentFields = (state as FieldLoaded).fields;
          final updatedFields = currentFields
              .where((field) => field.id != event.fieldId)
              .toList();
          
          emit(FieldLoaded(fields: updatedFields));
        }
        emit(FieldOperationSuccess());
      },
    );
  }
} 