import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/dependencies.dart';
import 'package:hmg_patient_app_new/core/enums.dart';
import 'package:hmg_patient_app_new/core/utils/doctor_response_mapper.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/authentication/authentication_view_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/blood_donation_repo.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_hospitals_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_list_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/blood_group_response_model.dart';
import 'package:hmg_patient_app_new/features/blood_donation/models/cities_model.dart';
import 'package:hmg_patient_app_new/features/book_appointments/book_appointments_view_model.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/facility_selection.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/doctor_list_api_response.dart';
import 'package:hmg_patient_app_new/features/my_appointments/models/resp_models/hospital_model.dart';
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
import 'package:hmg_patient_app_new/services/dialog_service.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';

class BloodDonationViewModel extends ChangeNotifier {
  final DialogService dialogService;
  BloodDonationRepo bloodDonationRepo;
  ErrorHandlerService errorHandlerService;
  final NavigationService navigationService;
  final AppState appState;
  bool isTermsAccepted = false;
  BdGetProjectsHaveBdClinic? selectedHospital;
  CitiesModel? selectedCity;
  BloodGroupListModel? selectedBloodGroup;
  int _selectedHospitalIndex = 0;
  int _selectedBloodTypeIndex = 0;
  GenderTypeEnum? selectedGender;
  String? selectedBloodType;
  final NavigationService navServices;

  List<BdGetProjectsHaveBdClinic> hospitalList = [];

  List<CitiesModel> citiesList = [];
  List_BloodGroupDetailsModel patientBloodGroupDetailsModel = List_BloodGroupDetailsModel();

  List<BloodGroupListModel> bloodGroupList = [
    BloodGroupListModel("O+", 0),
    BloodGroupListModel("O-", 1),
    BloodGroupListModel("AB+", 2),
    BloodGroupListModel("AB-", 3),
    BloodGroupListModel("A+", 4),
    BloodGroupListModel("A-", 5),
    BloodGroupListModel("B+", 6),
    BloodGroupListModel("B-", 7),
  ];

  BloodDonationViewModel({
    required this.bloodDonationRepo,
    required this.errorHandlerService,
    required this.navigationService,
    required this.dialogService,
    required this.appState,
    required this.navServices,
  });

  setSelectedCity(CitiesModel city) {
    selectedCity = city;
    notifyListeners();
  }

  void onGenderChange(String? status) {
    final newGender = GenderTypeExtension.fromType(status);
    if (newGender != null) {
      selectedGender = newGender;
      notifyListeners();
    }
  }

  setSelectedBloodGroup(BloodGroupListModel bloodGroup) {
    selectedBloodGroup = bloodGroup;
    selectedBloodType = selectedBloodGroup!.name;
    notifyListeners();
  }

  Future<void> getRegionSelectedClinics({Function(dynamic)? onSuccess, Function(String)? onError}) async {
    citiesList.clear();
    selectedCity = null;
    notifyListeners();
    final result = await bloodDonationRepo.getAllCities();

    result.fold(
      (failure) async {
        onError!(failure.message);
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          onError!(apiResponse.errorMessage ?? 'An unexpected error occurred');
        } else if (apiResponse.messageStatus == 1) {
          citiesList = apiResponse.data!;
          citiesList.sort((a, b) => a.description!.compareTo(b.description!));
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> getPatientBloodGroupDetails({Function(dynamic)? onSuccess, Function(String)? onError}) async {
    final result = await bloodDonationRepo.getPatientBloodGroupDetails();

    result.fold(
      (failure) async {
        onError!(failure.message);
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          onError!(apiResponse.errorMessage ?? 'An unexpected error occurred');
        } else if (apiResponse.messageStatus == 1) {
          patientBloodGroupDetailsModel = apiResponse.data!;

          CitiesModel citiesModel = CitiesModel();
          citiesModel.iD = getSelectedCityID();
          _selectedHospitalIndex = (citiesModel.iD! - 1);
          citiesModel.description = citiesList[_selectedHospitalIndex].description;
          citiesModel.descriptionN = citiesList[_selectedHospitalIndex].descriptionN;
          selectedCity = citiesModel;
          selectedBloodType = patientBloodGroupDetailsModel.bloodGroup!;
          _selectedBloodTypeIndex = getBloodIndex(selectedBloodType ?? '');

          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  int getSelectedCityID() {
    int cityID = 1;
    for (var element in citiesList) {
      if (element.description == patientBloodGroupDetailsModel.city) {
        cityID = element.iD!;
      }
    }
    return cityID;
  }

  int getBloodIndex(String type) {
    switch (type) {
      case "O+":
        return 0;
      case "O-":
        return 1;
      case "AB+":
        return 2;
      case "AB-":
        return 3;
      case "A+":
        return 4;
      case "A-":
        return 5;
      case "B+":
        return 6;
      case "B-":
        return 7;

      default:
        return 0;
    }
  }

  void onTermAccepted() {
    isTermsAccepted = !isTermsAccepted;
    notifyListeners();
  }

  bool isUserAuthanticated() {
    print("the app state is ${appState.isAuthenticated}");
    if (!appState.isAuthenticated) {
      return false;
    } else {
      return true;
    }
  }

  Future<void> fetchHospitalsList() async {
    // hospitalList.clear();
    notifyListeners();
    final result = await bloodDonationRepo.getBloodDonationProjectsList();

    result.fold(
      (failure) async => await errorHandlerService.handleError(failure: failure),
      (apiResponse) async {
        if (apiResponse.messageStatus == 2) {
        } else if (apiResponse.messageStatus == 1) {
          hospitalList = apiResponse.data!;
          hospitalList.sort((a, b) => a.projectName!.compareTo(b.projectName!));
          notifyListeners();
        }
      },
    );
  }

  Future<void> getFreeBloodDonationSlots({required Map<String, dynamic> request}) async {
    final result = await bloodDonationRepo.getFreeBloodDonationSlots(request: request);

    result.fold(
      (failure) async => await errorHandlerService.handleError(failure: failure),
      (apiResponse) async {
        if (apiResponse.messageStatus == 2) {
        } else if (apiResponse.messageStatus == 1) {
          // TODO: Handle free slots data
          print(apiResponse.data['BD_FreeSlots']);
          notifyListeners();
        }
      },
    );
  }

  bool isLocationEnabled() {
    return appState.userLong != 0.0 && appState.userLong != 0.0;
  }

  setSelectedHospital(BdGetProjectsHaveBdClinic hospital) {
    selectedHospital = hospital;
    notifyListeners();
  }

  Future<bool> validateSelections() async {
    AppState appState = getIt<AppState>();
    if (selectedCity == null) {
      await dialogService.showErrorBottomSheet(
        message: appState.isArabic() ? "اختر المدينة" :"Please choose city",
      );
      return false;
    }

    if (selectedGender == null) {
      await dialogService.showErrorBottomSheet(
        message:  appState.isArabic() ? "اختير الجنس" :"Please choose Gender",
      );
      return false;
    }

    if (selectedBloodType == null) {
      await dialogService.showErrorBottomSheet(
        message: appState.isArabic() ? "اختير فصيلة الدم" :"Please choose Blood Group",
      );
      return false;
    }

    if (!isTermsAccepted) {
      await dialogService.showErrorBottomSheet(
        message:appState.isArabic() ? "يرجى الموافقة على الشروط والأحكام للمتابعة" : "Please accept Terms and Conditions to continue",
      );
      return false;
    }
    return true;
  }

  Future<void> updateBloodGroup() async {
    LoaderBottomSheet.showLoader();
    Map<String, dynamic> payload = {"City": selectedCity?.description, "cityCode": selectedCity?.iD, "Gender": selectedGender?.value, "isDentalAllowedBackend": false};
    await bloodDonationRepo.updateBloodGroup(request: payload);
    await addUserAgreementForBloodDonation();
    LoaderBottomSheet.hideLoader();
    showCommonBottomSheetWithoutHeight(GetIt.instance<NavigationService>().navigatorKey.currentContext!,
        child: Utils.getSuccessWidget(loadingText: "Blood Group Updated Successfully").paddingSymmetrical(0.h, 24.h),
        callBackFunc: () {},
        isFullScreen: false,
        isCloseButtonVisible: false,
        isAutoDismiss: true);
    // dialogService.showSuccessBottomSheetWithoutH(message: "Blood Group Updated Successfully", onOkPressed: () {});
  }

  Future<void> addUserAgreementForBloodDonation() async {
    Map<String, dynamic> payload = {"IsAgreed": true};
    await bloodDonationRepo.addUserAgreementForBloodDonation(request: payload);
  }

  Future<void> getUserAgreementForBloodDonation() async {
    await bloodDonationRepo.getUserAgreementForBloodDonation();
  }

  Future<void> fetchAllData() async {
    LoaderBottomSheet.showLoader(loadingText: "Fetching Data...");
    await getRegionSelectedClinics();
    if (isUserAuthanticated()) {
       // await getPatientBloodGroupDetails();
    }
    LoaderBottomSheet.hideLoader();
  }
}
