import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_categories_list.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_category_model.dart'; import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_retailer_model.dart'; class OffersAndDiscountsApiClient { static final OffersAndDiscountsApiClient _instance = OffersAndDiscountsApiClient._internal(); OffersAndDiscountsApiClient._internal(); factory OffersAndDiscountsApiClient() => _instance; Future> getSaleCategories() async { List getSaleCategoriesList = []; String url = "${ApiConsts.cocRest}Mohemm_ITG_GetCategories"; Map postParams = {"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER, "ItgPageSize": 100, "ItgPageNo": 1, "ItgIsActive": true}; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject( (response) { var body = json.decode(response['Mohemm_ITG_ResponseItem']); GetCategoriesList getSaleCategoriesListObj = GetCategoriesList(); getSaleCategoriesListObj.id = 0; getSaleCategoriesListObj.categoryNameEn = "All"; getSaleCategoriesListObj.categoryNameAr = "الجميع"; getSaleCategoriesListObj.isActive = true; getSaleCategoriesListObj.content = ' '; getSaleCategoriesList.add(getSaleCategoriesListObj); body['result']['data'].forEach((v) { getSaleCategoriesList.add(GetCategoriesList.fromJson(v)); }); return getSaleCategoriesList; }, url, postParams, ); } Future> getOffersList(int categoryID, int pageSize) async { List getSaleCategoriesList = []; String url = "${ApiConsts.cocRest}GetOfferDiscountsConfigData"; Map postParams = {"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER, "ItgPageSize": pageSize, "ItgPageNo": 1, "ItgCategoryID": categoryID}; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject( (response) { var body = json.decode(response['Mohemm_ITG_ResponseItem']); var bodyData = body['result']['data']; if (bodyData != null) { bodyData.forEach((v) { getSaleCategoriesList.add(OffersListModel.fromJson(v)); }); } return getSaleCategoriesList; }, url, postParams, ); } String _resolveUserName() { String? pUserName = AppState().getUserName; if (pUserName == null || pUserName.isEmpty) { pUserName = AppState().postParamsObject?.userName ?? AppState().postParamsObject?.pUserName ?? AppState().memberInformationList?.eMPLOYEENUMBER; } return pUserName ?? ""; } String _resolveDepNationalId() { if (!ApiConsts.isDependetLogin) { return ""; } return AppState().getUserName ?? ""; } String _resolveMobileNumber({String? overrideMobile}) { if (overrideMobile != null && overrideMobile.trim().isNotEmpty) { return overrideMobile.trim(); } String? mobile = AppState().postParamsObject?.mobileNumber; if (mobile != null && mobile.trim().isNotEmpty) { return mobile.trim(); } mobile = AppState().memberInformationList?.eMPLOYEEMOBILENUMBER; if (mobile != null && mobile.trim().isNotEmpty) { return mobile.trim(); } mobile = AppState().walaplusDepInfoModel?.pEmpMobileNumber; if (mobile != null && mobile.trim().isNotEmpty) { return mobile.trim(); } mobile = AppState().memberLoginList?.pMOBILENUMBER; if (mobile != null && mobile.trim().isNotEmpty) { return mobile.trim(); } mobile = AppState().memberInformationList?.mobileNumberWithZipCode; if (mobile != null && mobile.trim().isNotEmpty) { return mobile.trim(); } return ""; } Map _getBaseWalaPlusParams() { Map base = {}; base.addAll(AppState().postParamsJson); if (ApiConsts.isDependetLogin) { String? token = AppState().postParamsObject?.tokenID ?? AppState().authenticationTokenID; if (token != null && token.isNotEmpty) { base["TokenID"] = token; } String? logInToken = AppState().postParamsObject?.logInTokenID; if (logInToken != null && logInToken.isNotEmpty) { base["LogInTokenID"] = logInToken; } } _cleanWalaPlusParams(base); return base; } void _cleanWalaPlusParams(Map map) { map.remove("P_EMAIL_ADDRESS"); map.remove("P_SESSION_ID"); map.remove("PayrollCodeStr"); map.remove("LegislationCodeStr"); map.remove("P_SELECTED_EMPLOYEE_NUMBER"); map.removeWhere((key, value) => value == null); } Future> getWalaPlusCategories({BuildContext? context, String? mobileNumber}) async { String url = ApiConsts.walaPlusCategories; String pUserName = _resolveUserName(); String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber); String pDepNationalId = _resolveDepNationalId(); Map postParams = _getBaseWalaPlusParams(); postParams["UserName"] = pUserName; postParams["P_USER_NAME"] = pUserName; postParams["P_DEP_NATIONAL_ID"] = pDepNationalId; if (pMobileNumber.isNotEmpty) { postParams["MobileNumber"] = pMobileNumber; } postParams["MemberType"] = ApiConsts.isDependetLogin ? 2 : 1; postParams["CompanyID"] = 1; _cleanWalaPlusParams(postParams); return await ApiClient().postJsonForObject( (response) { List categories = []; if (response != null) { dynamic cats = response['WalaPlus_Categories'] ?? response['walaPlus_Categories'] ?? response['WalaPlusCategories'] ?? response['result']; if (cats is String) { try { cats = json.decode(cats); } catch (e) { debugPrint("Error decoding WalaPlus_Categories: $e"); } } if (cats is List) { cats.forEach((v) { if (v is Map) { categories.add(WalaPlusCategoryModel.fromJson(v)); } else if (v is Map) { categories.add(WalaPlusCategoryModel.fromJson(Map.from(v))); } }); } } return categories; }, url, postParams, ); } Future getWalaPlusRetailers({ String? categoryId, int page = 1, int perPage = 10, String? geoLocation, BuildContext? context, String? mobileNumber, }) async { String url = ApiConsts.walaPlusRetailers; String pUserName = _resolveUserName(); String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber); String pDepNationalId = _resolveDepNationalId(); String effectiveCatId = (categoryId == "all" || categoryId == "0" || categoryId == null) ? "" : categoryId; Map postParams = _getBaseWalaPlusParams(); postParams["UserName"] = pUserName; postParams["P_USER_NAME"] = pUserName; postParams["P_DEP_NATIONAL_ID"] = pDepNationalId; if (pMobileNumber.isNotEmpty) { postParams["MobileNumber"] = pMobileNumber; } postParams["MemberType"] = ApiConsts.isDependetLogin ? 2 : 1; postParams["CompanyID"] = 1; postParams["WP_CategoryID"] = effectiveCatId; postParams["WP_Page"] = page; postParams["WP_Per_page"] = perPage; if (geoLocation != null && geoLocation.isNotEmpty) { postParams["WP_Geo_Location"] = geoLocation; } _cleanWalaPlusParams(postParams); return await ApiClient().postJsonForObject( (response) { if (response != null) { dynamic val = response['WalaPlus_Retailers'] ?? response['walaPlus_Retailers'] ?? response['WalaPlusRetailers'] ?? response['WP_Retailers'] ?? response['result']; if (val is String) { try { val = json.decode(val); } catch (e) { debugPrint("Error decoding WalaPlus_Retailers: $e"); } } if (val is Map) { return WalaPlusRetailersResponse.fromJson(val); } else if (val is Map) { return WalaPlusRetailersResponse.fromJson(Map.from(val)); } else if (val is List) { List retailers = []; for (var v in val) { if (v is Map) { retailers.add(WalaPlusRetailerModel.fromJson(v)); } else if (v is Map) { retailers.add(WalaPlusRetailerModel.fromJson(Map.from(v))); } } return WalaPlusRetailersResponse(retailers: retailers, page: 1, pagesCount: 1, perPage: retailers.length); } } return null; }, url, postParams, ); } Future getWalaPlusRetailerById({ required String retailerId, BuildContext? context, String? mobileNumber, }) async { String url = ApiConsts.walaPlusRetailersByID; String pUserName = _resolveUserName(); String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber); String pDepNationalId = _resolveDepNationalId(); Map postParams = _getBaseWalaPlusParams(); postParams["WP_RetailerID"] = retailerId; postParams["RetailerID"] = retailerId; postParams["UserName"] = pUserName; postParams["P_USER_NAME"] = pUserName; postParams["P_DEP_NATIONAL_ID"] = pDepNationalId; if (pMobileNumber.isNotEmpty) { postParams["MobileNumber"] = pMobileNumber; } postParams["MemberType"] = ApiConsts.isDependetLogin ? 2 : 1; postParams["CompanyID"] = 1; _cleanWalaPlusParams(postParams); debugPrint("getWalaPlusRetailerById: calling $url with WP_RetailerID: $retailerId"); return await ApiClient().postJsonForObject( (response) { if (response != null) { debugPrint("getWalaPlusRetailerById response keys: ${response is Map ? response.keys.toList() : 'non-map'}"); dynamic val = response['WalaPlus_RetailersByID'] ?? response['walaPlus_RetailersByID'] ?? response['WalaPlusRetailersByID'] ?? response['WP_RetailersByID'] ?? response['result']; if (val is String) { try { val = json.decode(val); } catch (e) { debugPrint("Error decoding WalaPlus_RetailersByID JSON string: $e"); } } WalaPlusRetailerModel? model; if (val is List && val.isNotEmpty) { var item = val.first; if (item is Map) { model = WalaPlusRetailerModel.fromJson(item); } else if (item is Map) { model = WalaPlusRetailerModel.fromJson(Map.from(item)); } } else if (val is Map) { Map map = (val is Map) ? val : Map.from(val); if (map.containsKey('retailer')) { var byIdResponse = WalaPlusRetailersByIDResponse.fromJson(map); model = byIdResponse.primaryRetailer ?? WalaPlusRetailerModel.fromJson(map); } else { model = WalaPlusRetailerModel.fromJson(map); } if ((model?.offers == null || model!.offers!.isEmpty) && (map.containsKey('offers') || map.containsKey('Offers'))) { model?.offers = WalaPlusRetailerModel.parseOffersList(map['offers'] ?? map['Offers']); } if ((model?.locations == null || model!.locations!.isEmpty) && (map.containsKey('locations') || map.containsKey('Locations') || map.containsKey('location') || map.containsKey('Location'))) { model?.locations = WalaPlusRetailerModel.parseLocationsList( map['locations'] ?? map['Locations'] ?? map['location'] ?? map['Location'], ); } } else if (response is Map && response.containsKey('name')) { model = WalaPlusRetailerModel.fromJson(response); } if (model != null) { if (response is Map) { if ((model.offers == null || model.offers!.isEmpty) && (response.containsKey('offers') || response.containsKey('Offers'))) { model.offers = WalaPlusRetailerModel.parseOffersList(response['offers'] ?? response['Offers']); } if ((model.locations == null || model.locations!.isEmpty) && (response.containsKey('locations') || response.containsKey('Locations') || response.containsKey('location') || response.containsKey('Location'))) { model.locations = WalaPlusRetailerModel.parseLocationsList( response['locations'] ?? response['Locations'] ?? response['location'] ?? response['Location'], ); } } debugPrint("getWalaPlusRetailerById: parsed retailer '${model.name}', offers: ${model.offers?.length ?? 0}, locations: ${model.locations?.length ?? 0}"); return model; } } return null; }, url, postParams, ); } String _resolveUserReference({String? overrideUserReference}) { if (overrideUserReference != null && overrideUserReference.trim().isNotEmpty) { return overrideUserReference.trim(); } String? ref = AppState().memberInformationList?.eMPLOYEENUMBER?.toString(); if (ref != null && ref.trim().isNotEmpty) { return ref.trim(); } String? pUserName = AppState().getUserName; if (pUserName != null && pUserName.trim().isNotEmpty) { return pUserName.trim(); } return ""; } Future?> redeemWalaPlusOffer({ required String offerId, String? offerType, String? userReference, BuildContext? context, }) async { String url = ApiConsts.walaPlusOfferRedeem; String pUserName = _resolveUserName(); String pUserReference = _resolveUserReference(overrideUserReference: userReference); Map postParams = _getBaseWalaPlusParams(); postParams["WP_User_Reference"] = pUserReference; postParams["WP_Offer_Id"] = offerId; postParams["WP_Offer_Type"] = (offerType != null && offerType.trim().isNotEmpty) ? offerType.trim() : "promo"; postParams["UserName"] = pUserName; postParams["P_USER_NAME"] = pUserName; if (ApiConsts.isDependetLogin) { String pDepNationalId = _resolveDepNationalId(); if (pDepNationalId.isNotEmpty) { postParams["P_DEP_NATIONAL_ID"] = pDepNationalId; } postParams["MemberType"] = 2; } else { postParams["P_DEP_NATIONAL_ID"] = ""; postParams["MemberType"] = 1; } _cleanWalaPlusParams(postParams); debugPrint("redeemWalaPlusOffer calling $url with params: $postParams"); return await ApiClient().postJsonForObject( (response) { if (response != null) { debugPrint("redeemWalaPlusOffer response: $response"); dynamic val = response['WalaPlus_OfferRedeem'] ?? response['walaPlus_OfferRedeem'] ?? response['WalaPlusOfferRedeem'] ?? response['result']; if (val is String) { try { val = json.decode(val); } catch (e) { debugPrint("Error decoding WalaPlus_OfferRedeem: $e"); } } if (val is Map) { return val; } else if (val is Map) { return Map.from(val); } } return null; }, url, postParams, ); } }