import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart';
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/root/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/sale/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/sales_out_of_province_buyers/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/sales_out_of_province_sales_list/logic.dart';
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
import 'package:rasadyar_core/core.dart';

class SalesOutOfProvinceLogic extends GetxController {
  StewardRootLogic rootLogic = Get.find<StewardRootLogic>();

  SaleLogic saleLogic = Get.find<SaleLogic>();

  SalesOutOfProvinceSalesListLogic saleListLogic = Get.find<SalesOutOfProvinceSalesListLogic>();

  SalesOutOfProvinceBuyersLogic buyerLogic = Get.find<SalesOutOfProvinceBuyersLogic>();

  RxBool isExpanded = false.obs;
  RxInt currentPage = 1.obs;
  RxBool isSaleSubmitButtonEnabled = false.obs;
  RxInt expandedListIndex = (-1).obs;
  Rx<Jalali> fromDateFilter = Jalali.now().obs;
  Rx<Jalali> toDateFilter = Jalali.now().obs;
  RxnString searchedValue = RxnString();
  RxList<String> routesName = RxList();
  RxBool isLoadingMoreAllocationsMade = false.obs;
  Rxn<IranProvinceCityModel> selectedCity = Rxn();

  GlobalKey<FormState> formKey = GlobalKey<FormState>();
  TextEditingController quarantineCodeController = TextEditingController();
  TextEditingController saleWeightController = TextEditingController();
  TextEditingController saleCountController = TextEditingController();
  Rx<Jalali> saleDate = Jalali.now().obs;
  String? key;

  Rx<Resource<PaginationModel<StewardFreeSaleBar>>> salesList =
      Resource<PaginationModel<StewardFreeSaleBar>>.loading().obs;

  Rxn<ProductModel> selectedProduct = Rxn();
  Rxn<OutProvinceCarcassesBuyer> selectedBuyer = Rxn();

  RxInt saleType = 2.obs;
  RxInt quotaType = 1.obs;

  @override
  void onInit() {
    super.onInit();
    routesName.value = [...saleLogic.routesName, 'خارج استان'].toList();
  }

  @override
  void onReady() {
    super.onReady();
    getOutProvinceSales();
    selectedProduct.value = rootLogic.rolesProductsModel.first;
    debounce(
      searchedValue,
      (callback) => getOutProvinceSales(),
      time: Duration(milliseconds: timeDebounce),
    );
    setupListeners();
  }

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

  void submitFilter() {
    fromDateFilter.value = fromDateFilter.value;
    toDateFilter.value = toDateFilter.value;
    getOutProvinceSales();
  }

  Future<void> getOutProvinceSales([bool isLoadingMore = false]) async {
    if (isLoadingMore) {
      isLoadingMoreAllocationsMade.value = true;
    } else {
      salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.loading();
    }
    await safeCall(
      call: () => rootLogic.chickenRepository.getStewardFreeSaleBar(
        token: rootLogic.tokenService.accessToken.value!,
        queryParameters: buildQueryParams(
          pageSize: 20,
          page: currentPage.value,
          state: 'buyer-list',
          search: 'filter',
          role: 'Steward',
          value: searchedValue.value ?? '',
          fromDate: fromDateFilter.value.toDateTime(),
          toDate: toDateFilter.value.toDateTime(),
        ),
      ),
      onSuccess: (res) {
        if ((res?.count ?? 0) == 0) {
          salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.empty();
        } else {
          salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.success(
            PaginationModel<StewardFreeSaleBar>(
              count: res?.count ?? 0,
              next: res?.next,
              previous: res?.previous,
              results: [...(salesList.value.data?.results ?? []), ...(res?.results ?? [])],
            ),
          );

          isLoadingMoreAllocationsMade.value = false;
        }
      },
    );
  }

  void setupListeners() {
    saleWeightController.addListener(checkSalesFormValid);
    quarantineCodeController.addListener(checkSalesFormValid);
    saleWeightController.addListener(() {
      checkSalesFormValid();
      var weight = int.parse(saleWeightController.text.clearComma);
      var res = (weight / selectedProduct.value!.weightAverage!.toInt()).round();
      saleCountController.text = res.separatedByComma;
    });
    ever(selectedBuyer, (_) => checkSalesFormValid);
    ever(selectedProduct, (_) => checkSalesFormValid);
    ever(saleDate, (_) => checkSalesFormValid());
  }

  void checkSalesFormValid() {
    isSaleSubmitButtonEnabled.value =
        saleDate.value.toString().isNotEmpty &&
        selectedProduct.value != null &&
        selectedBuyer.value != null &&
        saleWeightController.text.isNotEmpty &&
        quarantineCodeController.text.isNotEmpty;
  }

  void setEditDataSales(StewardFreeSaleBar item) {
    quarantineCodeController.text = item.clearanceCode ?? '';
    saleWeightController.text = item.weightOfCarcasses?.toInt().toString() ?? '';
    saleDate.value = Jalali.fromDateTime(DateTime.parse(item.date!));
    selectedCity.value = IranProvinceCityModel(name: item.city);
    selectedBuyer.value = buyerLogic.buyerList.value.data?.results?.firstWhere(
      (element) => element.key == item.buyer?.key,
    );
    selectedProduct.value = rootLogic.rolesProductsModel.first;
    key = item.key;
    saleType.value = item.saleType == 'free' ? 2 : 1;
    quotaType.value = item.quota == 'governmental' ? 1 : 2;
    isSaleSubmitButtonEnabled.value = true;
  }

  Future<void> deleteStewardPurchaseOutOfProvince(String key) async {
    await safeCall(
      call: () => rootLogic.chickenRepository.deleteOutProvinceStewardFreeBar(
        token: rootLogic.tokenService.accessToken.value!,
        key: key,
      ),
    );
  }

  Future<bool> createSale() async {
    bool res = false;
    StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
      buyerKey: selectedBuyer.value?.key,
      numberOfCarcasses: int.tryParse(saleCountController.text.clearComma),
      weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
      date: saleDate.value.toDateTime().formattedDashedGregorian,
      clearanceCode: quarantineCodeController.text,
      productKey: selectedProduct.value?.key,
      saleType: saleType.value == 2 ? 'free' : 'exclusive',
      quota: quotaType.value == 1 ? 'governmental' : 'free',
    );
    await safeCall(
      showError: true,
      call: () => rootLogic.chickenRepository.createOutProvinceStewardFreeBar(
        token: rootLogic.tokenService.accessToken.value!,
        body: requestBody,
      ),
      onSuccess: (_) {
        res = true;
        onRefresh();
        rootLogic.onRefresh();
      },
    );
    return res;
  }

  void clearSaleForm() {
    quarantineCodeController.clear();
    saleWeightController.clear();
    saleDate.value = Jalali.now();
    saleType.value = 2;
    quotaType.value = 1;
    selectedBuyer.value = null;
  }

  Future<bool> editSale() async {
    bool res = false;
    StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
      numberOfCarcasses: int.tryParse(saleCountController.text.clearComma),
      weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
      date: saleDate.value.toDateTime().formattedDashedGregorian,
      clearanceCode: quarantineCodeController.text,
      saleType: saleType.value == 2 ? 'free' : 'exclusive',
      quota: quotaType.value == 1 ? 'governmental' : 'free',
      key: key,
    );
    await safeCall(
      call: () => rootLogic.chickenRepository.updateOutProvinceStewardFreeBar(
        token: rootLogic.tokenService.accessToken.value!,
        body: requestBody,
      ),
      onSuccess: (_) {
        res = true;
        onRefresh();
      },
    );
    return res;
  }

  void resetSubmitForm() {
    selectedCity.value = null;

    key = null;
  }

  Future<void> onRefresh() async {
    toggleExpansion();
    currentPage.value = 1;
    resetSubmitForm();
    clearSaleForm();
    await rootLogic.onRefresh();
    await getOutProvinceSales();
  }

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