import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart';
import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
import 'package:rasadyar_core/core.dart';

class InspectionPoultryScienceLogic extends GetxController {
  BaseLogic baseLogic = Get.find<BaseLogic>();
  Rx<Resource<PaginationModel<HatchingModel>>> hatchingList =
      Resource<PaginationModel<HatchingModel>>.loading().obs;

  Rx<Resource<PaginationModel<HatchingReport>>> hatchingReportList =
      Resource<PaginationModel<HatchingReport>>.loading().obs;

  PoultryScienceRootLogic rootLogic = Get.find<PoultryScienceRootLogic>();

  Rx<LatLng> currentLocation = LatLng(34.798315281272544, 48.51479142983491).obs;

  final RxBool isLoadingMoreAllocationsMade = false.obs;
  RxInt currentPage = 1.obs;
  RxInt expandedIndex = RxInt(-1);
  RxList<XFile> pickedImages = <XFile>[].obs;
  final List<MultipartFile> _multiPartPickedImages = <MultipartFile>[];

  RxBool isOnUpload = false.obs;

  RxDouble presentUpload = 0.0.obs;
  RxList<String> routesName = RxList();
  RxInt selectedSegmentIndex = 0.obs;

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

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

    routesName.value = ['اقدام'].toList();

    ever(selectedSegmentIndex, (callback) {
      routesName.removeLast();
      routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی');
    });
  }

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

    checkLocationPermission(request: true);

    ever(pickedImages, (callback) {
      _multiPartPickedImages.clear();
      for (var element in pickedImages) {
        _multiPartPickedImages.add(
          MultipartFile.fromFileSync(element.path, filename: element.name),
        );
      }
    });
  }

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

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

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

    safeCall(
      call: () async => await rootLogic.poultryRepository.getHatchingPoultry(
        token: rootLogic.tokenService.accessToken.value!,
        queryParameters: buildQueryParams(
          queryParams: {'type': 'hatching', 'report': true},
          role: 'PoultryScience',
          search: 'filter',
          value: searchedValue.value,
          fromDate: fromDateFilter.value.toDateTime(),
          toDate: toDateFilter.value.toDateTime(),
          pageSize: 50,
          page: currentPage.value,
        ),
      ),
      onSuccess: (res) {
        if ((res?.count ?? 0) == 0) {
          hatchingList.value = Resource<PaginationModel<HatchingModel>>.empty();
        } else {
          hatchingList.value = Resource<PaginationModel<HatchingModel>>.success(
            PaginationModel<HatchingModel>(
              count: res?.count ?? 0,
              next: res?.next,
              previous: res?.previous,
              results: [...(hatchingList.value.data?.results ?? []), ...(res?.results ?? [])],
            ),
          );
        }
      },
    );
  }

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

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

    safeCall(
      call: () async => await rootLogic.poultryRepository.getHatchingPoultryReport(
        token: rootLogic.tokenService.accessToken.value!,
        queryParameters: buildQueryParams(
          role: 'PoultryScience',
          pageSize: 50,
          search: 'filter',
          value: searchedValue.value,
          fromDate: fromDateFilter.value.toDateTime(),
          toDate: toDateFilter.value.toDateTime(),
          page: currentPage.value,
        ),
      ),
      onSuccess: (res) {
        if ((res?.count ?? 0) == 0) {
          hatchingReportList.value = Resource<PaginationModel<HatchingReport>>.empty();
        } else {
          hatchingReportList.value = Resource<PaginationModel<HatchingReport>>.success(
            PaginationModel<HatchingReport>(
              count: res?.count ?? 0,
              next: res?.next,
              previous: res?.previous,
              results: [...(hatchingReportList.value.data?.results ?? []), ...(res?.results ?? [])],
            ),
          );
        }
      },
    );
  }

  Future<void> pickImages() async {
    determineCurrentPosition();
    var tmp = await pickCameraImage();
    if (tmp?.path != null && pickedImages.length < 7) {
      pickedImages.add(tmp!);
    }
  }

  void removeImage(int index) {
    pickedImages.removeAt(index);
  }

  void clearImages() {
    pickedImages.clear();
  }

  Future<void> submitInspectionReport({required int id}) async {
    isOnUpload.value = true;

    final tmpFiles = await Future.wait(
      pickedImages.map((element) => MultipartFile.fromFile(element.path, filename: element.name)),
    );

    var data = FormData.fromMap({
      'file': tmpFiles,
      'hatching_id': id.toString(),
      'lat': currentLocation.value.latitude.toString(),
      'log': currentLocation.value.longitude.toString(),
    });

    safeCall(
      call: () async => await rootLogic.poultryRepository.submitPoultryScienceReport(
        token: rootLogic.tokenService.accessToken.value!,
        data: data,
        onSendProgress: (sent, total) {
          presentUpload.value = calculateUploadProgress(sent: sent, total: total);
        },
      ),
      onSuccess: (res) {
        closeBottomSheet();
        clearImages();
        getHatchingList();
        getHatchingReport();
        isOnUpload.value = false;
      },
      onError: (error, stackTrace) async {
        clearImages();
        isOnUpload.value = false;

        await Future.delayed(const Duration(seconds: 4)).then((value) => closeBottomSheet());
      },
      showError: true,
    );
  }

  void closeBottomSheet() {
    Get.back();
  }

  double calculateUploadProgress({required int sent, required int total}) {
    if (total != 0) {
      double progress = (sent * 100 / total) / 100;
      return progress;
    } else {
      return 0.0;
    }
  }

  void toggleExpanded(int index) {
    expandedIndex.value = expandedIndex.value == index ? -1 : index;
  }

  String getStatus(HatchingReport item) {
    if (item.state == 'accepted') {
      return 'تکمیل شده';
    } else if (item.state == 'rejected') {
      return 'رد شده';
    } else {
      return 'در حال بررسی';
    }
  }

  Color getStatusColor(HatchingReport item) {
    if (item.state == 'accepted') {
      return AppColor.greenNormal;
    } else if (item.state == 'rejected') {
      return AppColor.redNormal;
    } else {
      return AppColor.yellowNormal;
    }
  }

  void setSearchValue(String? data) {
    dLog('Search Value: $data');
    searchedValue.value = data?.trim();
    final isReporter = selectedSegmentIndex.value == 1;
    if (isReporter) {
      getHatchingReport();
    } else {
      getHatchingList();
    }
  }

  Future<void> onRefresh() async {
    currentPage.value = 1;

    await Future.wait([getHatchingList(), getHatchingReport()]);
  }
}
