import 'package:cargocalculaterapp/constants/constants.dart';
import 'package:cargocalculaterapp/features/home/data/models/orders_list_response.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../core/usecase/usecase.dart';
import '../../data/models/banner_response.dart';
import '../../domain/usecase/banners_usecase.dart';
import '../../domain/usecase/orders_list_usecase.dart';

part 'home_event.dart';

part 'home_state.dart';

class HomeBloc extends Bloc<HomeEvent, HomeState> {
  HomeBloc(this.ordersListUseCase, this.bannersUseCase)
    : super(
        const HomeState(
          paginationLoading: false,
          isLoading: false,
          page: 1,
          selectedStatus: AppConst.all,
        ),
      ) {
    on<GetAllOrdersListEvent>(_getAllOrders);
    on<GetOrdersEvent>(_getOrders);
    on<OrderStatusEvent>(_changeOrderStatus);
    on<PaginationEvent>(_paginationLoading);
    on<GetBannersEvent>(_getBanner);
    on<RefreshEvent>(_refresh);
  }

  final OrdersListUseCase ordersListUseCase;
  final BannersUseCase bannersUseCase;

  final Map<String, dynamic> productsRequest = {};

  void _getAllOrders(GetAllOrdersListEvent event, Emitter<HomeState> emit) {
    productsRequest.remove(AppKeys.status);
    productsRequest[AppKeys.page] = 1;
    productsRequest[AppKeys.limit] = AppConst.limit;
    add(const GetOrdersEvent());
  }

  Future<void> _getOrders(GetOrdersEvent event, Emitter<HomeState> emit) async {
    emit(state.copyWith(isLoading: event.isLoading));
    final response = await ordersListUseCase(productsRequest);
    response.fold(
      (l) {
        emit(state.copyWith(isLoading: false, paginationLoading: false));
      },
      (r) {
        emit(
          state.copyWith(
            isLoading: false,
            paginationLoading: false,
            ordersList: r,
            page: productsRequest[AppKeys.page],
            pageCount: ((r.totalCount ?? 1) / 20).ceil(),
          ),
        );
      },
    );
  }

  void _changeOrderStatus(OrderStatusEvent event, Emitter<HomeState> emit) {
    if (event.status == state.selectedStatus) {
      return;
    }
    emit(state.copyWith(selectedStatus: event.status));
    productsRequest[AppKeys.page] = 1;
    if (event.status == AppConst.all) {
      productsRequest.remove(AppConst.status);
    } else {
      productsRequest[AppConst.status] = event.status;
    }
    add(const GetOrdersEvent());
  }

  Future<void> _paginationLoading(
    PaginationEvent event,
    Emitter<HomeState> emit,
  ) async {
    productsRequest[AppKeys.page] = productsRequest[AppKeys.page] + 1;
    emit(
      state.copyWith(
        paginationLoading: true,
        page: productsRequest[AppKeys.page],
      ),
    );
    final response = await ordersListUseCase(productsRequest);
    response.fold(
      (l) {
        emit(state.copyWith(isLoading: false, paginationLoading: false));
      },
      (r) {
        emit(
          state.copyWith(
            isLoading: false,
            paginationLoading: false,
            ordersList: OrdersListResponse(
              totalCount: r.totalCount,
              data: state.ordersList?.data?..addAll(r.data ?? []),
            ),
            page: productsRequest[AppKeys.page],
            pageCount: ((r.totalCount ?? 1) / 20).ceil(),
          ),
        );
      },
    );
  }

  Future<void> _getBanner(
    GetBannersEvent event,
    Emitter<HomeState> emit,
  ) async {
    final response = await bannersUseCase(const NoParams());
    response.fold((l) {}, (r) {
      emit(state.copyWith(banners: r));
    });
  }

  void _refresh(RefreshEvent event, Emitter<HomeState> emit) {
    productsRequest[AppKeys.page] = 1;
    add(const GetOrdersEvent(isLoading: false));
    add(const GetBannersEvent());
  }
}
