import 'package:bloc/bloc.dart';
import 'pdf_annotation_event.dart';
import 'pdf_annotation_state.dart';
import '../../services/file_service.dart';
import '../../models/annotation.dart';
import '../../models/api_error.dart';

class PdfAnnotationBloc extends Bloc<PdfAnnotationEvent, PdfAnnotationState> {
  final FileService _fileService;
  final String _orgId;
  final String _fileId;
  final List<Annotation> _annotations = <Annotation>[];
  final List<Annotation> _undoStack = <Annotation>[];
  String _selectedTool = 'text';

  PdfAnnotationBloc(this._fileService, this._orgId, this._fileId)
    : super(PdfAnnotationIdle()) {
    on<AnnotationToolSelected>(_onAnnotationToolSelected);
    on<AnnotationAdded>(_onAnnotationAdded);
    on<AnnotationRemoved>(_onAnnotationRemoved);
    on<AnnotationUndo>(_onAnnotationUndo);
    on<AnnotationRedo>(_onAnnotationRedo);
    on<AnnotationsSaved>(_onAnnotationsSaved);
  }

  String _getErrorMessage(dynamic error) {
    if (error is ApiError) {
      switch (error.code) {
        case 'CONFLICT':
          return 'The document has changed. Please reload to see the latest version.';
        case 'PERMISSION_DENIED':
          return 'You do not have permission to annotate this document.';
        default:
          return error.message;
      }
    }
    return error.toString();
  }

  void _onAnnotationToolSelected(
    AnnotationToolSelected event,
    Emitter<PdfAnnotationState> emit,
  ) {
    _selectedTool = event.tool;
    emit(
      PdfAnnotationEditing(
        annotations: _annotations,
        undoStack: _undoStack,
        selectedTool: _selectedTool,
      ),
    );
  }

  void _onAnnotationAdded(
    AnnotationAdded event,
    Emitter<PdfAnnotationState> emit,
  ) {
    _annotations.add(event.annotation);
    emit(
      PdfAnnotationEditing(
        annotations: _annotations,
        undoStack: _undoStack,
        selectedTool: _selectedTool,
      ),
    );
  }

  void _onAnnotationRemoved(
    AnnotationRemoved event,
    Emitter<PdfAnnotationState> emit,
  ) {
    _annotations.removeWhere((a) => a.id == event.id);
    emit(
      PdfAnnotationEditing(
        annotations: _annotations,
        undoStack: _undoStack,
        selectedTool: _selectedTool,
      ),
    );
  }

  void _onAnnotationUndo(
    AnnotationUndo event,
    Emitter<PdfAnnotationState> emit,
  ) {
    if (_annotations.isNotEmpty) {
      _undoStack.add(_annotations.removeLast());
    }
    emit(
      PdfAnnotationEditing(
        annotations: _annotations,
        undoStack: _undoStack,
        selectedTool: _selectedTool,
      ),
    );
  }

  void _onAnnotationRedo(
    AnnotationRedo event,
    Emitter<PdfAnnotationState> emit,
  ) {
    if (_undoStack.isNotEmpty) {
      _annotations.add(_undoStack.removeLast());
    }
    emit(
      PdfAnnotationEditing(
        annotations: _annotations,
        undoStack: _undoStack,
        selectedTool: _selectedTool,
      ),
    );
  }

  void _onAnnotationsSaved(
    AnnotationsSaved event,
    Emitter<PdfAnnotationState> emit,
  ) async {
    emit(PdfAnnotationSaving());
    try {
      await _fileService.saveAnnotations(_orgId, _fileId, _annotations);
      emit(PdfAnnotationSaved());
      // Reset to idle or editing?
      emit(PdfAnnotationIdle());
    } catch (e) {
      emit(PdfAnnotationError(message: _getErrorMessage(e)));
    }
  }
}
