import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:farm_tpf/presentation/screens/task/models/task_update_request.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import '../../../../data/api/app_exception.dart';
import '../../../../data/repository/repository.dart';
import '../../../../models/item_dropdown.dart';
import '../../../../utils/const_common.dart';
import '../../../../utils/helpers.dart';
import '../../../../utils/utils.dart';
import '../../../custom_widgets/widget_utils.dart';
import '../models/task.dart';
import '../models/task_filter_request.dart';

part 'task_event.dart';
part 'task_state.dart';

class TaskBloc extends Bloc<TaskEvent, TaskState> {
  final Repository repository;
  int pageSize = 20;
  TaskBloc(this.repository) : super(TaskInitial());
  var status = ValueNotifier(
    TaskStatus.values
        .map(
          (e) => ItemDropDown(key: describeEnum(e), value: Helpers.getTaskStatus(describeEnum(e))),
        )
        .toList(),
  );

  var selectedStatus = ValueNotifier(
    TaskStatus.values
        .map(
          (e) => ItemDropDown(key: describeEnum(e), value: Helpers.getTaskStatus(describeEnum(e))),
        )
        .toList(),
  );
  var sort = ValueNotifier(describeEnum(SortType.asc));
  var cropId = -1;

  @override
  Stream<TaskState> mapEventToState(
    TaskEvent event,
  ) async* {
    if (event is DataFetched && !(state is TaskSuccess && ((state as TaskSuccess).hasReachedMax ?? false))) {
      try {
        if (state is TaskInitial) {
          yield (TaskLoading());
          final response = await getListTask(0);
          yield TaskSuccess(
            items: response,
            page: 0,
            hasReachedMax: response.length < pageSize ? true : false,
          );
        }
        if (state is TaskSuccess) {
          final currentState = state as TaskSuccess;
          if (currentState.hasReachedMax ?? false) {
            return;
          }
          int page = (currentState.page ?? 0) + 1;
          final response = await getListTask(page);
          yield response.isEmpty
              ? currentState.copyWith(hasReachedMax: true)
              : TaskSuccess(
                  items: (currentState.items ?? []) + response,
                  page: (currentState.page ?? 0) + 1,
                  hasReachedMax: false,
                );
        }
      } catch (e) {
        var errorString = AppException.handleError(e);
        yield (TaskFailure(errorString: errorString));
      }
    }
    if (event is OnRefresh) {
      try {
        yield (TaskLoading());
        final response = await getListTask(0);
        var items = <Task>[];
        response.forEach((element) {
          items.add(Task.clone(element));
        });
        yield TaskSuccess(
          items: items,
          page: 0,
          hasReachedMax: items.length < pageSize ? true : false,
        );
      } catch (e) {
        yield (TaskFailure(errorString: AppException.handleError(e)));
      }
    } else if (event is OnSearch) {
      try {
        yield (TaskLoading());
        final response = await getListTask(0);
        yield TaskSuccess(items: response, page: 0, hasReachedMax: response.length < pageSize ? true : false);
      } catch (e) {
        yield (TaskFailure(errorString: AppException.handleError(e)));
      }
    }
  }

  Future<List<Task>> getListTask(int page) async {
    var filter = TaskFilterRequest()
      ..cropId = cropId
      ..sort = sort.value
      ..status = selectedStatus.value.map((e) => e.key ?? '').toList();
    return await repository.tasks(page: 0, filter: filter);
  }

  Future<void> updateStatusTask(
    RequestTaskUpdate task, {
    required Function onSuccess,
  }) async {
    print(task.toJson());
    UtilWidget.showLoading();
    await repository.updateTask(
      (success) {
        UtilWidget.hideDialog();
        // Utils.showSnackBarSuccess();
        onSuccess();
      },
      (errorMessage) {
        UtilWidget.hideDialog();
        Utils.showSnackBarError();
      },
      item: task,
    );
  }
}
