import 'dart:async';

import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart';
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/root/logic.dart';
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
import 'package:rasadyar_core/core.dart';

class BuyInProvinceWaitingLogic extends GetxController {
  RxInt isExpandedListIndex = (-1).obs;
  Rx<Jalali> fromDateFilter = Jalali.now().obs;
  Rx<Jalali> toDateFilter = Jalali.now().obs;
  RxnString searchedValue = RxnString();
  RxMap<String, bool> isLoadingConfirmMap = RxMap();
  Rx<Color> bgConfirmAllColor = AppColor.blueNormal.obs;
  RxInt currentPage = 1.obs;
  final RxBool isLoadingMoreAllocationsMade = false.obs;
  StewardRootLogic rootLogic = Get.find<StewardRootLogic>();

  Rx<Resource<PaginationModel<WaitingArrivalModel>>> waitingProduct =
      Resource<PaginationModel<WaitingArrivalModel>>.loading().obs;

  TextEditingController weightController = TextEditingController();
  TextEditingController countController = TextEditingController();
  TextEditingController lossController = TextEditingController();
  TextEditingController approvedWithOtpController = TextEditingController();

  RxBool approvedWithOtpCode = false.obs;

  @override
  void onInit() {
    super.onInit();
    debounce(
      searchedValue,
      (callback) => getWaitingArrivals(),
      time: Duration(milliseconds: timeDebounce),
    );
  }

  @override
  void onReady() {
    super.onReady();
    getWaitingArrivals();
  }

  @override
  void onClose() {
    super.onClose();
  }

  void setSearchValue(String? data) {
    searchedValue.value = data?.trim();
  }

  Future<void> getWaitingArrivals([bool isLoadingMore = false]) async {
    if (isLoadingMore) {
      isLoadingMoreAllocationsMade.value = true;
    } else {
      waitingProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.loading();
    }

    if (searchedValue.value != null &&
        searchedValue.value!.trim().isNotEmpty &&
        currentPage.value > 1) {
      currentPage.value = 1;
    }

    safeCall(
      call: () async => await rootLogic.chickenRepository.getWaitingArrivals(
        token: rootLogic.tokenService.accessToken.value!,
        queryParameters: buildQueryParams(
          queryParams: {'type': 'not_entered'},
          pageSize: 20,
          page: currentPage.value,
          search: 'filter',
          role: 'Steward',
          value: searchedValue.value,
          fromDate: fromDateFilter.value?.toDateTime(),
          toDate: toDateFilter.value?.toDateTime(),
        ),
      ),
      onSuccess: (res) async {
        await Future.delayed(Duration(milliseconds: 200));
        if ((res?.count ?? 0) == 0) {
          waitingProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.empty();
        } else {
          waitingProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.success(
            PaginationModel<WaitingArrivalModel>(
              count: res?.count ?? 0,
              next: res?.next,
              previous: res?.previous,
              results: [...(waitingProduct.value.data?.results ?? []), ...(res?.results ?? [])],
            ),
          );
          flashingFabBgColor();
        }
      },
    );
  }

  Future<void> acceptEntries(WaitingArrivalModel model) async {
    var request = StewardAllocationRequest(
      allocationKey: model.key,
      checkAllocation: true,
      state: 'accepted',
      receiverRealNumberOfCarcasses: model.realNumberOfCarcasses ?? 0,
      receiverRealWeightOfCarcasses: model.realWeightOfCarcasses?.toInt() ?? 0,
      registrationCode: model.registrationCode,
      weightLossOfCarcasses: model.weightLossOfCarcasses?.toInt() ?? 0,
    ).toJson();
    request.removeWhere((key, value) => value == null);

    safeCall(
      showError: true,
      call: () async => await rootLogic.chickenRepository.setSateForArrivals(
        token: rootLogic.tokenService.accessToken.value!,
        request: request,
      ),
      onError: (error, stackTrace) {
        eLog(error);
      },
      onSuccess: (result) {
        getWaitingArrivals();
        rootLogic.onRefresh();
        clearApprovedController();
        toggleExpansion();
        Get.back();
      },
    );
  }

  Future<void> denyEntries(WaitingArrivalModel model) async {
    var request = StewardAllocationRequest(
      allocationKey: model.key,
      checkAllocation: true,
      state: 'rejected',
    ).toJson();
    request.removeWhere((key, value) => value == null);

    safeCall(
      call: () async => await rootLogic.chickenRepository.setSateForArrivals(
        token: rootLogic.tokenService.accessToken.value!,
        request: request,
      ),
      onError: (error, stackTrace) {
        eLog(error);
      },
      onSuccess: (result) {
        getWaitingArrivals();
        rootLogic.onRefresh();
      },
    );
  }

  void flashingFabBgColor() {
    Timer.periodic(Duration(seconds: 2), (timer) {
      if (bgConfirmAllColor.value == AppColor.blueNormal) {
        bgConfirmAllColor.value = AppColor.blueLightHover;
      } else {
        bgConfirmAllColor.value = AppColor.blueNormal;
      }
    });
  }

  void clearApprovedController() {
    weightController.clear();
    countController.clear();
    lossController.clear();
    approvedWithOtpController.clear();
    approvedWithOtpCode.value = false;
  }

  void toggleExpansion({int? index}) {
    if (isExpandedListIndex.value == index || index == null) {
      isExpandedListIndex.value = -1;
    } else {
      isExpandedListIndex.value = index;
    }
  }
}
