import 'dart:async';

import 'package:equatable/equatable.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/features/notes/data/notes_repository.dart';
import 'package:flux/features/notes/models/note_model.dart';
import 'package:get_it/get_it.dart';

part 'notes_state.dart';

class NotesCubit extends Cubit<NotesState> {
  final NotesRepository _repository = GetIt.I.get<NotesRepository>();
  String? get companyId => GetIt.I.get<SessionCubit>().state.company?.id;
  String? get staffId =>
      GetIt.I.get<SessionCubit>().state.currentStaffMember?.id;

  StreamSubscription<void>? _subscription;

  NotesCubit() : super(NotesState(status: NotesStatus.initial));

  void stopListening() {
    _subscription?.cancel();
    _subscription = null;
  }

  void startListening() {
    stopListening();

    emit(state.copyWith(status: NotesStatus.loading));

    // Primo caricamento
    _loadNotesSilently();

    // Inizio ascolto campanello
    try {
      _subscription = _repository
          .notesStream(companyId: companyId!, currentStaffId: staffId!)
          .listen((_) {
            // Quando il campanello suona (qualcosa è cambiato a DB), ricarichiamo!
            _loadNotesSilently();
          });
    } on Exception catch (e) {
      debugPrint(e.toString());
    }
  }

  Future<void> _loadNotesSilently() async {
    try {
      final notes = await _repository.getNotes();

      emit(
        state.copyWith(
          status: NotesStatus.success,
          notes: notes,
          errorMessage: null,
        ),
      );
    } catch (e) {
      emit(
        state.copyWith(status: NotesStatus.failure, errorMessage: e.toString()),
      );
    }
  }

  Future<void> saveNote(NoteModel note) async {
    try {
      await _repository.saveNote(note);
      // Non serve fare l'emit! Ci pensa lo stream a far rimbalzare i dati aggiornati
    } catch (e) {
      emit(
        state.copyWith(status: NotesStatus.failure, errorMessage: e.toString()),
      );
    }
  }

  Future<void> deleteNote(String noteId) async {
    try {
      await _repository.deleteNote(noteId);
      // Non serve fare l'emit
    } catch (e) {
      emit(
        state.copyWith(status: NotesStatus.failure, errorMessage: e.toString()),
      );
    }
  }

  @override
  Future<void> close() {
    stopListening();
    return super.close();
  }
}
