import 'dart:developer';

import 'package:easy_localization/easy_localization.dart';
import 'package:mc_common_app/api/api_client.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/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.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/pdf_receipt_model.dart';
import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart';
import 'package:mc_common_app/models/advertisment_models/special_service_model.dart';
import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart';
import 'package:mc_common_app/models/general_models/generic_resp_model.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';

abstract class AdsRepo {
  Future<List<AdsDurationModel>> getAdsDuration({required int? countryId});

  Future<List<SpecialServiceModel>> getSpecialServices({required int specialServiceType, required int cityId, required int countryId});

  Future<GenericRespModel> createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required bool isExtendAdEditEnabled});

  Future<GenericRespModel> createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo});

  Future<List<AdDetailsModel>> getAllAds({
    required bool isMyAds,
    AdPostStatus? adPostStatus,
    CreatedByRoleEnum? createdByRoleEnum,
    int? vehicleBrandId,
    int? page,
  });

  Future<List<AdDetailsModel>> getMyDraftAds({int? page});

  Future<List<AdDetailsModel>> getExploreAdsBasedOnFilters({
    List<String>? adIdsList,
    List<String>? cityIdsList,
    List<String>? vehicleModelYearIdsList,
    List<String>? vehicleTypeIdsList,
    List<String>? vehicleBrandIdsList,
    List<String>? createdByRolesIdsList,
    List<String>? vehicleAdConditionIdsList,
    List<String>? vehicleAdCreatedDateList,
    List<String>? mobileNumbersList,
    int? startPriceDemand,
    int? endPriceDemand,
    int page,
    bool isMyAds = false,
  });

  Future<List<AdDetailsModel>> getMyReservedAds();

  Future<List<AdDetailsModel>> getMyAds();

  Future<List<AdDetailsModel>> getFavouriteAds();

  Future<GenericRespModel> toggleAdFavorite({required int adsID, required bool isFavorite});

  Future<AdsBankDetailsModel?> getAdBankingAccountInfo({required int adId});

  Future<GenericRespModel> updateAdStatus({required int adId, required AdPostStatus adStatusToUpdate, String? comment});

  Future<GenericRespModel> createAppointmentForAdSpecialService({required int adId, required int photoOfficeID, required int photoOfficeSlotID, required int adsSpecialServiceID});

  Future<GenericRespModel> deleteAd({required int adId});

  Future<GenericRespModel> cancelMyAdReservation({required int adId, required int adsReserveStatus, required String reason});

  Future<GenericRespModel> createReserveAd({required int adId});

  Future<GenericRespModel> uploadBankReceiptsOnReserveDealDone({required int adId, required String detailNote, required List<PdfReceiptModel> pdfReceiptsList});

  Future<List<BuyersChatForAdsModel>> getChatBuyersForAds({required int adsID});

  Future<GenericRespModel> createAdExtensionOrder({required int adID, required List<int> specialServiceIds, required int adsDurationId});
}

class AdsRepoImp implements AdsRepo {
  ApiClient apiClient = injector.get<ApiClient>();
  AppState appState = injector.get<AppState>();

  @override
  Future<List<AdsDurationModel>> getAdsDuration({required int? countryId}) async {
    int roleID = appState.getUser.data!.userInfo!.roleId ?? 0;
    var param = {
      "CountryID": countryId.toString(),
      "roleID": roleID.toString(),
    };
    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      queryParameters: param,
      ApiConsts.vehicleAdsDurationGet,
    );
    List<AdsDurationModel> vehicleAdsDuration = List.generate(adsGenericModel.data.length, (index) => AdsDurationModel.fromJson(adsGenericModel.data[index]));
    return vehicleAdsDuration;
  }

  @override
  Future<List<SpecialServiceModel>> getSpecialServices({required int specialServiceType, required int cityId, required int countryId}) async {
    log("getSpecialServices cityId: $cityId");
    var params = {
      "SpecialServiceType": specialServiceType.toString(),
      "CountryID": countryId.toString(),
    };
    GenericRespModel adsGenericModel =
        await apiClient.getJsonForObject(token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), ApiConsts.vehicleAdsSpecialServicesGet, queryParameters: params);
    List<SpecialServiceModel> list = List.generate(adsGenericModel.data.length, (index) => SpecialServiceModel.fromJson(adsGenericModel.data[index]));

    List<SpecialServiceModel> specialServicesByCity = getOfficesOnlyByCity(list, cityId);

    return specialServicesByCity;
  }

  List<SpecialServiceModel> getOfficesOnlyByCity(List<SpecialServiceModel> allServices, int cityId) {
    List<SpecialServiceModel> list = [];

    for (var service in allServices) {
      if (service.office != null && service.office!.isNotEmpty) {
        for (var office in service.office!) {
          if (office.cityID == cityId) {
            list.add(service);
          }
        }
      }
    }
    return list;
  }

  @override
  Future<GenericRespModel> createOrUpdateAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required bool isExtendAdEditEnabled}) async {
    List vehiclePostingImages = [];

    log("isExtendAdEditEnabled: $isExtendAdEditEnabled");
    log("adsCreationPayloadModel.ads!.adsDurationID,: ${adsCreationPayloadModel.ads!.adsDurationID}");
    adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach((element) {
      var imageMap = {
        "id": element.id ?? 0,
        "imageName": element.imageName,
        "imageUrl": element.imageUrl,
        "imageStr": element.imageStr,
        "vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0,
        "vehiclePosting": null,
      };
      vehiclePostingImages.add(imageMap);
    });

    List vehiclePostingDamageParts = [];

    int sellerTypeID = AppState().getUser.data!.userInfo!.roleId ?? 0;

    adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) {
      log("comment: ${element.comment}");
      var imageMap = {
        "id": element.id ?? 0,
        "comment": element.comment,
        "vehicleImageBase64": element.vehicleImageBase64,
        "vehicleDamagePartID": element.vehicleDamagePartID,
        "vehiclePostingID": isCreateNew ? 0 : element.vehiclePostingID ?? 0,
        "isActive": true
      };
      vehiclePostingDamageParts.add(imageMap);
    });
    var postParams = {
      "ads": {
        "id": isCreateNew ? 0 : adsCreationPayloadModel.ads!.id ?? 0,
        "adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
        "startDate": adsCreationPayloadModel.ads!.startDate,
        "countryId": adsCreationPayloadModel.ads!.countryId,
        "specialServiceIDs": adsCreationPayloadModel.ads!.specialServiceIDs,
        "isMCHandled": false,
        "showContactDetail": adsCreationPayloadModel.ads!.showContactDetail ?? false,
        "isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false,
      },
      "vehiclePosting": {
        "id": isCreateNew ? 0 : adsCreationPayloadModel.vehiclePosting!.id ?? 0,
        "userID": adsCreationPayloadModel.vehiclePosting!.userID,
        "vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
        "vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
        "vehicleModelYearID": adsCreationPayloadModel.vehiclePosting!.vehicleModelYearID,
        "vehicleColorID": adsCreationPayloadModel.vehiclePosting!.vehicleColorID,
        "vehicleCategoryID": adsCreationPayloadModel.vehiclePosting!.vehicleCategoryID,
        "vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID,
        "vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID,
        "vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID,
        "vehicleSellerTypeID": sellerTypeID,
        "cityID": adsCreationPayloadModel.vehiclePosting!.cityID,
        "price": adsCreationPayloadModel.vehiclePosting!.price,
        "vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN,
        "vehicleDescription": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
        "vehicleTitle": adsCreationPayloadModel.vehiclePosting!.vehicleTitle,
        "vehicleDescriptionN": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
        "isFinanceAvailable": adsCreationPayloadModel.vehiclePosting!.isFinanceAvailable,
        "warantyYears": adsCreationPayloadModel.vehiclePosting!.warantyYears,
        "demandAmount": adsCreationPayloadModel.vehiclePosting!.demandAmount,
        // "adStatus": 1,
        "vehiclePostingImages": vehiclePostingImages,
        "vehiclePostingDamageParts": vehiclePostingDamageParts,
        "mobileNo": adsCreationPayloadModel.vehiclePosting!.phoneNo,
        "whatsAppNo": adsCreationPayloadModel.vehiclePosting!.whatsAppNo,
        "odometer": adsCreationPayloadModel.vehiclePosting!.odometer,
        "isInUsed": adsCreationPayloadModel.vehiclePosting!.isInUsed,
        "isAccidentFree": adsCreationPayloadModel.vehiclePosting!.isAccidentFree,
      }
    };

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      isExtendAdEditEnabled
          ? ApiConsts.vehicleAdsSingleStepUpdateExtend
          : isCreateNew
              ? ApiConsts.vehicleAdsSingleStepCreate
              : ApiConsts.vehicleAdsSingleStepUpdate,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<GenericRespModel> createOrUpdateDraftAd({required AdsCreationPayloadModel adsCreationPayloadModel, required bool isCreateNew, required AdCreationStepsEnum stepNo}) async {
    int sellerTypeID = AppState().getUser.data!.userInfo!.roleId ?? 0;

    List vehiclePostingImages = [];
    List vehiclePostingDamageParts = [];

    if (adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages != null) {
      adsCreationPayloadModel.vehiclePosting!.vehiclePostingImages?.forEach(
        (element) {
          var imageMap = {
            "id": element.id ?? 0,
            "imageName": element.imageName,
            "imageUrl": element.imageUrl,
            "imageStr": element.imageStr,
            "vehiclePostingDraftID": element.vehiclePostingID ?? 0,
            "vehiclePosting": null,
          };
          vehiclePostingImages.add(imageMap);
        },
      );
    }

    if (adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts != null) {
      adsCreationPayloadModel.vehiclePosting!.vehiclePostingDamageParts?.forEach((element) {
        var imageMap = {
          "id": element.id ?? 0,
          "comment": element.comment,
          "vehicleImageBase64": element.vehicleImageBase64,
          "vehicleDamagePartID": element.vehicleDamagePartID,
          "vehiclePostingDraftID": element.vehiclePostingID ?? 0,
          "isActive": true
        };
        vehiclePostingDamageParts.add(imageMap);
      });
    }

    var postParams = {
      "adsDraft": {
        "id": adsCreationPayloadModel.ads!.id ?? 0,
        "adsDurationID": adsCreationPayloadModel.ads!.adsDurationID,
        "startDate": adsCreationPayloadModel.ads!.startDate,
        "countryId": adsCreationPayloadModel.ads!.countryId,
        "specialServiceIDs": adsCreationPayloadModel.ads!.specialServiceIDs,
        "isMCHandled": false,
        "showContactDetail": adsCreationPayloadModel.ads!.showContactDetail ?? false,
        "isOnWhatsApp": adsCreationPayloadModel.ads!.isOnWhatsApp ?? false,
      },
      "vehiclePostingDraft": {
        "id": adsCreationPayloadModel.vehiclePosting!.id ?? 0,
        "userID": adsCreationPayloadModel.vehiclePosting!.userID,
        "vehicleType": adsCreationPayloadModel.vehiclePosting!.vehicleType,
        "vehicleModelID": adsCreationPayloadModel.vehiclePosting!.vehicleModelID,
        "vehicleModelYearID": adsCreationPayloadModel.vehiclePosting!.vehicleModelYearID,
        "vehicleColorID": adsCreationPayloadModel.vehiclePosting!.vehicleColorID,
        "vehicleCategoryID": adsCreationPayloadModel.vehiclePosting!.vehicleCategoryID,
        "vehicleConditionID": adsCreationPayloadModel.vehiclePosting!.vehicleConditionID,
        "vehicleMileageID": adsCreationPayloadModel.vehiclePosting!.vehicleMileageID,
        "vehicleTransmissionID": adsCreationPayloadModel.vehiclePosting!.vehicleTransmissionID,
        "vehicleSellerTypeID": sellerTypeID,
        "cityID": adsCreationPayloadModel.vehiclePosting!.cityID,
        "price": adsCreationPayloadModel.vehiclePosting!.price,
        "vehicleVIN": adsCreationPayloadModel.vehiclePosting!.vehicleVIN,
        "vehicleDescription": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
        "vehicleTitle": adsCreationPayloadModel.vehiclePosting!.vehicleTitle,
        "vehicleDescriptionN": adsCreationPayloadModel.vehiclePosting!.vehicleDescription,
        "isFinanceAvailable": adsCreationPayloadModel.vehiclePosting!.isFinanceAvailable,
        "warantyYears": adsCreationPayloadModel.vehiclePosting!.warantyYears,
        "demandAmount": adsCreationPayloadModel.vehiclePosting!.demandAmount,
        "vehiclePostingImagesDraft": vehiclePostingImages,
        "vehiclePostingDamagePartsDraft": vehiclePostingDamageParts,
        "mobileNo": adsCreationPayloadModel.vehiclePosting!.phoneNo,
        "whatsAppNo": adsCreationPayloadModel.vehiclePosting!.whatsAppNo,
        "odometer": adsCreationPayloadModel.vehiclePosting!.odometer,
        "isInUsed": adsCreationPayloadModel.vehiclePosting!.isInUsed,
        "isAccidentFree": adsCreationPayloadModel.vehiclePosting!.isAccidentFree,
        // "adStatus": 1,
      },
      "stepNo": stepNo.toIntFromStepsEnum(),
    };

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      isCreateNew ? ApiConsts.adsSingleStepDraftCreate : ApiConsts.adsSingleStepDraftUpdate,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<List<AdDetailsModel>> getMyDraftAds({int? page}) async {
    var draftAdsParams = {
      "PageSize": "30",
      "PageIndex": page != null ? page.toString() : "0",
      "userID": appState.getUser.data!.userInfo!.userId ?? "",
    };

    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.getMyDraftAds,
      queryParameters: draftAdsParams,
    );
    List<AdDetailsModel> vehicleAdsDetails = List.generate(
      adsGenericModel.data.length,
      (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], true, adsGenericModel.totalItemsCount ?? 1),
    );
    return vehicleAdsDetails;
  }

  @override
  Future<List<AdDetailsModel>> getAllAds({
    required isMyAds,
    AdPostStatus? adPostStatus,
    CreatedByRoleEnum? createdByRoleEnum,
    int? vehicleBrandId,
    int? page,
  }) async {
    Map<String, dynamic> onlyMyAdsParams = {
      "userID": appState.getUser.data!.userInfo!.userId ?? "",
    };
    if (isMyAds && adPostStatus != null) {
      onlyMyAdsParams.addAll({
        "AdsStatuses": ["${adPostStatus.getIdFromAdPostStatusEnum()}"],
        "PageSize": "30",
        "PageIndex": page != null ? page.toString() : "0",
      });
    }
    var allAdsParams = {
      "AdsStatuses": ["${AdPostStatus.active.getIdFromAdPostStatusEnum()}"], //only Active ADS
      "isActive": "true", //only Active ADS
      "isExplore": "true",
      "PageSize": "30",
      "PageIndex": page != null ? page.toString() : "0",
    };

    if (!isMyAds && createdByRoleEnum != null) {
      allAdsParams.addAll({
        "CreatedByRoles": ["${createdByRoleEnum.getIdFromCreatedByRoleEnum()}"],
      });
    }
    if (!isMyAds && vehicleBrandId != null && vehicleBrandId != 0) {
      allAdsParams.addAll({
        "VehicleBrandIDs": ["$vehicleBrandId"],
      });
    }
    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.vehicleAdsGet,
      queryParameters: isMyAds ? onlyMyAdsParams : allAdsParams,
    );
    List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], isMyAds, adsGenericModel.totalItemsCount ?? 1));
    return vehicleAdsDetails;
  }

  @override
  Future<List<AdDetailsModel>> getExploreAdsBasedOnFilters({
    List<String>? adIdsList,
    List<String>? cityIdsList,
    List<String>? vehicleModelYearIdsList,
    List<String>? vehicleTypeIdsList,
    List<String>? vehicleBrandIdsList,
    List<String>? createdByRolesIdsList,
    List<String>? vehicleAdConditionIdsList,
    List<String>? vehicleAdCreatedDateList,
    List<String>? mobileNumbersList,
    int? startPriceDemand,
    int? endPriceDemand,
    int? page,
    bool isMyAds = false,
  }) async {
    var parameters = {
      "AdsIDs": adIdsList ?? [],
      "CityIDs": cityIdsList ?? [],
      "VehicleTypeIDs": vehicleTypeIdsList ?? [],
      "VehicleBrandIDs": vehicleBrandIdsList ?? [],
      "VehicleModelYearIDs": vehicleModelYearIdsList ?? [],
      "CreatedByRoles": createdByRolesIdsList ?? [],
      "AdsStatuses": ["${AdPostStatus.active.getIdFromAdPostStatusEnum()}"], //only Active ADS
      "VehicleNew": vehicleAdConditionIdsList != null && vehicleAdConditionIdsList.isNotEmpty ? vehicleAdConditionIdsList.first.toString() : null,
      "CreatedOn": (vehicleAdCreatedDateList != null && vehicleAdCreatedDateList.isNotEmpty) ? vehicleAdCreatedDateList.first.toString() : null,
      "MobileNumbers": mobileNumbersList ?? [],
      "StartPriceDemand": startPriceDemand?.toString(),
      "EndPriceDemand": endPriceDemand?.toString(),
      "isActive": "true", //only Active ADS
      "isExplore": (!isMyAds).toString(),
      "PageSize": "30",
      "PageIndex": page != null ? page.toString() : "1",
    };

    if (isMyAds) {
      parameters.addAll({
        "userID": appState.getUser.data!.userInfo!.userId ?? "",
      });
    }

    parameters.removeWhere((key, value) => value == null);

    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.vehicleAdsGet,
      queryParameters: parameters,
    );

    if (adsGenericModel.messageStatus != 1 || adsGenericModel.data == null) {
      Utils.showToast(adsGenericModel.message ?? LocaleKeys.somethingWrong.tr());
      return [];
    }
    List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], false, adsGenericModel.totalItemsCount ?? 1));
    return vehicleAdsDetails;
  }

  @override
  Future<List<AdDetailsModel>> getMyReservedAds() async {
    var params = {
      "userID": appState.getUser.data!.userInfo!.userId ?? "",
    };

    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.myAdsReserveGet,
      queryParameters: params,
    );

    if (adsGenericModel.messageStatus != 1 || adsGenericModel.data == null) {
      Utils.showToast(adsGenericModel.message ?? LocaleKeys.somethingWrong.tr());
      return [];
    }
    List<MyReservedAdsRespModel> reservedAds = List.generate(adsGenericModel.data.length, (index) => MyReservedAdsRespModel.fromJson(adsGenericModel.data[index]));
    List<String> selectedIdsString = reservedAds.map((component) => component.adsID.toString()).toList();

    if (selectedIdsString.isEmpty) {
      return [];
    }

    return await getAdsPerSpecificIds(ids: selectedIdsString, reservedAds: reservedAds);
  }

  Future<List<AdDetailsModel>> getAdsPerSpecificIds({required List<String> ids, required List<MyReservedAdsRespModel> reservedAds}) async {
    var params = {
      "AdsIDs": ids,
      "isActive": "true",
      "PageSize": "30",
    };
    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      queryParameters: params,
      ApiConsts.vehicleAdsGet,
    );
    if (adsGenericModel.messageStatus != 1 || adsGenericModel.data == null) {
      Utils.showToast(adsGenericModel.message ?? LocaleKeys.somethingWrong.tr());
      return [];
    }
    List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], true, adsGenericModel.totalItemsCount ?? 1));

    for (int i = 0; i < vehicleAdsDetails.length; i++) {
      vehicleAdsDetails[i].adReserveStatus = (reservedAds[i].adsReserveStatus ?? 0).toAdRserveStatusEnum();
    }

    vehicleAdsDetails.removeWhere((element) => element.adReserveStatus != AdReserveStatus.reserved);
    return vehicleAdsDetails;
  }

  @override
  Future<List<AdDetailsModel>> getMyAds() async {
    var params = {
      "userID": appState.getUser.data!.userInfo!.userId ?? "",
      "PageSize": "30",
    };
    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      queryParameters: params,
      ApiConsts.vehicleAdsGet,
    );
    if (adsGenericModel.messageStatus != 1 || adsGenericModel.data == null) {
      Utils.showToast(adsGenericModel.message ?? LocaleKeys.somethingWrong.tr());
      return [];
    }
    List<AdDetailsModel> vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], true, adsGenericModel.totalItemsCount ?? 1));
    return vehicleAdsDetails;
  }

  @override
  Future<List<AdDetailsModel>> getFavouriteAds() async {
    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.favouriteAdsGet,
    );
    if (adsGenericModel.messageStatus != 1 || adsGenericModel.data == null) {
      return [];
    }
    List<AdDetailsModel> favouriteAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], false, adsGenericModel.totalItemsCount ?? 1));
    return favouriteAdsDetails;
  }

  @override
  Future<GenericRespModel> toggleAdFavorite({required int adsID, required bool isFavorite}) async {
    var params = {
      "adsID": adsID.toString(),
    };

    String endpoint = isFavorite ? ApiConsts.unFavouriteAds : ApiConsts.favouriteAdsCreate;

    GenericRespModel genericRespModel = await apiClient.postJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      endpoint,
      params,
    );

    return genericRespModel;
  }

  @override
  Future<AdsBankDetailsModel?> getAdBankingAccountInfo({required int adId}) async {
    var params = {
      "userID": appState.getUser.data!.userInfo!.userId ?? "",
      "AdsID": "$adId",
    };
    GenericRespModel adsGenericModel = await apiClient.getJsonForObject(
      token: appState.getUser.data!.accessToken,
      (json) => GenericRespModel.fromJson(json),
      queryParameters: params,
      ApiConsts.adsMCBankAccountAdGet,
    );

    List<AdsBankDetailsModel> adsBankDetails = List.generate(adsGenericModel.data.length, (index) => AdsBankDetailsModel.fromJson(adsGenericModel.data[index]));
    if (adsBankDetails.isNotEmpty) {
      return adsBankDetails.first;
    }
    return null;
  }

  @override
  Future<GenericRespModel> updateAdStatus({required int adId, required AdPostStatus adStatusToUpdate, String? comment}) async {
    var postParams = {
      "id": adId,
      "status": adStatusToUpdate.getIdFromAdPostStatusEnum().toString(),
      "comment": comment ?? "",
    };

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.adsUpdateStatus,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<GenericRespModel> createAdExtensionOrder({required int adID, required List<int> specialServiceIds, required int adsDurationId}) async {
    var postParams = {
      "adsID": adID,
      "adsDurationID": adsDurationId,
      "specialServiceIDs": specialServiceIds,
    };

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.adsExtendDurationCreate,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<GenericRespModel> deleteAd({required int adId}) async {
    var postParams = {
      "adID": adId,
    };

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.deleteAd,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<GenericRespModel> cancelMyAdReservation({required int adId, required int adsReserveStatus, required String reason}) async {
    int customerID = AppState().getUser.data!.userInfo!.customerId ?? 0;

    var postParams = {
      "adsID": adId,
      "adsReserveStatus": adsReserveStatus,
      "comment": reason,
    };

    if (!AppState().getIsViewOnly) {
      postParams["customerID"] = customerID;
    }

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.deleteAd,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<GenericRespModel> createReserveAd({required int adId}) async {
    int customerID = AppState().getUser.data!.userInfo!.customerId ?? 0;

    var postParams = {
      "adsID": adId,
      "adsReserveStatus": 0,
    };

    if (!AppState().getIsViewOnly) {
      postParams["customerID"] = customerID;
    }

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.adsReserveCreate,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<GenericRespModel> createAppointmentForAdSpecialService({
    required int adId,
    required int photoOfficeID,
    required int photoOfficeSlotID,
    required int adsSpecialServiceID,
  }) async {
    String? userId = AppState().getUser.data!.userInfo!.userId ?? "";

    var postParams = {
      "adsID": adId,
      "photoOfficeID": photoOfficeID,
      "photoOfficeSlotID": photoOfficeSlotID,
      "adsSpecialServiceID": adsSpecialServiceID,
      "UserID": userId,
    };

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.adsPhotoOfficeAppointmentCreate,
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<GenericRespModel> uploadBankReceiptsOnReserveDealDone({required int adId, required String detailNote, required List<PdfReceiptModel> pdfReceiptsList}) async {
    int customerId = AppState().getUser.data!.userInfo!.customerId ?? 0;

    List receiptImages = [];

    for (var element in pdfReceiptsList) {
      var pdfReceiptMap = {
        "id": 0,
        "imageName": element.pdfName,
        "imageStr": element.pdfString,
      };
      receiptImages.add(pdfReceiptMap);
    }

    var postParams = {
      "adsID": adId,
      "detailNote": detailNote,
      "receiptImages": receiptImages,
    };

    if (!AppState().getIsViewOnly) {
      postParams["customerID"] = customerId;
    }

    String token = appState.getUser.data!.accessToken ?? "";
    GenericRespModel adsGenericModel = await apiClient.postJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      "",
      postParams,
      token: token,
    );

    return Future.value(adsGenericModel);
  }

  @override
  Future<List<BuyersChatForAdsModel>> getChatBuyersForAds({required int adsID}) async {
    var queryParameters = {"AdsID": adsID.toString()};
    GenericRespModel genericRespModel = await apiClient.getJsonForObject(
      (json) => GenericRespModel.fromJson(json),
      ApiConsts.getChatBuyersForAds,
      queryParameters: queryParameters,
      token: appState.getUser.data!.accessToken,
    );
    List<BuyersChatForAdsModel> buyersChatListForAds = [];
    if (genericRespModel.data != null && genericRespModel.data.length > 0) {
      buyersChatListForAds = List.generate(genericRespModel.data.length, (index) => BuyersChatForAdsModel.fromJson(genericRespModel.data[index]));
    }
    return buyersChatListForAds;
  }
}
