import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart';
import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart';
import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart';
import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart';
import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/genocide/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
import 'package:rasadyar_core/core.dart';

class KillingRegistrationLogic extends GetxController {
  List<String> routes = ['اقدام', 'درخواست کشتارها', 'ثبت کشتار'];
  var tokenService = Get.find<TokenStorageService>();
  var gService = Get.find<GService>();
  var rootLogic = Get.find<PoultryScienceRootLogic>();
  GlobalKey<FormState> formKey = GlobalKey<FormState>();

  Rxn<ApprovedPrice> approvedPrice = Rxn<ApprovedPrice>();
  Rx<Jalali> killsDate = Jalali.now().obs;

  Rxn<SellForFreezing> sellForFreezing = Rxn<SellForFreezing>();
  Rxn<PoultryExport> poultryExport = Rxn<PoultryExport>();

  TextEditingController quantityKillsController = TextEditingController();
  RxBool quantityKillsIsCompleted = false.obs;
  TextEditingController quantityLoseController = TextEditingController(text: 0.toString());
  TextEditingController averageWeightKillsController = TextEditingController();
  RxBool averageWeightKillsIsCompleted = false.obs;
  TextEditingController priceFreeSaleController = TextEditingController();

  RxInt generatedApprovedPrice = 0.obs;
  RxBool isOnSubmitLoading = false.obs;

  RxBool isExportSelected = false.obs;
  RxBool isFreezedSelected = false.obs;
  RxBool isMarketSelected = false.obs;
  RxBool isFreeSale = false.obs;

  //step 1
  Rx<Resource<List<AllPoultry>>> allPoultryList = Resource<List<AllPoultry>>.loading().obs;
  Rxn<AllPoultry> selectedPoultry = Rxn();

  //step 2
  Rx<Resource<List<KillRequestPoultry>>> poultryList = Resource<List<KillRequestPoultry>>.success(
    [],
  ).obs;
  Rxn<KillRequestPoultry> selectedKillRequestPoultry = Rxn();

  //step 3
  Rx<Resource<List<PoultryHatching>>> poultryHatchingList = Resource<List<PoultryHatching>>.success(
    [],
  ).obs;
  Rxn<PoultryHatching> selectedPoultryHatching = Rxn();

  //step 5
  Rx<Resource<List<KillHousePoultry>>> killHouseList = Resource<List<KillHousePoultry>>.success(
    [],
  ).obs;
  Rxn<KillHousePoultry> selectedKillHouse = Rxn();

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

    getApprovedPrice();

    getAllPoultryList();

    getSellForFreezing();

    getPoultryExport();

    priceListener();

    ever(selectedKillRequestPoultry, (callback) {
      if (callback?.provinceAllowChooseKillHouse?.allowState ?? false) {
        getKillHouseList();
      }
    });

    everAll(
      [selectedPoultry, selectedKillRequestPoultry, selectedPoultryHatching, selectedKillHouse],
      (callback) {
        checkSubmitButton();
      },
    );
  }

  @override
  void onClose() {
    super.onClose();
    quantityKillsController.dispose();
    quantityLoseController.dispose();
    averageWeightKillsController.dispose();
    priceFreeSaleController.dispose();
    clearSelectedStep1();
    clearSelectedStep2();
    selectedKillHouse.value = null;
    killHouseList.value = Resource<List<KillHousePoultry>>.success([]);
  }

  void priceListener() {
    quantityKillsController.addListener(() {
      quantityKillsIsCompleted.value = quantityKillsController.text.trim().isNotEmpty;

      if (averageWeightKillsController.text.isNotEmpty &&
          quantityKillsController.text.trim().isNotEmpty) {
        generatedApprovedPrice.value = calculateApprovedPrice().toInt();
        priceFreeSaleController.text = generatedApprovedPrice.value.separatedByComma;

        checkSubmitButton();
      } else {
        generatedApprovedPrice.value = 0;
        priceFreeSaleController.text = '0';
        checkSubmitButton();
      }
    });

    averageWeightKillsController.addListener(() {
      averageWeightKillsIsCompleted.value = averageWeightKillsController.text.trim().isNotEmpty;

      if (averageWeightKillsController.text.trim().isNotEmpty &&
          quantityKillsController.text.trim().isNotEmpty) {
        generatedApprovedPrice.value = calculateApprovedPrice().toInt();
        priceFreeSaleController.text = generatedApprovedPrice.value.separatedByComma;
        checkSubmitButton();
      } else {
        generatedApprovedPrice.value = 0;
        priceFreeSaleController.text = '0';
        checkSubmitButton();
      }
    });

    priceFreeSaleController.addListener(() {
      final text = priceFreeSaleController.text;
      if (text.isNotEmpty) {
        generatedApprovedPrice.value = int.parse(text.replaceAll(',', ''));
      } else {
        generatedApprovedPrice.value = 0;
      }
      checkSubmitButton();
    });
  }

  void clearSelectedStep1() {
    selectedPoultry.value = null;
    selectedKillRequestPoultry.value = null;
    selectedPoultryHatching.value = null;
    poultryList.value = Resource<List<KillRequestPoultry>>.success([]);
    poultryHatchingList.value = Resource<List<PoultryHatching>>.success([]);
  }

  void clearSelectedStep2() {
    selectedKillRequestPoultry.value = null;
    selectedPoultryHatching.value = null;
    poultryHatchingList.value = Resource<List<PoultryHatching>>.success([]);
  }

  Future<void> getApprovedPrice() async {
    await safeCall(
      call: () async => await rootLogic.poultryRepository.getApprovedPrice(
        token: tokenService.accessToken.value ?? '',
      ),
      onSuccess: (result) {
        if (result != null) {
          approvedPrice.value = result;
        }
      },
      onError: (error, stackTrace) {},
    );
  }

  Future<void> getAllPoultryList() async {
    await safeCall(
      call: () async => await rootLogic.poultryRepository.getAllPoultry(
        token: tokenService.accessToken.value ?? '',
        queryParameters: buildRawQueryParams(role: gService.getRole(Module.chicken)),
      ),
      onSuccess: (result) {
        if (result != null) {
          allPoultryList.value = Resource<List<AllPoultry>>.success(result);
        }
      },
      onError: (error, stackTrace) {
        allPoultryList.value = Resource<List<AllPoultry>>.error('$error -- $stackTrace');
      },
    );
  }

  Future<void> getSellForFreezing() async {
    await safeCall(
      call: () async => await rootLogic.poultryRepository.getSellForFreezing(
        token: tokenService.accessToken.value ?? '',
      ),
      onSuccess: (result) {
        if (result != null) {
          sellForFreezing.value = result;
        }
      },
      onError: (error, stackTrace) {},
    );
  }

  Future<void> getPoultryExport() async {
    await safeCall(
      call: () async => await rootLogic.poultryRepository.getPoultryExport(
        token: tokenService.accessToken.value ?? '',
      ),
      onSuccess: (result) {
        if (result != null) {
          poultryExport.value = result;
        }
      },
      onError: (error, stackTrace) {},
    );
  }

  Future<void> getUserPoultryList() async {
    poultryList.value = Resource<List<KillRequestPoultry>>.loading();
    await safeCall(
      call: () async => await rootLogic.poultryRepository.getUserPoultry(
        token: tokenService.accessToken.value ?? '',
        queryParameters: buildQueryParams(
          value: selectedPoultry.value?.user?.mobile,
          queryParams: {'type': 'filter'},
        ),
      ),
      onSuccess: (result) {
        if (result != null) {
          poultryList.value = Resource<List<KillRequestPoultry>>.success(result);
        }
      },
      onError: (error, stackTrace) {
        poultryList.value = Resource<List<KillRequestPoultry>>.error('$error -- $stackTrace');
      },
    );
  }

  Future<void> getPoultryHatchingList() async {
    poultryHatchingList.value = Resource<List<PoultryHatching>>.loading();
    await safeCall(
      call: () async => await rootLogic.poultryRepository.getPoultryHatching(
        token: tokenService.accessToken.value ?? '',
        queryParameters: buildRawQueryParams(
          queryParams: {'key': selectedKillRequestPoultry.value?.key},
        ),
      ),
      onSuccess: (result) {
        if (result != null) {
          poultryHatchingList.value = Resource<List<PoultryHatching>>.success(result);
        }
      },
      onError: (error, stackTrace) {
        poultryHatchingList.value = Resource<List<PoultryHatching>>.error('$error -- $stackTrace');
      },
    );
  }

  Future<void> getKillHouseList() async {
    killHouseList.value = Resource<List<KillHousePoultry>>.loading();
    await safeCall(
      call: () async => await rootLogic.poultryRepository.getKillHouseList(
        token: tokenService.accessToken.value ?? '',
        queryParameters: buildRawQueryParams(
          queryParams: {'show_poultry': '', 'date': DateTime.now().formattedDashedGregorian},
        ),
      ),
      onSuccess: (result) {
        if (result != null) {
          killHouseList.value = Resource<List<KillHousePoultry>>.success(result);
        }
      },
      onError: (error, stackTrace) {
        killHouseList.value = Resource<List<KillHousePoultry>>.error('$error -- $stackTrace');
      },
    );
  }

  double calculateApprovedPrice() {
    final inputWeight = double.parse(averageWeightKillsController.text) * 1000;
    final lowestWeight = approvedPrice.value?.lowestWeight ?? 0;
    final highestWeight = approvedPrice.value?.highestWeight ?? 0;
    final lowestPrice = approvedPrice.value?.lowestPrice ?? 0;
    final highestPrice = approvedPrice.value?.highestPrice ?? 0;

    if (inputWeight <= lowestWeight) {
      return lowestPrice;
    } else if (inputWeight >= highestWeight) {
      return highestPrice;
    } else {
      final diffWeight = highestWeight - lowestWeight;
      final diffPrice = highestPrice - lowestPrice;
      final fraction = diffPrice / diffWeight;
      final diffFromMinWeight = inputWeight - lowestWeight;
      return diffFromMinWeight * fraction + lowestPrice;
    }
  }

  void changeSaleType() {
    isFreeSale.value = !isFreeSale.value;
    generatedApprovedPrice.value = calculateApprovedPrice().toInt();
  }

  void checkSubmitButton() {
    isOnSubmitLoading.value =
        selectedPoultry.value != null &&
        selectedKillRequestPoultry.value != null &&
        selectedPoultryHatching.value != null &&
        quantityKillsController.text.isNotEmpty &&
        averageWeightKillsController.text.isNotEmpty &&
        ((selectedKillRequestPoultry.value?.provinceAllowChooseKillHouse?.mandatory ?? false)
            ? selectedKillHouse.value != null
            : true);
  }

  Future<void> submitKillRegistration() async {
    isOnSubmitLoading.value = false;
    if (!formKey.currentState!.validate()) {
      return;
    }

    dLog(double.parse(averageWeightKillsController.text));
    KillRegistrationRequest registrationRequest = KillRegistrationRequest(
      indexWeight: double.parse(averageWeightKillsController.text),
      amount: generatedApprovedPrice.value,
      approvedPrice: approvedPrice.value?.approved ?? false,
      auctionList: [],
      cash: true,
      chickenBreed: selectedPoultryHatching.value?.chickenBreed,
      confirmPoultryMobile: selectedPoultry.value?.user?.mobile,
      credit: false,
      export: isExportSelected.value,
      financialOperation: "outside-system",
      freeSaleInProvince: isMarketSelected.value,
      freezing: isFreezedSelected.value,
      killHouseList: [
        if (selectedKillHouse.value != null)
          '${selectedKillHouse.value?.name}(${selectedKillHouse.value?.fullname})',
      ],
      killReqKey: selectedKillHouse.value?.killReqKey,
      losses: quantityLoseController.text,
      market: isMarketSelected.value,
      operatorKey: "",
      poultryHatchingKey: selectedPoultryHatching.value?.key,
      poultryKey: selectedPoultry.value?.key,
      quantity: int.parse(quantityKillsController.text.clearComma),
      role: gService.getRole(Module.chicken),
      sendDate: killsDate.value.toDateTime().formattedDashedGregorian,
    );

    await safeCall(
      call: () async => await rootLogic.poultryRepository.submitKillRegistration(
        token: tokenService.accessToken.value ?? '',
        request: registrationRequest,
      ),
      onSuccess: (result) async {
        defaultShowSuccessMessage(
          'ثبت با موفقیت انجام شد',
          durationInSeconds: 2,
          onDismissed: () async {
            Get.find<GenocideLogic>().getPoultryOrderList();
            Future.delayed(Duration(milliseconds: 300), () {
              Get.back();
            });
            Get.find<GenocideLogic>().getPoultryOrderList();
          },
        );
      },
      onError: (error, stackTrace) {},
    );
  }

  void clearAllFields() {
    // ریست فرم
    formKey.currentState?.reset();

    // ریست Rxn ها
    approvedPrice.value = null;
    sellForFreezing.value = null;
    poultryExport.value = null;
    selectedPoultry.value = null;
    selectedKillRequestPoultry.value = null;
    selectedPoultryHatching.value = null;
    selectedKillHouse.value = null;

    // ریست Rx ها
    killsDate.value = Jalali.now();
    generatedApprovedPrice.value = 0;
    isOnSubmitLoading.value = false;
    isExportSelected.value = false;
    isFreezedSelected.value = false;
    isMarketSelected.value = false;
    isFreeSale.value = false;

    // ریست TextEditingController ها
    quantityKillsController.clear();
    quantityLoseController.text = '0';
    averageWeightKillsController.clear();
    priceFreeSaleController.clear();

    // ریست RxBool ها
    quantityKillsIsCompleted.value = false;
    averageWeightKillsIsCompleted.value = false;

    // ریست Resource لیست‌ها
    allPoultryList.value = Resource<List<AllPoultry>>.loading();
    poultryList.value = Resource<List<KillRequestPoultry>>.success([]);
    poultryHatchingList.value = Resource<List<PoultryHatching>>.success([]);
    killHouseList.value = Resource<List<KillHousePoultry>>.success([]);
  }
}
