import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rasadyar_auth/data/utils/safe_call.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/out_of_province/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/root/logic.dart';
import 'package:rasadyar_core/core.dart';

class SalesOutOfProvinceLogic extends GetxController {
  RxInt currentIndex = 0.obs;

  RxBool isExpanded = false.obs;
  RxBool isBuyerSubmitButtonEnabled = false.obs;
  RxBool isSaleSubmitButtonEnabled = false.obs;
  RxList<int> isExpandedList = <int>[].obs;
  RxBool searchIsSelected = false.obs;

  //TODO add this to Di
  ImagePicker imagePicker = ImagePicker();

  Rx<Resource<List<OutProvinceCarcassesBuyer>>> buyerList =
      Resource<List<OutProvinceCarcassesBuyer>>.loading().obs;
  Rx<Resource<List<StewardFreeSaleBar>>> salesList =
      Resource<List<StewardFreeSaleBar>>.loading().obs;

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

  RxList<IranProvinceCityModel> cites = <IranProvinceCityModel>[].obs;
  Rxn<IranProvinceCityModel> selectedProvince = Rxn();
  Rxn<IranProvinceCityModel> selectedCity = Rxn();

  RootLogic get rootLogic => Get.find<RootLogic>();

  OutOfProvinceLogic get outOfTheProvinceLogic =>
      Get.find<OutOfProvinceLogic>();

  GlobalKey<FormState> formKey = GlobalKey<FormState>();
  TextEditingController buyerNameController = TextEditingController();
  TextEditingController buyerLastNameController = TextEditingController();
  TextEditingController buyerPhoneController = TextEditingController();
  TextEditingController buyerUnitNameController = TextEditingController();

  //Sale
  TextEditingController quarantineCodeController = TextEditingController();
  TextEditingController saleWeightController = TextEditingController();
  Rx<Jalali> saleDate = Jalali
      .now()
      .obs;
  String? key;

  Rx<Jalali> fromDateFilter = Jalali
      .now()
      .obs;
  Rx<Jalali> toDateFilter = Jalali
      .now()
      .obs;
  RxnString searchedValue = RxnString();

  @override
  void onReady() {
    super.onReady();
    getOutProvinceCarcassesBuyer();
    getOutProvinceSales();

    selectedProvince.listen((p0) => getCites());
    tLog(selectedProduct.value);
    outOfTheProvinceLogic.rolesProductsModel.listen((lists) {
      selectedProduct.value = lists.first;
    });
    setupListeners();
    debounce(
      searchedValue,
          (callback) => getOutProvinceCarcassesBuyer(),
      time: Duration(milliseconds: 2000),
    );
    ever(searchIsSelected, (data) {
      if (data == false) {
        searchedValue.value = null;
      }
    });
  }

  @override
  void onClose() {
    buyerNameController.dispose();
    buyerLastNameController.dispose();
    buyerPhoneController.dispose();
    buyerUnitNameController.dispose();
    selectedCity.value = null;
    selectedProvince.value = null;
    isExpandedList.clear();

    super.onClose();
  }

  Future<void> getOutProvinceCarcassesBuyer() async {
    await safeCall(
      call: () =>
          rootLogic.chickenRepository.getOutProvinceCarcassesBuyer(
            token: rootLogic.tokenService.accessToken.value!,
            queryParameters: buildQueryParams(
              pageSize: 10,
              page: 1,
              state: 'buyer-list',
              search: 'filter',
              role: 'Steward',
              value: searchedValue.value ?? '',
            ),
          ),
      onSuccess: (res) {
        if ((res?.count ?? 0) == 0) {
          buyerList.value = Resource<List<OutProvinceCarcassesBuyer>>.empty();
        } else {
          buyerList.value = Resource<List<OutProvinceCarcassesBuyer>>.success(
            res!.results!,
          );
        }
      },
    );
  }

  Future<void> getOutProvinceSales() async {
    await safeCall(
      call: () =>
          rootLogic.chickenRepository.getStewardFreeSaleBar(
            token: rootLogic.tokenService.accessToken.value!,
            queryParameters: buildQueryParams(
              pageSize: 10,
              page: 1,
              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<List<StewardFreeSaleBar>>.empty();
        } else {
          salesList.value = Resource<List<StewardFreeSaleBar>>.success(
            res!.results!,
          );
        }
      },
    );
  }

  Future<void> getCites() async {
    await safeCall(
      call: () =>
          rootLogic.chickenRepository.getCity(
            provinceName: selectedProvince.value?.name ?? '',
          ),
      onSuccess: (result) {
        if (result != null && result.isNotEmpty) {
          cites.value = result;
        }
      },
    );
  }

  void setupListeners() {
    //buyer form listeners
    buyerNameController.addListener(checkBuyerFormValid);
    buyerLastNameController.addListener(checkBuyerFormValid);
    buyerPhoneController.addListener(checkBuyerFormValid);
    buyerUnitNameController.addListener(checkBuyerFormValid);

    ever(selectedProvince, (_) => checkBuyerFormValid());
    ever(selectedCity, (_) => checkBuyerFormValid());
    ever(selectedProduct, (_) => checkBuyerFormValid());

    //sales form listeners
    saleWeightController.addListener(checkSalesFormValid);
    quarantineCodeController.addListener(checkSalesFormValid);
    ever(selectedBuyer, (_) => checkSalesFormValid);
    ever(selectedProduct, (_) => checkSalesFormValid);
    ever(saleDate, (_) => checkSalesFormValid());
  }

  void checkBuyerFormValid() {
    isBuyerSubmitButtonEnabled.value =
        buyerNameController.text.isNotEmpty &&
            buyerLastNameController.text.isNotEmpty &&
            buyerPhoneController.text.isNotEmpty &&
            buyerUnitNameController.text.isNotEmpty &&
            selectedProvince.value != null &&
            selectedCity.value != null &&
            selectedProduct.value != null;
  }

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

  Future<bool> createBuyer() async {
    bool res = false;
    if (!(formKey.currentState?.validate() ?? false)) {
      return res;
    }
    await safeCall(
      call: () async {
        OutProvinceCarcassesBuyer buyer = OutProvinceCarcassesBuyer(
          province: selectedProvince.value!.name,
          city: selectedCity.value!.name,
          firstName: buyerNameController.text,
          lastName: buyerLastNameController.text,
          unitName: buyerUnitNameController.text,
          mobile: buyerPhoneController.text,
          role: 'Steward',
        );
        final res = await rootLogic.chickenRepository
            .createOutProvinceCarcassesBuyer(
          token: rootLogic.tokenService.accessToken.value!,
          body: buyer,
        );
      },
      onSuccess: (result) {
        getOutProvinceCarcassesBuyer();
        resetSubmitForm();
        res = true;
      },
    );
    return res;
  }

  void resetSubmitForm() {
    buyerNameController.clear();
    buyerLastNameController.clear();
    buyerPhoneController.clear();
    buyerUnitNameController.clear();
    selectedProvince.value = null;
    selectedCity.value = null;
    selectedProduct.value = null;
    key = null;
    isBuyerSubmitButtonEnabled.value = false;
  }

  void setEditDataBuyer(OutProvinceCarcassesBuyer item) {
    buyerNameController.text = item.firstName ?? '';
    buyerLastNameController.text = item.lastName ?? '';
    buyerUnitNameController.text = item.unitName ?? '';
    buyerPhoneController.text = item.mobile ?? '';
    selectedProvince.value = IranProvinceCityModel(name: item.province);
    selectedCity.value = IranProvinceCityModel(name: item.city);
    isBuyerSubmitButtonEnabled.value = true;
  }

  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 = buyerList.value.data?.firstWhere(
          (element) => element.key == item.buyer?.key,
    );
    selectedProduct.value =
        outOfTheProvinceLogic.rolesProductsModel.value.first;
    key = item.key;
    isSaleSubmitButtonEnabled.value = true;
  }

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

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

  void clearSaleForm() {
    quarantineCodeController.clear();
    saleWeightController.clear();
    saleDate.value = Jalali.now();
    selectedBuyer.value = null;
    selectedProduct.value = null;
    isBuyerSubmitButtonEnabled.value = false;
  }

  Future<bool> editSale() async {
    bool res = false;
    StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
        numberOfCarcasses: 0,
        weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
        date: saleDate.value
            .toDateTime()
            .formattedDashedGregorian,
        clearanceCode: quarantineCodeController.text,
        key:key
    );
    await safeCall(
      call: () =>
          rootLogic.chickenRepository.updateOutProvinceStewardFreeBar(
            token: rootLogic.tokenService.accessToken.value!,
            body: requestBody,
          ),
      onSuccess: (_) {
        res = true;
      },
    );
    return res;
  }
}
