import 'package:collection/collection.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow/core/application/di/injectable.dart';
import 'package:krow/features/profile/certificates/domain/certificates_repository.dart';
import 'package:krow/features/profile/certificates/data/models/staff_certificate.dart';
import 'package:krow/features/profile/certificates/domain/bloc/certificates_event.dart';
import 'package:krow/features/profile/certificates/domain/bloc/certificates_state.dart';

class CertificatesBloc extends Bloc<CertificatesEvent, CertificatesState> {
  CertificatesBloc() : super(CertificatesState()) {
    on<CertificatesEventFetch>(_onFetch);
    on<CertificatesEventSubmit>(_onSubmit);
    on<CertificatesEventUpload>(_onUploadPhoto);
    on<CertificatesEventDelete>(_onDeleteCertificate);
  }

  void _onFetch(
      CertificatesEventFetch event, Emitter<CertificatesState> emit) async {
    emit(state.copyWith(loading: true));
    var certificates = await getIt<CertificatesRepository>().getCertificates();
    List<StaffCertificate> staffCertificates =
        await getIt<CertificatesRepository>().getStaffCertificates();
    var items = certificates.map((certificate) {
      var staffCertificate = staffCertificates.firstWhereOrNull(
        (e) => certificate.id == e.certificate.id,
      );

      return CertificatesViewModel(
        id: staffCertificate?.id,
        certificateId: certificate.id,
        title: certificate.name,
        imageUrl: staffCertificate?.file,
        expirationDate: staffCertificate?.expirationDate,
        status: staffCertificate?.status,
      );
    }).toList();

    emit(state.copyWith(
      loading: false,
      certificatesItems: items,
    ));
  }

  void _onUploadPhoto(
      CertificatesEventUpload event, Emitter<CertificatesState> emit) async {
    event.item.uploading = true;
    emit(state.copyWith());

    try {
      var split = event.expirationDate.split('.').reversed;
      split = [split.elementAt(0), split.elementAt(2), split.elementAt(1)];
      var formattedDate = split.join('-');
      var newCertificate = await getIt<CertificatesRepository>()
          .putStaffCertificate(
              event.item.certificateId, event.path, formattedDate);
      event.item.applyNewStaffCertificate(newCertificate);
    } finally {
      event.item.uploading = false;
      emit(state.copyWith());
    }
  }

  void _onSubmit(
      CertificatesEventSubmit event, Emitter<CertificatesState> emit) async {
    final allCertUploaded = state.certificatesItems.every((element) {
      return element.certificateId == '3' ||
        element.status == CertificateStatus.pending ||
        element.status == CertificateStatus.verified;
    });

    if (allCertUploaded) {
      emit(state.copyWith(success: true));
    } else {
      emit(state.copyWith(showError: true));
    }
  }

  void _onDeleteCertificate(
      CertificatesEventDelete event, Emitter<CertificatesState> emit) async {
    emit(state.copyWith(loading: true));
    try {
      await getIt<CertificatesRepository>()
          .deleteStaffCertificate(event.item.id ?? '0');
      state.certificatesItems
          .firstWhere((element) => element.id == event.item.id)
          .clear();
    } finally {
      emit(state.copyWith(loading: false));
    }
  }
}
