import 'dart:convert';
import 'dart:developer';
import 'dart:io';

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_bank_details_model.dart';
import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_model.dart';
import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart';
import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart';
import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart';
import 'package:mc_common_app/models/chat_models/chat_message_model.dart';
import 'package:mc_common_app/models/general_models/enums_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:provider/provider.dart';

class AdVM extends BaseVM {
  final CommonRepo commonRepo;
  final AdsRepo adsRepo;

  final CommonAppServices commonServices;

  AdVM({required this.commonServices, required this.commonRepo, required this.adsRepo});

  AdCreationSteps currentProgressStep = AdCreationSteps.vehicleDetails;

  VehicleDetailsModel? vehicleDetails;

  List<VehicleTypeModel> vehicleTypes = [];
  List<VehicleBrandsModel> vehicleBrands = [];
  List<VehicleModel> vehicleModels = [];
  List<VehicleYearModel> vehicleModelYears = [];
  List<VehicleColorModel> vehicleColors = [];
  List<VehicleConditionModel> vehicleConditions = [];
  List<VehicleCategoryModel> vehicleCategories = [];
  List<VehicleMileageModel> vehicleMileages = [];
  List<VehicleTransmissionModel> vehicleTransmissions = [];
  List<VehicleSellerTypeModel> vehicleSellerTypes = [];
  List<VehiclePartModel> vehicleDamageParts = [];
  List<VehiclePartModel> vehiclePartsSearchResults = [];
  List<VehicleCountryModel> vehicleCountries = [];
  List<VehicleCityModel> vehicleCities = [];
  List<AdsDurationModel> vehicleAdsDurations = [];
  List<SpecialServiceModel> vehicleAdsSpecialServices = [];
  SSCarCheckScheduleModel? ssCarCheckScheduleModel;
  SSPhotoOfficeScheduleModel? ssPhotoScheduleModel;

  String demandAmountError = "";
  String vehicleVinError = "";
  String vehicleTitleError = "";
  String warrantyError = "";
  String vehicleDescError = "";
  String vehicleImageError = "";
  String vehicleDamageImageError = "";
  String adStartDateError = "";
  String damagePartSearchValue = "";
  String adReservePriceError = "";
  String adPhoneNumberError = "";

  // Edit Variables Amir
  bool isAdEditEnabled = false;
  AdDetailsModel? previousAdDetails;

  List<AdDetailsModel> exploreAds = [];
  List<AdDetailsModel> exploreAdsFilteredList = [];
  List<AdDetailsModel> myAdsFilteredList = [];
  List<AdDetailsModel> myAds = [];
  List<AdDetailsModel> myReservedAds = [];
  List<AdDetailsModel> myActiveAdsForHome = [];

  List<VehicleDamageCard> vehicleDamageCards = [];

  void addNewDamagePartCard({required VehicleDamageCard damageCard}) {
    vehicleDamageCards.add(damageCard);
    notifyListeners();
  }

  void clearDamageCards() {
    vehicleDamageCards.clear();
  }

  List<SpecialServiceCard> specialServiceCards = [];

  void addNewSpecialServiceCard({required SpecialServiceCard specialServiceCard}) {
    int index = vehicleAdsSpecialServices.indexWhere((element) => element.name == specialServiceCard.serviceSelectedId!.selectedOption);
    if (index != -1) {
      vehicleAdsSpecialServices[index].isSelected = true;
    }
    specialServiceCards.add(specialServiceCard);
    selectedVehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    adSpecialServiceDate = "";
    notifyListeners();
  }

  void removeSpecialServiceCard(int index) {
    String option = specialServiceCards.elementAt(index).serviceSelectedId!.selectedOption;

    for (var value in vehicleAdsSpecialServices) {
      if (value.name == option) {
        value.isSelected = false;
        break;
      }
    }
    specialServiceCards.removeAt(index);

    notifyListeners();
  }

  void clearSpecialServiceCard() {
    specialServiceCards.clear();
    notifyListeners();
  }

  void onSearchChangedForDamagePart(String text) {
    vehiclePartsSearchResults.clear();
    damagePartSearchValue = text;

    if (text.isEmpty) {
      notifyListeners();
      return;
    }

    for (var damagePartDetail in vehicleDamageParts) {
      if (damagePartDetail.partName!.toLowerCase().contains(text.toLowerCase())) {
        vehiclePartsSearchResults.add(damagePartDetail);

        notifyListeners();
      }
    }
  }

  bool isExploreAdsTapped = true;

  void updateIsExploreAds(bool value) async {
    isExploreAdsTapped = value;

    //To show the Active Ads
    // applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.allAds);
    // applyFilterOnExploreAds(createdByRoleFilter: CreatedByRoleEnum.allAds);
    // if (value) {
    //   await getExploreAds();
    // }
    notifyListeners();
  }

  List<EnumsModel> exploreAdsEnums = [];

  List<EnumsModel> myAdsEnums = [];

  List<FilterListModel> exploreAdsFilterOptions = [];
  List<FilterListModel> myAdsFilterOptions = [];

  populateAdsFilterList() async {
    if (myAdsFilterOptions.isNotEmpty && exploreAdsFilterOptions.isNotEmpty) {
      return;
    }

    if (myAdsEnums.isEmpty) {
      myAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.myAdsFilterEnumId);
    }
    if (exploreAdsEnums.isEmpty) {
      exploreAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.exploreAdsFilterEnumId);
    }

    exploreAdsFilterOptions.clear();
    myAdsFilterOptions.clear();
    for (int i = 0; i < myAdsEnums.length; i++) {
      myAdsFilterOptions.add(FilterListModel(title: myAdsEnums[i].enumValueStr, isSelected: false, id: myAdsEnums[i].enumValue));
    }
    myAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", isSelected: true, id: 0));

    log("myAdsFilterOptions: ${myAdsFilterOptions.last.id}");

    for (int i = 0; i < exploreAdsEnums.length; i++) {
      exploreAdsFilterOptions.add(FilterListModel(title: "${exploreAdsEnums[i].enumValueStr} Ads", isSelected: false, id: exploreAdsEnums[i].enumValue));
    }
    exploreAdsFilterOptions.insert(0, FilterListModel(title: "All Ads", isSelected: true, id: 0));
    notifyListeners();
  }

  applyFilterOnExploreAds({required CreatedByRoleEnum createdByRoleFilter}) async {
    if (exploreAdsFilterOptions.isEmpty) return;
    int index = exploreAdsFilterOptions.indexWhere((element) => element.id.toCreatedByRoleEnum() == createdByRoleFilter);

    for (var value in exploreAdsFilterOptions) {
      value.isSelected = false;
    }
    exploreAdsFilterOptions[index].isSelected = true;
    if (createdByRoleFilter == CreatedByRoleEnum.allAds) {
      getExploreAds();
      return;
    }
    setState(ViewState.busy);
    exploreAdsFilteredList = await getAdsByFilter(createdByRoleEnum: createdByRoleFilter, isMyAds: false);
    setState(ViewState.idle);

    notifyListeners();
  }

  int currentPageForExploreAds = 1;
  int currentPageForMyAds = 1;
  bool isLoadingMore = false;
  bool hasMoreData = true;

  fetchMoreAds() async {}

  Future<List<AdDetailsModel>> getAdsByFilter({AdPostStatus? adPostStatus, required bool isMyAds, CreatedByRoleEnum? createdByRoleEnum}) async {
    return await adsRepo.getAllAds(isMyAds: isMyAds, adPostStatus: adPostStatus, createdByRoleEnum: createdByRoleEnum);
  }

  applyFilterOnMyAds({required AdPostStatus adPostStatusEnum}) async {
    if (myAdsFilterOptions.isEmpty) return;
    int index = myAdsFilterOptions.indexWhere((element) => element.id.toAdPostEnum() == adPostStatusEnum);

    for (var value in myAdsFilterOptions) {
      value.isSelected = false;
    }
    myAdsFilterOptions[index].isSelected = true;

    if (adPostStatusEnum.getIdFromAdPostStatusEnum() == 0) {
      getMyAds();
      return;
    }
    // this means if the filter is reserved ads
    if (adPostStatusEnum == AdPostStatus.reserved) {
      log("reserved: ${myReservedAds.length}");
      myAdsFilteredList = myReservedAds;
      for (var ad in myAdsFilteredList) {
        ad.isReservedByMe = true;
      }
      notifyListeners();
      return;
    }
    setState(ViewState.busy);
    myAdsFilteredList = await getAdsByFilter(adPostStatus: adPostStatusEnum, isMyAds: true);
    setState(ViewState.idle);
    notifyListeners();
  }

  Future<bool> createReserveAd({required int adId, required BuildContext context}) async {
    Utils.showLoading(context);
    GenericRespModel genericRespModel = await adsRepo.createReserveAd(adId: adId);
    if (genericRespModel.messageStatus == null) {
      Utils.hideLoading(context);

      Utils.showToast(genericRespModel.message ?? "Something went wrong!");
      return false;
    }
    Utils.hideLoading(context);
    return true;
  }

  Future<void> getExploreAds() async {
    setState(ViewState.busy);
    exploreAds = await adsRepo.getAllAds(isMyAds: false);
    exploreAdsFilteredList = exploreAds;
    notifyListeners();
    setState(ViewState.idle);
  }

  Future<void> getMyAds() async {
    setState(ViewState.busy);
    myAds = await adsRepo.getAllAds(isMyAds: true);
    myAdsFilteredList = myAds;
    final myActiveAds = myAds.where((element) => element.adPostStatus == AdPostStatus.active).toList();
    myActiveAdsForHome = myActiveAds.length >= 3 ? myActiveAds.take(3).toList() : myActiveAds;
    await getMyReservedAds();
    notifyListeners();
    setState(ViewState.idle);
  }

  Future<List<AdDetailsModel>> getMyReservedAds() async {
    try {
      setState(ViewState.busy);
      myReservedAds = await adsRepo.getMyReservedAds();
      isFetchingLists = false;
      setState(ViewState.idle);
      return myReservedAds;
    } catch (e) {
      logger.e(e.toString());
      setState(ViewState.idle);
      return [];
    }
  }

  Future<void> getVehicleTypes() async {
    vehicleTypes = await commonRepo.getVehicleTypes();
    notifyListeners();
  }

  Future<void> getVehicleAdsDuration() async {
    final countryId = AppState().getUser.data!.userInfo!.countryId;
    vehicleAdsDurations = await adsRepo.getAdsDuration(countryId: countryId);
    notifyListeners();
  }

  Future<void> getVehicleAdsSpecialServices() async {
    vehicleAdsSpecialServices = await adsRepo.getSpecialServices(specialServiceType: 1);
    notifyListeners();
  }

  AdsBankDetailsModel? adsBankDetailsModel;

  Future<void> getAdBankingAccountInfo({required int adId}) async {
    setState(ViewState.busy);
    try {
      adsBankDetailsModel = await adsRepo.getAdBankingAccountInfo(adId: 21);
      setState(ViewState.idle);
    } catch (e) {
      setState(ViewState.idle);
      Utils.showToast(e.toString());
    }
  }

  Future<void> markAdAsSold(BuildContext context, {required int adId}) async {
    Utils.showLoading(context);
    GenericRespModel respModel = await adsRepo.updateAdStatus(adId: adId, adStatusToUpdate: AdPostStatus.sold);

    if (respModel.messageStatus != 1) {
      Utils.hideLoading(context);
      Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
      return;
    }
    Utils.hideLoading(context);
    Utils.showToast(respModel.message ?? LocaleKeys.adMarkedAsSold.tr());
    updateIsExploreAds(false);
    applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.sold); //pending for review
    navigateReplaceWithName(context, AppRoutes.dashboard);
  }

  Future<void> deleteMyAd(BuildContext context, {required int adId}) async {
    Utils.showLoading(context);
    GenericRespModel respModel = await adsRepo.deleteAd(adId: adId);

    if (respModel.messageStatus != 1) {
      Utils.hideLoading(context);
      Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
      return;
    }
    Utils.hideLoading(context);
    Utils.showToast(LocaleKeys.AdDeletedSuccessfully.tr());
    updateIsExploreAds(false);
    applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review
    navigateReplaceWithName(context, AppRoutes.dashboard);
  }

  Future<void> cancelMyAdReservation(BuildContext context, {required int adId, required String reason}) async {
    Utils.showLoading(context);
    GenericRespModel respModel = await adsRepo.cancelMyAdReservation(adId: adId, adsReserveStatus: 11, reason: reason); // 11 is to Cancel Reservation

    if (respModel.messageStatus != 1) {
      Utils.hideLoading(context);
      Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
      return;
    }
    Utils.hideLoading(context);
    Utils.showToast(LocaleKeys.yourReservationCancelled.tr());
    updateIsExploreAds(false);
    applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.active); //pending for review
    navigateReplaceWithName(context, AppRoutes.dashboard);
  }

  Future<void> deactivateTheAd(BuildContext context, {required int adId, String? comment}) async {
    Utils.showLoading(context);
    GenericRespModel respModel = await adsRepo.updateAdStatus(adId: adId, adStatusToUpdate: AdPostStatus.cancelled, comment: comment);

    if (respModel.messageStatus != 1) {
      Utils.hideLoading(context);
      Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
      return;
    }
    Utils.hideLoading(context);
    Utils.showToast(LocaleKeys.adDeactivatedSuccessfully.tr());
    updateDeactivateAdReasonDescription('');
    updateIsExploreAds(false);
    applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.cancelled); //Cacncelled
    navigateReplaceWithName(context, AppRoutes.dashboard);
  }

  bool isFetchingLists = false;
  bool isCountryFetching = false;

  // Future<void> getAllDataBasedOnVehicleTypeId() async {
  //   if (vehicleTypeId.selectedId == -1) {
  //     return;
  //   }
  //   isFetchingLists = true;
  //   notifyListeners();
  //   vehicleModels = await adsRepo.getVehicleModels(vehicleTypeId: vehicleTypeId.selectedId);
  //   vehicleModelYears = await adsRepo.getVehicleModelYears(vehicleTypeId: vehicleTypeId.selectedId);
  //   vehicleColors = await adsRepo.getVehicleColors(vehicleTypeId: vehicleTypeId.selectedId);
  //   vehicleConditions = await adsRepo.getVehicleConditions(vehicleTypeId: vehicleTypeId.selectedId);
  //   vehicleCategories = await adsRepo.getVehicleCategories(vehicleTypeId: vehicleTypeId.selectedId);
  //   vehicleMileages = await adsRepo.getVehicleMileages(vehicleTypeId: vehicleTypeId.selectedId);
  //   vehicleTransmissions = await adsRepo.getVehicleTransmission(vehicleTypeId: vehicleTypeId.selectedId);
  //   vehicleCountries = await adsRepo.getVehicleCountries();
  //   isFetchingLists = false;
  //   notifyListeners();
  // }

  Future<void> getVehicleBrandsByVehicleTypeId({int vehicleIdForEditAd = -1}) async {
    // if (vehicleTypeId.selectedId == -1 || vehicleBrands.isNotEmpty) {
    //   return;
    // }
    isFetchingLists = true;
    notifyListeners();

    vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: vehicleIdForEditAd != -1 ? vehicleIdForEditAd : vehicleTypeId.selectedId);
    isFetchingLists = false;

    notifyListeners();
  }

  Future<void> getVehicleDetailsByVehicleBrandId() async {
    // if (vehicleBrandId.selectedId == -1 || vehicleTypeId.selectedId == -1) {
    //   return;
    // }
    isFetchingLists = true;
    notifyListeners();
    vehicleDetails = await commonRepo.getVehicleDetails(vehicleTypeId: vehicleTypeId.selectedId, vehicleBrandId: vehicleBrandId.selectedId);

    if (vehicleDetails != null) {
      vehicleModels = vehicleDetails!.vehicleModels!;
      vehicleModelYears = vehicleDetails!.vehicleModelYears!;
      vehicleColors = vehicleDetails!.vehicleColors!;
      vehicleConditions = vehicleDetails!.vehicleConditions!;
      vehicleCategories = vehicleDetails!.vehicleCategories!;
      vehicleMileages = vehicleDetails!.vehicleMileages!;
      vehicleSellerTypes = vehicleDetails!.vehicleSellerTypes!;
      vehicleTransmissions = vehicleDetails!.vehicleTransmissions!;
      vehicleCountries = vehicleDetails!.vehicleCountries!;
    }
    isFetchingLists = false;
    notifyListeners();
  }

  String selectionDurationStartDate = "";

  void updateSelectionDurationStartDate(String date) {
    selectionDurationStartDate = date;
    if (selectionDurationStartDate.isNotEmpty) adStartDateError = "";
    notifyListeners();
  }

  String adPhoneNumber = "";

  void updateAdPhoneNumber(String date) {
    adPhoneNumber = date;
    if (adPhoneNumber.isNotEmpty) adPhoneNumberError = "";
    notifyListeners();
  }

  String adPhoneNumberDialCode = "+966";

  void updateAdPhoneNumberDialCode(String date) {
    adPhoneNumberDialCode = date;
    notifyListeners();
  }

  String adReserveAmount = "";

  void updateAdReservePriceAmount(String date) {
    adReserveAmount = date;
    if (adReserveAmount.isNotEmpty) adReservePriceError = "";
    notifyListeners();
  }

  String adSpecialServiceDate = "";

  void updateAdSpecialServiceDate(String date) {
    adSpecialServiceDate = date;
    if (adSpecialServiceDate.isNotEmpty) {
      adStartDateError = "";
    }
    notifyListeners();
  }

  SelectionModel vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleTypeId(SelectionModel id) async {
    vehicleTypeId = id;
    await getVehicleBrandsByVehicleTypeId();
    notifyListeners();
  }

  SelectionModel vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  Future<void> updateSelectionVehicleBrandId(SelectionModel id, {bool isForSearch = false}) async {
    if (isForSearch) {
      VehicleBrandsModel brand = vehicleBrands.firstWhere((element) => element.id == id.selectedId);
      DropValue brandValue = DropValue(brand.id ?? 0, brand.vehicleBrandDescription ?? "", "");
      if (!ifAlreadyExist(list: vehicleBrandsAdSearchHistory, value: brandValue)) {
        addToVehicleBrandsAdSearchHistory(value: brandValue);
      }
      notifyListeners();
      return;
    }
    vehicleBrandId = id;
    await getVehicleDetailsByVehicleBrandId();

    notifyListeners();
  }

  SelectionModel vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleModelId(SelectionModel id) {
    vehicleModelId = id;
    notifyListeners();
  }

  SelectionModel vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleModelYearId(SelectionModel id, {bool isForSearch = false}) {
    if (isForSearch) {
      VehicleYearModel year = vehicleModelYears.firstWhere((element) => element.id == id.selectedId);
      DropValue yearValue = DropValue(year.id ?? 0, year.modelYear ?? "", "");
      if (!ifAlreadyExist(list: vehicleYearAdSearchHistory, value: yearValue)) {
        addToVehicleYearAdSearchHistory(value: yearValue);
      }
      notifyListeners();
      return;
    }
    vehicleModelYearId = id;
    notifyListeners();
  }

  SelectionModel vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleColorId(SelectionModel id) {
    vehicleColorId = id;
    notifyListeners();
  }

  SelectionModel vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleConditionId(SelectionModel id, {bool showSelectionInDropdown = true, bool isForSearch = false}) {
    if (isForSearch) {
      EnumsModel owner = vehicleConditionsEnum.firstWhere((element) => element.enumValue == id.selectedId);
      DropValue ownerValue = DropValue(owner.enumValue, owner.enumValueStr, "");
      if (!ifAlreadyExist(list: vehicleAdConditionSearchHistory, value: ownerValue)) {
        addToVehicleAdConditionSearchHistory(value: ownerValue);
      }
    }
    if (showSelectionInDropdown) {
      vehicleConditionId = id;
    }
    notifyListeners();
  }

  SelectionModel vehicleCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleCategoryId(SelectionModel id) {
    vehicleCategoryId = id;
    notifyListeners();
  }

  SelectionModel vehicleMileageId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleMileageId(SelectionModel id) {
    vehicleMileageId = id;
    notifyListeners();
  }

  String vehicleVin = "";

  void updateVehicleVin(String vin) {
    vehicleVin = vin;
  }

  String warrantyDuration = "";

  void updateVehicleWarrantyDuration(String warranty) {
    warrantyDuration = warranty;
  }

  String vehicleDemandAmount = "";

  void updateVehicleDemandAmount(String amount) {
    vehicleDemandAmount = amount;
  }

  String reservationCancelReason = "";
  String reservationCancelError = "";

  void updateReservationCancelReason(String value) {
    if (value.isNotEmpty) {
      reservationCancelError = "";
    }
    reservationCancelReason = value;
  }

  List<OfferRequestCommentModel> deActivateAdModelList = [
    OfferRequestCommentModel(
      index: 0,
      isSelected: true,
      title: LocaleKeys.vehicleDealOutsideApp.tr(),
    ),
    OfferRequestCommentModel(
      index: 1,
      isSelected: false,
      title: LocaleKeys.changedDesireToSell.tr(),
    ),
    OfferRequestCommentModel(
      index: 2,
      isSelected: false,
      title: LocaleKeys.otherVar.tr(),
    ),
  ];

  OfferRequestCommentModel selectedDeActivateAdCommentModel = OfferRequestCommentModel(
    index: 0,
    isSelected: true,
    title: LocaleKeys.changedMind.tr(),
  );

  void updateSelectionInDeActivateAdModelList(int index) {
    for (var value in deActivateAdModelList) {
      value.isSelected = false;
    }
    selectedDeActivateAdCommentModel = deActivateAdModelList[index];
    log("selectedDeActivateAdCommentModel: ${selectedDeActivateAdCommentModel.index}");
    deActivateAdModelList[index].isSelected = true;
    notifyListeners();
  }

  String deactivateAdReasonDescription = "";
  String deactivateAdReasonDescriptionError = "";

  void updateDeactivateAdReasonDescription(String value) {
    deactivateAdReasonDescription = value;
    if (value.isNotEmpty) {
      deactivateAdReasonDescriptionError = "";
    }
  }

  bool isDeActivateReasonSubmitValidated() {
    if (selectedDeActivateAdCommentModel.index != deActivateAdModelList.length - 1) {
      return true;
    }
    bool isValidated = true;
    if (deactivateAdReasonDescription.isEmpty) {
      deactivateAdReasonDescriptionError = GlobalConsts.descriptionError;
      isValidated = false;
    } else {
      deactivateAdReasonDescriptionError = "";
    }

    notifyListeners();

    return isValidated;
  }

  String completeDealNotesForAdmin = "";

  void updateCompleteDealNotesForAdmin(String value) {
    completeDealNotesForAdmin = value;
  }

  String vehicleTitle = "";

  void updateVehicleTitle(String title) {
    vehicleTitle = title;
  }

  String vehicleDescription = "";

  void updateVehicleDescription(String desc) {
    vehicleDescription = desc;
  }

  SelectionModel vehicleTransmissionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleTransmissionId(SelectionModel id) {
    vehicleTransmissionId = id;
    notifyListeners();
  }

  SelectionModel vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleSellerTypeId(SelectionModel id, {bool needRefresh = true}) {
    vehicleSellerTypeId = id;
    if (needRefresh) {
      notifyListeners();
    }
  }

// SelectionModel vehicleDamagePartId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleDamagePartId(SelectionModel id, int index) {
    vehicleDamageCards[index].partSelectedId = id;
    int partIndex = vehicleDamageParts.indexWhere((element) => element.partName == id.selectedOption);
    if (partIndex != -1) {
      // vehicleDamageParts[partIndex].isSelected = true;
    }
    notifyListeners();
  }

  SelectionModel vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleCountryId(SelectionModel id) async {
    vehicleCountryId = id;
    isCountryFetching = true;
    notifyListeners();
    vehicleCities = await commonRepo.getVehicleCities(countryId: vehicleCountryId.selectedId);
    isCountryFetching = false;
    notifyListeners();
  }

  SelectionModel vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleCityId(SelectionModel id, {bool isForSearch = false}) async {
    if (isForSearch) {
      VehicleCityModel city = vehicleCities.firstWhere((element) => element.id == id.selectedId);
      DropValue cityValue = DropValue(city.id ?? 0, city.cityName ?? "", "");
      if (!ifAlreadyExist(list: vehicleLocationAdSearchHistory, value: cityValue)) {
        addToVehicleLocationAdSearchHistory(value: cityValue);
      }
      notifyListeners();
      return;
    }
    vehicleCityId = id;
    notifyListeners();
  }

  SelectionModel vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateVehicleAdDurationId(SelectionModel id) {
    vehicleAdDurationId = id;
    notifyListeners();
  }

  SelectionModel vehicleExtendAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateVehicleExtendAdDurationId(SelectionModel id) {
    vehicleAdDurationId = id;
    notifyListeners();
  }

  SelectionModel vehicleAdReservableId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateVehicleAdReservableId(SelectionModel id) {
    vehicleAdReservableId = id;
    notifyListeners();
  }

  SelectionModel selectedVehicleAdsSpecialServicesId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectedVehicleAdsSpecialServicesId(SelectionModel id) async {
    selectedVehicleAdsSpecialServicesId = id;
    // isFetchingLists = true;
    // adSSTimeSlots.clear();
    // vehicleAdsPhotoServiceDate = SelectionModel(selectedId: -1, selectedOption: "");
    // vehicleAdsCarCheckServicesDate = SelectionModel(selectedId: -1, selectedOption: "");
    // notifyListeners();
    // if (id.selectedId == 1) {
    //   ssPhotoScheduleModel = await commonRepo.getPhotographyServiceScheduleDetails(lat: 0.0, long: 0.0);
    // } else if (id.selectedId == 3) {
    //   ssCarCheckScheduleModel = await commonRepo.getCarCheckServiceScheduleDetails(lat: 0.0, long: 0.0);
    // } else {}
    // isFetchingLists = false;
    notifyListeners();
  }

  List<TimeSlotModel> adSSTimeSlots = [];
  int? slotSelectedIndex;

  void updateIsSelectedInSlots(int index) {
    for (var value in adSSTimeSlots) {
      value.isSelected = false;
    }
    slotSelectedIndex = index;
    notifyListeners();
    adSSTimeSlots[index].isSelected = true;
  }

  SelectionModel vehicleAdsPhotoServiceDate = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateVehicleVehicleAdsPhotoServiceDate(SelectionModel id) {
    vehicleAdsPhotoServiceDate = id;

    adSSTimeSlots.clear();
    slotSelectedIndex = null;

    for (var value in ssPhotoScheduleModel!.photoOfficeScheduleSlots!) {
      if (value.slotDate!.toFormattedDateWithoutTime() == vehicleAdsPhotoServiceDate.selectedOption) {
        adSSTimeSlots.add(TimeSlotModel(slot: value.startTime!, isSelected: false, slotId: value.id!));
      }
    }
    notifyListeners();
  }

  SelectionModel vehicleAdsCarCheckServicesDate = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateVehicleAdsCarCheckServicesDate(SelectionModel id) {
    vehicleAdsCarCheckServicesDate = id;

    adSSTimeSlots.clear();
    slotSelectedIndex = null;

    for (var value in ssCarCheckScheduleModel!.branchScheduleSlots!) {
      if (value.slotDate!.toFormattedDateWithoutTime() == vehicleAdsCarCheckServicesDate.selectedOption) {
        adSSTimeSlots.add(TimeSlotModel(slot: value.startTime!, isSelected: false, slotId: value.id!));
      }
    }
    notifyListeners();
  }

  String selectedTimeSlotForEngineCarCheck = "";

  void updateSelectedTimeSlotForEngineCarCheck(String timeSlot) {
    selectedTimeSlotForEngineCarCheck = timeSlot;
    notifyListeners();
  }

  bool isPresentInThisList({required List list, required String item}) {
    bool isPresent = false;

    for (var element in list) {
      if (element == item) {
        isPresent = true;
        break;
      }
    }

    return isPresent;
  }

  List<DropValue> populateScheduleDatesForAdPhotoService() {
    List<DropValue> vehicleAdsSpecialServiceDates = [];

    List<String> slotDates = [];

    if (ssPhotoScheduleModel!.photoOfficeScheduleSlots == null) {
      return [];
    }
    for (var element in ssPhotoScheduleModel!.photoOfficeScheduleSlots!) {
      if (!slotDates.contains(element.slotDate!)) {
        slotDates.add(element.slotDate!);
        vehicleAdsSpecialServiceDates.add(DropValue(element.id!.toInt(), element.slotDate!.toFormattedDateWithoutTime(), ""));
      }
    }

    return vehicleAdsSpecialServiceDates;
  }

  List<DropValue> populateScheduleDatesForAdCarCheckService() {
    List<DropValue> vehicleAdsSpecialServiceDates = [];

    List<String> slotDates = [];

    if (ssCarCheckScheduleModel!.branchScheduleSlots == null) {
      return [];
    }
    for (var element in ssCarCheckScheduleModel!.branchScheduleSlots!) {
      if (!slotDates.contains(element.slotDate!)) {
        slotDates.add(element.slotDate!);
        vehicleAdsSpecialServiceDates.add(DropValue(element.id!.toInt(), element.slotDate!.toFormattedDateWithoutTime(), ""));
      }
    }

    return vehicleAdsSpecialServiceDates;
  }

  bool isVehicleDetailsValidated() {
    bool isValidated = true;
    if (vehicleTypeId.selectedId == -1) {
      vehicleTypeId.errorValue = LocaleKeys.vehicle_selectVehicleType.tr();
      isValidated = false;
      notifyListeners();
      return isValidated;
    } else {
      vehicleTypeId.errorValue = "";
    }
    if (vehicleModelId.selectedId == -1) {
      vehicleModelId.errorValue = LocaleKeys.vehicle_selectVehicleModel.tr();
      isValidated = false;
    } else {
      vehicleModelId.errorValue = "";
    }

    if (vehicleModelYearId.selectedId == -1) {
      vehicleModelYearId.errorValue = LocaleKeys.vehicle_selectVehicleModelYear.tr();
      isValidated = false;
    } else {
      vehicleModelYearId.errorValue = "";
    }

    if (vehicleColorId.selectedId == -1) {
      vehicleColorId.errorValue = LocaleKeys.vehicle_selectVehicleColor.tr();
      isValidated = false;
    } else {
      vehicleColorId.errorValue = "";
    }

    if (vehicleConditionId.selectedId == -1) {
      vehicleConditionId.errorValue = LocaleKeys.vehicle_vehicleCondition.tr();
      isValidated = false;
    } else {
      vehicleConditionId.errorValue = "";
    }

    if (vehicleCategoryId.selectedId == -1) {
      vehicleCategoryId.errorValue = LocaleKeys.vehicle_vehicleCategory.tr();
      isValidated = false;
    } else {
      vehicleCategoryId.errorValue = "";
    }

    if (vehicleMileageId.selectedId == -1) {
      vehicleMileageId.errorValue = LocaleKeys.vehicle_vehicleMileage.tr();
      isValidated = false;
    } else {
      vehicleMileageId.errorValue = "";
    }

    if (vehicleTransmissionId.selectedId == -1) {
      vehicleTransmissionId.errorValue = LocaleKeys.vehicle_vehicleTransmission.tr();
      isValidated = false;
    } else {
      vehicleTransmissionId.errorValue = "";
    }

    // if (vehicleSellerTypeId.selectedId == -1) {
    //   vehicleSellerTypeId.errorValue = LocaleKeys.vehicle_vehicleSellerType.tr();
    //   isValidated = false;
    // } else {
    //   vehicleSellerTypeId.errorValue = "";
    // }

    if (vehicleCountryId.selectedId == -1) {
      vehicleCountryId.errorValue = LocaleKeys.vehicle_selectAny.tr();
      isValidated = false;
    } else {
      vehicleCountryId.errorValue = "";
    }

    if (vehicleCityId.selectedId != -1 && vehicleCityId.selectedId == -1) {
      vehicleCityId.errorValue = LocaleKeys.vehicle_vehicleCity.tr();
      isValidated = false;
    } else {
      vehicleCityId.errorValue = "";
    }

    if (vehicleDemandAmount.isEmpty) {
      demandAmountError = GlobalConsts.demandAmountError;
      isValidated = false;
    } else {
      demandAmountError = "";
    }
    if (vehicleVin.isEmpty) {
      vehicleVinError = GlobalConsts.vehicleVinError;
      isValidated = false;
    } else {
      vehicleVinError = "";
    }
    if (vehicleTitle.isEmpty) {
      vehicleTitleError = GlobalConsts.vehicleTitleError;
      isValidated = false;
    } else {
      vehicleTitleError = "";
    }
    if (warrantyDuration.isEmpty) {
      warrantyError = GlobalConsts.warrantyError;
      isValidated = false;
    } else {
      warrantyError = "";
    }
    if (vehicleDescription.isEmpty) {
      vehicleDescError = GlobalConsts.vehicleDescError;
      isValidated = false;
    } else {
      vehicleDescError = "";
    }
    if ((pickedPostingImages.isEmpty || pickedPostingImages.length < 3) && !isAdEditEnabled) {
      vehicleImageError = GlobalConsts.attachImageError;
      isValidated = false;
    } else {
      vehicleImageError = "";
    }

    notifyListeners();
    return isValidated;
  }

  bool validateReservationCancelReason() {
    bool isValidated = true;

    if (reservationCancelReason.isEmpty) {
      reservationCancelError = GlobalConsts.reservationCancelError;
      isValidated = false;
      notifyListeners();
    }
    return isValidated;
  }

  bool isDamagePartsValidated() {
    bool isValidated = true;

    for (var element in vehicleDamageCards) {
      if (element.partSelectedId!.selectedId == -1) {
        element.partSelectedId!.errorValue = LocaleKeys.vehicle_vehiclePart.tr();
        isValidated = false;
      } else {
        element.partSelectedId!.errorValue = "";
        element.partSelectedId!.errorValue = "";
      }
    }

    for (var element in vehicleDamageCards) {
      if (element.partImages == null || element.partImages!.isEmpty) {
        element.partImageErrorValue = GlobalConsts.attachDamagePartImage;
        isValidated = false;
      } else {
        element.partImageErrorValue = "";
      }
    }

    // if (pickedDamageImages.isEmpty || pickedDamageImages.length < 3) {
    //   vehicleDamageImageError = GlobalConsts.attachImageError;
    //   isValidated = false;
    // } else {
    //   vehicleDamageImageError = "";
    // }

    notifyListeners();
    return isValidated;
  }

  bool isAdDurationValidated() {
    bool isValidated = true;
    if (AppState().userType != UserType.providerDealer && vehicleAdDurationId.selectedId == -1) {
      vehicleAdDurationId.errorValue = LocaleKeys.vehicle_vehiclePart.tr();
      isValidated = false;
    } else {
      vehicleAdDurationId.errorValue = "";
    }

    if (selectionDurationStartDate.isEmpty) {
      adStartDateError = GlobalConsts.adDurationDateError;
      isValidated = false;
    } else {
      adStartDateError = "";
    }

    if (isPhoneNumberShown && adPhoneNumber.isEmpty) {
      adPhoneNumberError = GlobalConsts.adDurationPhoneNumberError;
      isValidated = false;
    } else {
      adPhoneNumberError = "";
    }
    //
    // if (vehicleAdReservableId.selectedId == -1) {
    //   vehicleAdReservableId.errorValue = "Please select if the Ad is Reservable or not.";
    //   isValidated = false;
    // } else {
    //   vehicleAdReservableId.errorValue = "";
    // }
    //
    // if (adReserveAmount.isEmpty) {
    //   adReservePriceError = GlobalConsts.adReservablePriceErrorConst;
    //   isValidated = false;
    // } else {
    //   adStartDateError = "";
    // }

    notifyListeners();
    return isValidated;
  }

  void onBackButtonPressed(BuildContext context) {
    switch (currentProgressStep) {
      case AdCreationSteps.vehicleDetails:
        resetValues();
        pop(context);
        break;
      case AdCreationSteps.damageParts:
        currentProgressStep = AdCreationSteps.vehicleDetails;
        notifyListeners();
        break;
      case AdCreationSteps.adDuration:
        currentProgressStep = AdCreationSteps.damageParts;
        notifyListeners();
        break;
      case AdCreationSteps.reviewAd:
        currentProgressStep = AdCreationSteps.adDuration;
        notifyListeners();
        break;
    }
  }

  void updateCurrentStep(BuildContext context) async {
    switch (currentProgressStep) {
      case AdCreationSteps.vehicleDetails:
        if (isVehicleDetailsValidated()) {
          currentProgressStep = AdCreationSteps.damageParts;
          getVehicleDamagePartsList();
          notifyListeners();
        }
        break;
      case AdCreationSteps.damageParts:
        if (isDamagePartsValidated()) {
          currentProgressStep = AdCreationSteps.adDuration;
          if (vehicleAdsDurations.isEmpty) {
            getVehicleAdsDuration();
          }

          if (vehicleAdsSpecialServices.isEmpty) {
            getVehicleAdsSpecialServices();
          }

          notifyListeners();
        }
        break;
      case AdCreationSteps.adDuration:
        if (isAdDurationValidated()) {
          currentProgressStep = AdCreationSteps.reviewAd;
          notifyListeners();
        }
        break;
      case AdCreationSteps.reviewAd:
        Utils.showLoading(context);
        try {
          int status = await createNewAd();
          if (status != 1) {
            Utils.hideLoading(context);
            return;
          }
          isAdEditEnabled = false;
          Utils.hideLoading(context);
          currentProgressStep = AdCreationSteps.vehicleDetails;
          resetValues();
          updateIsExploreAds(false);
          applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.pendingForReview); //pending for review
          navigateReplaceWithName(context, AppRoutes.dashboard, arguments: DashboardRouteEnum.fromAdsSubmit);
        } catch (e) {
          Utils.hideLoading(context);
          Utils.showToast("Error: ${e.toString()}");
        }

        break;
    }
  }

  bool financeAvailableStatus = false;

  void updateFinanceAvailableStatus(bool status) {
    financeAvailableStatus = status;
    notifyListeners();
  }

  bool isPhoneNumberShown = false;

  void updateIsPhoneNumberShownStatus(bool status) {
    isPhoneNumberShown = status;
    notifyListeners();
  }

  bool isNumberOnWhatsApp = false;

  void updateIsNumberOnWhatsAppStatus(bool status) {
    isNumberOnWhatsApp = status;
    notifyListeners();
  }

  List<ImageModel> pickedPostingImages = [];

  void removeImageFromList(String filePath) {
    int index = pickedPostingImages.indexWhere((element) => element.filePath == filePath);
    if (index == -1) {
      return;
    }
    pickedPostingImages.removeAt(index);
    notifyListeners();
  }

  void pickMultipleImages() async {
    List<ImageModel> imageModels = [];
    List<File> images = await commonServices.pickMultipleImages();

    for (var element in images) {
      imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
    }
    pickedPostingImages.addAll(imageModels);
    if (pickedPostingImages.isNotEmpty) vehicleImageError = "";
    notifyListeners();
  }

  List<ImageModel> pickedReceiptPdfFiles = [];

  String receiptPdfFileError = "";

  void removePdfFileFromList(String filePath) {
    int index = pickedReceiptPdfFiles.indexWhere((element) => element.filePath == filePath);
    if (index == -1) {
      return;
    }
    pickedReceiptPdfFiles.removeAt(index);
    notifyListeners();
  }

  void pickPdfReceiptFile(BuildContext context) async {
    List<ImageModel> imageModels = [];
    List<File>? files = await commonServices.pickMultipleFiles(context);
    if (files == null) return;
    for (var element in files) {
      imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
    }
    pickedReceiptPdfFiles.addAll(imageModels);
    if (pickedReceiptPdfFiles.isNotEmpty) receiptPdfFileError = "";
    notifyListeners();
  }

// sourceFlag for Camera = 0
// sourceFlag for Gallery = 1
  void pickDamagePartImage(int index) async {
    List<ImageModel> imageModels = [];
    List<File> images = await commonServices.pickMultipleImages();
    for (var element in images) {
      imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
    }
    if (images.isNotEmpty) {
      if (vehicleDamageCards[index].partImages == null) {
        vehicleDamageCards[index].partImages = imageModels;
      } else {
        vehicleDamageCards[index].partImages!.addAll(imageModels);
      }
      vehicleDamageCards[index].partImageErrorValue = "";
      notifyListeners();
    }
  }

  List<File> pickedDamageImages = [];

  void removeDamageImageFromList(String filePath) {
    int index = pickedDamageImages.indexWhere((element) => element.path == filePath);
    if (index == -1) {
      return;
    }
    pickedDamageImages.removeAt(index);
    notifyListeners();
  }

  void removeDamagePartCard(int index) {
    String option = vehicleDamageCards.elementAt(index).partSelectedId!.selectedOption;

    for (var value in vehicleDamageParts) {
      if (value.partName == option) {
        value.isSelected = false;
        break;
      }
    }
    vehicleDamageCards.removeAt(index);

    notifyListeners();
  }

  void updateDamagePartDescription(int index, String value) {
    vehicleDamageCards[index].damagePartDescription = value;
    notifyListeners();
  }

  void removeDamageImageFromCard(int imageIndex, String filePath, int cardIndex) {
    VehicleDamageCard card = vehicleDamageCards.elementAt(cardIndex);
    if (card.partImages == null) return;
    int index = card.partImages!.indexWhere((element) => element.filePath == filePath);
    if (index == -1) {
      return;
    }
    vehicleDamageCards[cardIndex].partImages!.removeAt(index);
    notifyListeners();
  }

  void pickMultipleDamageImages() async {
    List<File> images = await commonServices.pickMultipleImages();
    pickedDamageImages.addAll(images);
    if (pickedDamageImages.isNotEmpty) vehicleDamageImageError = "";
    notifyListeners();
  }

  void resetValues() {
    pickedDamageImages.clear();
    pickedPostingImages.clear();
    vehicleDamageCards.clear();
    specialServiceCards.clear();
    vehicleAdsSpecialServices.clear();
    currentProgressStep = AdCreationSteps.vehicleDetails;
    vehicleTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleModelId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    // vehicleAdDurationId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleColorId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleConditionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleMileageId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleTransmissionId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleSellerTypeId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleCountryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleDemandAmount = "";
    vehicleVin = "";
    vehicleTitle = "";
    warrantyDuration = "";
    vehicleDescription = "";
    selectionDurationStartDate = "";
    isPhoneNumberShown = false;
    isNumberOnWhatsApp = false;
    adPhoneNumberDialCode = "";
    adPhoneNumber = "";
    clearSpecialServiceCard();
    updateFinanceAvailableStatus(false);
    notifyListeners();
  }

  Future<void> getVehicleDamagePartsList() async {
    vehicleDamageParts = await commonRepo.getVehicleDamageParts();

    notifyListeners();
  }

  resetSpecialServiceBottomSheet() {
    photoOfficeSelectedId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel();
    selectedPhotoOfficeSlotDateTime = null;
    photoSSSchedulesByOffices = [];
  }

  SelectionModel photoOfficeSelectedId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updatePhotoOfficeSelectedId(SelectionModel id) {
    photoOfficeSelectedId = id;
    selectedPhotoSSSchedulesByOffice = photoSSSchedulesByOffices.elementAt(int.parse(id.itemPrice));
    notifyListeners();
  }

  updateSelectedPhotoOfficeAppointmentDate({required int dateIndex}) {
    for (var element in selectedPhotoSSSchedulesByOffice.customTimeDateSlotList!) {
      element.date!.isSelected = false;
      for (var element in element.availableSlots!) {
        element.isSelected = false;
      }
    }

    selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.isSelected = true;
    selectedPhotoSSSchedulesByOffice.selectedDateIndex = dateIndex;
    final date = TimeSlotModel(
      date: selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.date,
      slotId: selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![dateIndex].date!.slotId,
      isSelected: true,
      slot: "",
    );
    selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel = CustomTimeDateSlotModel(date: date);
    notifyListeners();
  }

  int? selectedPhotoOfficeSlotDateTime;

  updateSelectedAppointmentSlotByDate({required int slotIndex}) {
    for (var element in selectedPhotoSSSchedulesByOffice.customTimeDateSlotList!) {
      for (var element in element.availableSlots!) {
        element.isSelected = false;
      }
    }
    int index = selectedPhotoSSSchedulesByOffice.selectedDateIndex!;
    selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots![slotIndex].isSelected = true;
    selectedPhotoOfficeSlotDateTime = selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots![slotIndex].slotId;
    selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots = selectedPhotoSSSchedulesByOffice.customTimeDateSlotList![index].availableSlots!;
    notifyListeners();
  }

  List<SSPhotoOfficeScheduleModel> photoSSSchedulesByOffices = [];
  SSPhotoOfficeScheduleModel selectedPhotoSSSchedulesByOffice = SSPhotoOfficeScheduleModel();

  Future<void> getPhotographyServiceScheduleListByOffices({required double latitude, required double longitude, bool isNeedToRebuild = false}) async {
    if (isNeedToRebuild) setState(ViewState.busy);

    int cityID = AppState().getUser.data!.userInfo!.cityId ?? 1;
    try {
      photoSSSchedulesByOffices = await commonRepo.getPhotographyServiceScheduleListByOffices(lat: latitude, long: longitude, cityID: cityID);
      if (isNeedToRebuild) setState(ViewState.idle);
    } catch (e) {
      if (isNeedToRebuild) setState(ViewState.idle);
      Utils.showToast("Error: ${e.toString()}");
    }
  }

  // Future<void> getCarCheckServiceScheduleListByOffices({required double latitude, required double longitude, bool isNeedToRebuild = false}) async {
  //   if (isNeedToRebuild) setState(ViewState.busy);
  //
  //   try {
  //     photoSSSchedulesByOffices = await commonRepo.getCarCheckServiceScheduleDetails(lat: latitude, long: longitude);
  //     if (isNeedToRebuild) setState(ViewState.idle);
  //   } catch (e) {
  //     if (isNeedToRebuild) setState(ViewState.idle);
  //     Utils.showToast("Error: ${e.toString()}");
  //   }
  // }

  Future<void> onAdSSBookAppointmentPressed(BuildContext context, {required AdDetailsModel adDetailsModel, required int adsSpecialServiceID}) async {
    bool isValidated = false;

    if (selectedPhotoSSSchedulesByOffice.photoOfficeID == null) {
      isValidated = false;
    } else if (selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel == null || !selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.date!.isSelected) {
      isValidated = false;
    } else {
      if (selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots == null) {
        isValidated = false;
      } else {
        TimeSlotModel slot = selectedPhotoSSSchedulesByOffice.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected);
        if (slot.date.isNotEmpty) {
          isValidated = true;
        }
      }
    }
    if (!isValidated) {
      Utils.showToast(LocaleKeys.selectAppointmentTimeService.tr());
      return;
    }
    Utils.showLoading(context);
    try {
      GenericRespModel genericRespModel = await adsRepo.createAppointmentForAdSpecialService(
        adId: adDetailsModel.id ?? 0,
        photoOfficeID: photoOfficeSelectedId.selectedId,
        photoOfficeSlotID: selectedPhotoOfficeSlotDateTime ?? 0,
        adsSpecialServiceID: adsSpecialServiceID,
      );

      Utils.hideLoading(context);
      if (genericRespModel.messageStatus != 1) {
        Utils.showToast("${LocaleKeys.error.tr()}: ${genericRespModel.message}");
      } else {
        resetSpecialServiceBottomSheet();
        navigateWithName(context, AppRoutes.paymentMethodsView, arguments: PaymentTypes.ads);
      }
    } catch (e) {
      Utils.hideLoading(context);
      Utils.showToast("${LocaleKeys.error.tr()}: ${e.toString()}");
    }
  }

  Future<int> createNewAd() async {
    AppState appState = injector.get<AppState>();
    List<int> adsSelectedServices = [];

    for (var value in specialServiceCards) {
      adsSelectedServices.add(value.serviceSelectedId!.selectedId);
    }
    Ads ads = Ads(
      id: isAdEditEnabled ? previousAdDetails!.id : null,
      adsDurationID: vehicleAdDurationId.selectedId == -1 ? 0 : vehicleAdDurationId.selectedId,
      startDate: selectionDurationStartDate,
      countryId: vehicleCountryId.selectedId,
      specialServiceIDs: adsSelectedServices,
    );
    List<VehiclePostingImages> vehicleImages = [];

    for (var image in pickedPostingImages) {
      vehicleImages.add(await convertFileToVehiclePostingImages(imageModel: image));
    }

    List<VehiclePostingDamageParts> vehicleDamageImages = [];

    for (var card in vehicleDamageCards) {
      if (card.partImages != null && card.partImages!.isNotEmpty) {
        for (var image in card.partImages!) {
          VehiclePostingDamageParts stringImage = await convertFileToVehiclePostingDamageParts(
            imageModel: image,
            damagePartId: card.partSelectedId!.selectedId,
            commentParam: card.damagePartDescription ?? "",
          );
          vehicleDamageImages.add(stringImage);
        }
      }
    }

    VehiclePosting vehiclePosting = VehiclePosting(
      id: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
      userID: appState.getUser.data!.userInfo!.userId,
      vehicleType: vehicleTypeId.selectedId,
      vehicleModelID: vehicleModelId.selectedId,
      vehicleModelYearID: vehicleModelYearId.selectedId,
      vehicleColorID: vehicleColorId.selectedId,
      vehicleCategoryID: vehicleCategoryId.selectedId,
      vehicleConditionID: vehicleConditionId.selectedId,
      vehicleMileageID: vehicleMileageId.selectedId,
      vehicleTransmissionID: vehicleTransmissionId.selectedId,
      vehicleSellerTypeID: vehicleSellerTypeId.selectedId == -1 ? 1 : vehicleSellerTypeId.selectedId,
      cityID: vehicleCityId.selectedId,
      price: int.parse(vehicleDemandAmount),
      vehicleVIN: vehicleVin,
      vehicleDescription: vehicleDescription,
      vehicleTitle: vehicleTitle,
      vehicleDescriptionN: vehicleDescription,
      isFinanceAvailable: financeAvailableStatus,
      warantyYears: int.parse(warrantyDuration),
      demandAmount: int.parse(vehicleDemandAmount),
      vehiclePostingImages: vehicleImages,
      vehiclePostingDamageParts: vehicleDamageImages,
      phoneNo: isPhoneNumberShown ? adPhoneNumberDialCode + adPhoneNumber : null,
      whatsAppNo: (isPhoneNumberShown && isNumberOnWhatsApp) ? adPhoneNumberDialCode + adPhoneNumber : null,
    );

    AdsCreationPayloadModel adsCreationPayloadModel = AdsCreationPayloadModel(ads: ads, vehiclePosting: vehiclePosting);
    GenericRespModel respModel = await adsRepo.createOrUpdateAd(adsCreationPayloadModel: adsCreationPayloadModel, isCreateNew: !isAdEditEnabled);

    Utils.showToast(respModel.message.toString());

    return Future.value(respModel.messageStatus);
  }

  Future<VehiclePostingImages> convertFileToVehiclePostingImages({required ImageModel imageModel}) async {
    VehiclePostingImages vehiclePostingImages;
    if (imageModel.isFromNetwork ?? false) {
      vehiclePostingImages = VehiclePostingImages(
        id: imageModel.id,
        imageUrl: imageModel.filePath,
      );
    } else {
      File file = File(imageModel.filePath!);
      List<int> imageBytes = await file.readAsBytes();
      String image = base64Encode(imageBytes);
      String fileName = file.path.split('/').last;
      vehiclePostingImages = VehiclePostingImages(
        imageName: fileName,
        imageStr: image,
        imageUrl: file.path,
        vehiclePostingID: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
      );
    }

    return vehiclePostingImages;
  }

  Future<VehiclePostingDamageParts> convertFileToVehiclePostingDamageParts({required ImageModel imageModel, required int damagePartId, required String commentParam}) async {
    VehiclePostingDamageParts vehiclePostingDamageParts;

    if (imageModel.isFromNetwork ?? false) {
      vehiclePostingDamageParts = VehiclePostingDamageParts(
        id: imageModel.id,
        vehicleDamagePartID: damagePartId,
        imageUrl: imageModel.filePath,
        comment: commentParam,
        vehiclePostingID: isAdEditEnabled ? previousAdDetails!.vehiclePostingID : null,
      );
    } else {
      File file = File(imageModel.filePath!);
      List<int> imageBytes = await file.readAsBytes();
      String image = base64Encode(imageBytes);
      vehiclePostingDamageParts = VehiclePostingDamageParts(vehicleImageBase64: image, vehicleDamagePartID: damagePartId, imageUrl: file.path, comment: commentParam);
    }

    return vehiclePostingDamageParts;
  }

// ************ ADS SEARCH VIEW ****************

  List<EnumsModel> vehicleConditionsEnum = [];

  Future<void> populateDataForAdFilter() async {
    setState(ViewState.busy);

    if (vehicleConditionsEnum.isEmpty) {
      vehicleConditionsEnum = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.conditionEnumId);
    }

    if (vehicleBrands.isEmpty) {
      vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: -1);
    }
    if (vehicleModelYears.isEmpty) {
      vehicleModelYears = await commonRepo.getVehicleModelYears(vehicleTypeId: -1);
    }
    vehicleCities = await commonRepo.getVehicleCities(countryId: -1); // fetch all the cities
    setState(ViewState.idle);
  }

  ifAlreadyExist({required List<DropValue> list, required DropValue value}) {
    int index = list.indexWhere((element) {
      return element.id == value.id;
    });

    if (index != -1) {
      return true;
    }

    return false;
  }

  //BRANDS
  List<DropValue> vehicleBrandsAdSearchHistory = [];

  void removeVehicleBrandsAdSearchHistory({bool isClear = false, required int index}) {
    if (isClear) {
      vehicleBrandsAdSearchHistory.clear();
      notifyListeners();
      return;
    }
    vehicleBrandsAdSearchHistory.removeAt(index);
    if (vehicleBrandsAdSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter - 1);
    }
    notifyListeners();
  }

  void addToVehicleBrandsAdSearchHistory({required DropValue value}) {
    if (vehicleBrandsAdSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter + 1);
    }
    vehicleBrandsAdSearchHistory.add(value);
    notifyListeners();
  }

  // LOCATION
  List<DropValue> vehicleLocationAdSearchHistory = [];

  void removeVehicleLocationAdSearchHistory({bool isClear = false, required int index}) {
    if (isClear) {
      vehicleLocationAdSearchHistory.clear();
      notifyListeners();
      return;
    }
    vehicleLocationAdSearchHistory.removeAt(index);
    if (vehicleLocationAdSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter - 1);
    }
    notifyListeners();
  }

  void addToVehicleLocationAdSearchHistory({required DropValue value}) {
    if (vehicleLocationAdSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter + 1);
    }
    vehicleLocationAdSearchHistory.add(value);
    notifyListeners();
  }

  // OWNER

  SelectionModel vehicleOwnerId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");

  void updateSelectionVehicleAdOwnerId(SelectionModel id, {bool isForSearch = false}) {
    if (isForSearch) {
      EnumsModel owner = exploreAdsEnums.firstWhere((element) => element.enumValue == id.selectedId);
      DropValue ownerValue = DropValue(owner.enumValue, "${owner.enumValueStr} Ads", "");
      if (!ifAlreadyExist(list: vehicleAdOwnerSearchHistory, value: ownerValue)) {
        addToVehicleAdOwnerSearchHistory(value: ownerValue);
      }
      notifyListeners();
      return;
    }
    vehicleOwnerId = id;
    notifyListeners();
  }

  List<DropValue> vehicleAdOwnerSearchHistory = [];

  void removeVehicleAdOwnerSearchHistory({bool isClear = false, required int index}) {
    if (isClear) {
      vehicleAdOwnerSearchHistory.clear();
      notifyListeners();
      return;
    }
    vehicleAdOwnerSearchHistory.removeAt(index);
    if (vehicleAdOwnerSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter - 1);
    }
    notifyListeners();
  }

  void addToVehicleAdOwnerSearchHistory({required DropValue value}) {
    if (vehicleAdOwnerSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter + 1);
    }
    vehicleAdOwnerSearchHistory.add(value);
    notifyListeners();
  }

  // YEAR
  List<DropValue> vehicleYearAdSearchHistory = [];

  void removeVehicleYearAdSearchHistory({bool isClear = false, required int index}) {
    if (isClear) {
      vehicleYearAdSearchHistory.clear();
      notifyListeners();
      return;
    }
    vehicleYearAdSearchHistory.removeAt(index);
    if (vehicleYearAdSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter - 1);
    }
    notifyListeners();
  }

  void addToVehicleYearAdSearchHistory({required DropValue value}) {
    if (vehicleYearAdSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter + 1);
    }
    vehicleYearAdSearchHistory.add(value);
    notifyListeners();
  }

  // Created Date

  List<DropValue> vehicleAdCreatedDateSearchHistory = [];

  void removeVehicleAdCreatedDateSearchHistory({bool isClear = false, required int index}) {
    if (isClear) {
      vehicleAdCreatedDateSearchHistory.clear();
      notifyListeners();
      return;
    }
    vehicleAdCreatedDateSearchHistory.removeAt(index);
    if (vehicleAdCreatedDateSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter - 1);
    }
    notifyListeners();
  }

  void addToVehicleAdCreatedDateSearchHistory({required DropValue value}) {
    if (vehicleAdCreatedDateSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter + 1);
    }
    if (vehicleAdCreatedDateSearchHistory.isEmpty) {
      vehicleAdCreatedDateSearchHistory.add(value);
    } else {
      vehicleAdCreatedDateSearchHistory.first = value;
    }

    notifyListeners();
  }

// Ad Condition
  List<DropValue> vehicleAdConditionSearchHistory = [];

  void removeVehicleAdConditionSearchHistory({bool isClear = false, required int index}) {
    if (isClear) {
      vehicleAdConditionSearchHistory.clear();
      notifyListeners();
      return;
    }
    vehicleAdConditionSearchHistory.removeAt(index);
    if (vehicleAdConditionSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter - 1);
    }
    notifyListeners();
  }

  void addToVehicleAdConditionSearchHistory({required DropValue value}) {
    if (vehicleAdConditionSearchHistory.isEmpty) {
      updateAdsFiltersCounter(adsFiltersCounter + 1);
    }
    vehicleAdConditionSearchHistory.add(value);
    notifyListeners();
  }

  int adsFiltersCounter = 0;

  updateAdsFiltersCounter(int value) {
    adsFiltersCounter = value;
    notifyListeners();
  }

  void clearAdsFilters() {
    vehicleBrandsAdSearchHistory.clear();
    vehicleAdOwnerSearchHistory.clear();
    vehicleLocationAdSearchHistory.clear();
    vehicleYearAdSearchHistory.clear();
    vehicleAdCreatedDateSearchHistory.clear();
    vehicleAdConditionSearchHistory.clear();
    adsFiltersCounter = 0;
    getExploreAds();
    notifyListeners();
  }

  void clearAdFilterSelections() {
    vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
    vehicleOwnerId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
  }

  Future<void> getAdsBasedOnFilters() async {
    exploreAdsFilteredList.clear();
    setState(ViewState.busy);
    List<String> cityIdsList = [];
    if (vehicleLocationAdSearchHistory.isNotEmpty) {
      for (var element in vehicleLocationAdSearchHistory) {
        cityIdsList.add(element.id.toString());
      }
    }
    List<String> brandsIdsList = [];
    if (vehicleBrandsAdSearchHistory.isNotEmpty) {
      for (var element in vehicleBrandsAdSearchHistory) {
        brandsIdsList.add(element.id.toString());
      }
    }

    List<String> vehicleYearIdsList = [];
    if (vehicleYearAdSearchHistory.isNotEmpty) {
      for (var element in vehicleYearAdSearchHistory) {
        vehicleYearIdsList.add(element.id.toString());
      }
    }

    List<String> adOwnerIdsList = [];
    if (vehicleAdOwnerSearchHistory.isNotEmpty) {
      for (var element in vehicleAdOwnerSearchHistory) {
        adOwnerIdsList.add(element.id.toString());
      }
    }

    List<String> conditionsIdsList = [];
    if (vehicleAdConditionSearchHistory.isNotEmpty) {
      for (var element in vehicleAdConditionSearchHistory) {
        conditionsIdsList.add(element.id.toString());
      }
    }

    List<String> createdDatesList = [];
    if (vehicleAdCreatedDateSearchHistory.isNotEmpty) {
      for (var element in vehicleAdCreatedDateSearchHistory) {
        createdDatesList.add(element.value.toString());
      }
    }

    exploreAdsFilteredList = await adsRepo.getExploreAdsBasedOnFilters(
      cityIdsList: cityIdsList,
      createdByRolesIdsList: adOwnerIdsList,
      vehicleBrandIdsList: brandsIdsList,
      vehicleModelYearIdsList: vehicleYearIdsList,
      vehicleAdConditionIdsList: conditionsIdsList,
      vehicleAdCreatedDateList: createdDatesList,
    );
    setState(ViewState.idle);
  }

  void onEditUpdateAdPressed({required BuildContext context, required AdDetailsModel previousDetails, required bool isFromExtendAd}) {
    isAdEditEnabled = true;
    previousAdDetails = previousDetails;
    autoFillSelectedVehicleType();
    autoFillSelectedVehicleAdsDuration();

    navigateWithName(context, AppRoutes.selectAdTypeView, arguments: [AppState().currentAppType == AppType.provider, isFromExtendAd, previousDetails.id]);
  }

  Future<bool> createAdExtensionOrder(BuildContext context, {required int adId, required int adsDurationId}) async {
    try {
      Utils.showLoading(context);
      GenericRespModel respModel = await adsRepo.createAdExtensionOrder(adID: adId, adsDurationId: adsDurationId, specialServiceIds: []);

      if (respModel.messageStatus != 1) {
        Utils.hideLoading(context);
        Utils.showToast(respModel.message ?? LocaleKeys.somethingWrong.tr());
        return false;
      }
      Utils.hideLoading(context);
      return respModel.messageStatus == 1;
    } catch (e) {
      Utils.hideLoading(context);
      Utils.showToast(e.toString());
      return false;
    }
  }

  void autoFillSelectedVehicleType() async {
    if (vehicleTypes.isEmpty) {
      await getVehicleTypes();
      return;
    }
    if (vehicleTypes.isNotEmpty) {
      for (var vehicle in vehicleTypes) {
        if (vehicle.id == previousAdDetails!.vehicle?.vehicleType) {
          vehicle.isSelected = true;
          break;
        }
      }
    }
    notifyListeners();
  }

  void autoFillSelectedVehicleAdsDuration() async {
    if (vehicleAdsDurations.isEmpty) {
      await getVehicleAdsDuration();
    }
    if (vehicleAdsDurations.isNotEmpty) {
      // TODO: FOR THE PROVIDER,  THIS CHECK WILL NOT WORK. BECAUSE IN CASE OF PROVIDER,THE PRICE WILL ALWAYS BE 0.0. Have to get ads duration ID from API in previousAd Details
      int index = vehicleAdsDurations.indexWhere((element) => element.price == previousAdDetails!.adsDurationPrice!);
      if (index != -1) {
        updateVehicleAdDurationId(
          SelectionModel(
            selectedId: vehicleAdsDurations[index].id ?? 0,
            selectedOption: "${vehicleAdsDurations[index].days} Days",
            itemPrice: vehicleAdsDurations[index].price!.toString(),
            currency: vehicleAdsDurations[index].currency!.toString(),
          ),
        );
      }
    }
    notifyListeners();
  }

  List<VehiclePostingDamageParts> vehicleOldDamageImagesList = [];

  void removeVehicleOldDamageImagesList(String imageUrl) {
    int index = vehicleOldDamageImagesList.indexWhere((element) => element.imageUrl == imageUrl);
    if (index == -1) {
      return;
    }
    vehicleOldDamageImagesList.removeAt(index);
    notifyListeners();
  }

  void autoFillSelectedVehicleAdsDetails() async {
    int index = vehicleBrands.indexWhere((element) => element.id == previousAdDetails!.vehicle!.model!.vehicleBrandID);
    if (index != -1) {
      await updateSelectionVehicleBrandId(SelectionModel(selectedId: vehicleBrands[index].id!, selectedOption: vehicleBrands[index].vehicleBrandDescription ?? ""));
    }

    updateSelectionVehicleModelId(SelectionModel(selectedId: previousAdDetails!.vehicle!.model!.id!, selectedOption: previousAdDetails!.vehicle!.model!.label ?? ""));
    updateSelectionVehicleModelYearId(SelectionModel(selectedId: previousAdDetails!.vehicle!.modelyear!.id!, selectedOption: previousAdDetails!.vehicle!.modelyear!.label ?? ""));
    updateSelectionVehicleColorId(SelectionModel(selectedId: previousAdDetails!.vehicle!.color!.id!, selectedOption: previousAdDetails!.vehicle!.color!.label ?? ""));
    updateSelectionVehicleConditionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.condition!.id!, selectedOption: previousAdDetails!.vehicle!.condition!.label ?? ""));
    updateSelectionVehicleCategoryId(SelectionModel(selectedId: previousAdDetails!.vehicle!.category!.id!, selectedOption: previousAdDetails!.vehicle!.category!.label ?? ""));
    updateSelectionVehicleMileageId(SelectionModel(
        selectedId: previousAdDetails!.vehicle!.mileage!.id!, selectedOption: "${previousAdDetails!.vehicle!.mileage!.mileageStart} - ${previousAdDetails!.vehicle!.mileage!.mileageEnd}"));
    updateSelectionVehicleTransmissionId(SelectionModel(selectedId: previousAdDetails!.vehicle!.transmission!.id!, selectedOption: previousAdDetails!.vehicle!.transmission!.label ?? ""));
    updateSelectionVehicleSellerTypeId(SelectionModel(selectedId: previousAdDetails!.vehicle!.sellertype!.id!, selectedOption: previousAdDetails!.vehicle!.sellertype!.label ?? ""));
    int indexCountry = vehicleCountries.indexWhere((element) => element.id == previousAdDetails!.vehicle!.countryID);
    if (indexCountry != -1) {
      updateSelectionVehicleCountryId(SelectionModel(selectedId: vehicleCountries[indexCountry].id!, selectedOption: vehicleCountries[indexCountry].countryName ?? ""));
    }
    updateSelectionVehicleCityId(SelectionModel(selectedId: previousAdDetails!.vehicle!.cityID!, selectedOption: previousAdDetails!.vehicle!.cityName ?? ""));

    vehicleDemandAmount = previousAdDetails!.vehicle!.demandAmount!.toInt().toString();
    vehicleVin = previousAdDetails!.vehicle!.vehicleVIN.toString();
    vehicleTitle = previousAdDetails!.vehicle!.vehicleTitle.toString();
    vehicleDescription = previousAdDetails!.vehicle!.vehicleDescription.toString();
    financeAvailableStatus = previousAdDetails!.vehicle!.isFinanceAvailable ?? false;
    pickedPostingImages.clear();
    if (previousAdDetails!.vehicle!.image != null && previousAdDetails!.vehicle!.image!.isNotEmpty) {
      for (var element in previousAdDetails!.vehicle!.image!) {
        if (element.imageUrl != null) {
          ImageModel imageModel = ImageModel(id: element.id, filePath: element.imageUrl, isFromNetwork: true);
          pickedPostingImages.add(imageModel);
        }
      }
    }

    if (previousAdDetails!.vehicle!.damagereport != null && previousAdDetails!.vehicle!.damagereport!.isNotEmpty) {
      for (var element in previousAdDetails!.vehicle!.damagereport!) {
        int index = -1;
        if (vehicleDamageCards.isNotEmpty) {
          index = ifDamagePartAlreadyThere(element.vehicleDamagePartID!);
          ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);
          vehicleDamageCards[index].partImages!.add(imageModel);
        } else {
          ImageModel imageModel = ImageModel(id: element.id!, filePath: element.imageUrl!, isFromNetwork: true);

          VehicleDamageCard vehicleDamageCard = VehicleDamageCard(
            partSelectedId: SelectionModel(
              selectedId: element.vehicleDamagePartID!,
              selectedOption: element.partName ?? "",
            ),
            damagePartDescription: "",
            partImages: [imageModel],
          );
          addNewDamagePartCard(damageCard: vehicleDamageCard);
        }
      }
    }

    if (previousAdDetails!.specialservice != null && previousAdDetails!.specialservice!.isNotEmpty) {
      for (var element in previousAdDetails!.specialservice!) {
        SelectionModel vehicleAdsSpecialServicesId = SelectionModel(selectedId: element.specialServiceID!, selectedOption: element.name ?? "", itemPrice: element.price.toString());
        SpecialServiceCard specialServiceCard = SpecialServiceCard(
          serviceSelectedId: vehicleAdsSpecialServicesId,
          description: element.description ?? "",
          duration: "",
          serviceDate: "",
          serviceDateError: "",
          serviceTimeError: "",
          address: "",
          serviceTime: "",
        );
        addNewSpecialServiceCard(specialServiceCard: specialServiceCard);
      }
    }

    selectionDurationStartDate = DateHelper.formatDateT(previousAdDetails!.startdate ?? "");
    isPhoneNumberShown = previousAdDetails!.phoneNo != null;
    if (isPhoneNumberShown) {
      adPhoneNumber = previousAdDetails!.phoneNo ?? "";
      adPhoneNumberDialCode = "+966";
    }

    isNumberOnWhatsApp = previousAdDetails!.whatsAppNo != null;
    warrantyDuration = previousAdDetails!.warrantyYears ?? "";

    notifyListeners();
  }

  int ifDamagePartAlreadyThere(int partId) {
    return vehicleDamageCards.indexWhere((element) => element.partSelectedId!.selectedId == partId);
  }

  int ifSpecialServiceAlreadyThere(int id) {
    return specialServiceCards.indexWhere((element) => element.serviceSelectedId!.selectedId == id);
  }

  List<BuyersChatForAdsModel> buyersChatListForAds = [];

  void onMessagesButtonPressed({required BuildContext context, required AdDetailsModel adDetailsModel}) async {
    final myUserID = AppState().getUser.data!.userInfo!.userId;
    if (adDetailsModel.isMyAd != null && adDetailsModel.isMyAd!) {
      await getBuyerChatsByAds(adsID: adDetailsModel.id!, context: context);
      navigateWithName(context, AppRoutes.adsBuyerChatsListView, arguments: buyersChatListForAds);
    } else {
      ChatViewArgumentsForAd chatViewArgumentsForAd = ChatViewArgumentsForAd(receiverUserID: adDetailsModel.userID, adsID: adDetailsModel.id);
      ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.ads, chatViewArgumentsForAd: chatViewArgumentsForAd);
      final chatVM = context.read<ChatVM>();
      await chatVM
          .getUsersChatMessagesForAd(
            context: context,
            isForBuyer: true,
            adsChatBuyerId: 1,
            adID: adDetailsModel.id,
            userID: myUserID,
            senderName: adDetailsModel.adOwnerName,
          )
          .whenComplete(() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments));
    }
  }

  Future<void> getBuyerChatsByAds({required int adsID, required BuildContext context}) async {
    try {
      Utils.showLoading(context);
      List<BuyersChatForAdsModel> buyersChatList = await adsRepo.getChatBuyersForAds(adsID: adsID);
      Utils.hideLoading(context);
      buyersChatListForAds.clear();
      buyersChatListForAds = buyersChatList;
      notifyListeners();
    } catch (e) {
      logger.i(e.toString());
      Utils.showToast(e.toString());
      Utils.hideLoading(context);
    }
  }
}

class VehicleDamageCard {
  List<ImageModel>? partImages;
  SelectionModel? partSelectedId;
  String? damagePartDescription;
  String partImageErrorValue;

  VehicleDamageCard({
    this.partImages,
    this.partSelectedId,
    this.damagePartDescription,
    this.partImageErrorValue = "",
  });

  @override
  String toString() {
    return 'VehicleDamageCard{partImages: $partImages, partSelectedId: $partSelectedId,damagePartDescription: $damagePartDescription, partImageErrorValue: $partImageErrorValue}';
  }
}

class ImageModel {
  int? id;
  bool? isFromNetwork;
  String? filePath;

  ImageModel({this.id, this.filePath, this.isFromNetwork});

  ImageModel.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    filePath = json['image'];
    isFromNetwork = true;
  }

  @override
  String toString() {
    return 'ImageModel{id: $id, isFromNetwork: $isFromNetwork, filePath: $filePath}';
  }
}

class SpecialServiceCard {
  SelectionModel? serviceSelectedId;
  String? serviceDate;
  String? serviceDateError;
  String? serviceTime;
  String? serviceTimeError;
  String? description;
  String? duration;
  String? address;

  SpecialServiceCard({
    this.serviceSelectedId,
    this.serviceDate = "",
    this.serviceDateError = "",
    this.serviceTime = "",
    this.serviceTimeError = "",
    this.description = "",
    this.duration = "",
    this.address = "",
  });
}
