import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:farm_tpf/custom_model/CropPlot.dart';
import 'package:farm_tpf/data/api/app_exception.dart';
import 'package:farm_tpf/data/repository/repository.dart';
import 'package:meta/meta.dart';

part 'plot_detail_event.dart';
part 'plot_detail_state.dart';

class PlotDetailBloc extends Bloc<PlotDetailEvent, PlotDetailState> {
  final Repository repository;
  PlotDetailBloc({required this.repository}) : super(PlotDetailInitial());
  static int pageSize = 20;

  @override
  Stream<PlotDetailState> mapEventToState(
    PlotDetailEvent event,
  ) async* {
    if (event is DataFetched && !(state is PlotDetailSuccess && (state as PlotDetailSuccess).hasReachedMax)) {
      try {
        if (state is PlotDetailInitial) {
          yield PlotDetailLoading();
          var response;
          if (event.cropId != null) {
            response = await repository.getPlotDetail(event.cropId, page: 0, size: pageSize);
            yield PlotDetailSuccess(items: response.activities, page: 0, hasReachedMax: response.activities.length < pageSize ? true : false);
          } else {
            var response = await repository.getPlotDetailByCode(event.cropCode, page: 0, size: pageSize);

            yield PlotDetailSuccess(ownerItem: response, items: response.activities ?? <Activities>[], page: 0, hasReachedMax: true);
          }
        }
        if (state is PlotDetailSuccess) {
          final currentState = state as PlotDetailSuccess;
          var page = currentState.page + 1;
          var response;
          if (event.cropId != null) {
            response = await repository.getPlotDetail(event.cropId, page: page, size: pageSize);
            yield response.activities.isEmpty
                ? currentState.copyWith(hasReachedMax: true, items: [], page: page)
                : PlotDetailSuccess(items: currentState.items + response.activities, page: currentState.page + 1, hasReachedMax: false);
          } else {
            var response = await repository.getPlotDetailByCode(event.cropCode, page: page, size: pageSize);
            yield PlotDetailSuccess(ownerItem: response, items: response.activities ?? <Activities>[], page: 0, hasReachedMax: true);
          }
        }
      } catch (e) {
        var errorString = AppException.handleError(e);
        yield PlotDetailFailure(errorString: errorString);
      }
    }
    if (event is CheckInfo) {
      try {
        yield PlotDetailLoading();
        var response;
        if (event.cropId != null) {
          response = await repository.getPlotDetail(event.cropId, page: 0, size: pageSize);
        } else {
          response = await repository.getPlotDetailByCode(event.cropCode, page: 0, size: pageSize);
        }
        var cropPlot = response as CropPlot;
        yield PlotDetailSuccess(
          ownerItem: cropPlot,
          page: 0,
          hasReachedMax: (response.activities ?? <Activities>[]).length < pageSize ? true : false,
          items: [],
        );
      } catch (e) {
        yield PlotDetailFailure(errorString: AppException.handleError(e));
      }
    }
    if (event is OnRefresh) {
      try {
        yield PlotDetailLoading();
        var response;
        if (event.cropId != null) {
          response = await repository.getPlotDetail(event.cropId, page: 0, size: pageSize);
        } else {
          response = await repository.getPlotDetailByCode(event.cropCode, page: 0, size: pageSize);
        }
        var listActivities = <Activities>[];
        var cropPlot = response as CropPlot;
        cropPlot.activities?.forEach((element) {
          listActivities.add(Activities.clone(element));
        });
        yield PlotDetailSuccess(
            items: listActivities, page: 0, hasReachedMax: (response.activities ?? <Activities>[]).length < pageSize ? true : false);
      } catch (e) {
        yield PlotDetailFailure(errorString: AppException.handleError(e));
      }
    } else if (event is OnUpdate) {
      yield PlotDetailLoading();
      try {
        yield PlotDetailSuccess(items: event.currentItems, page: event.currentPage, hasReachedMax: event.hasReachedMax);
      } catch (e) {
        yield PlotDetailFailure(errorString: AppException.handleError(e));
      }
    }
  }
}
