import 'dart:async'; import 'dart:convert'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:grocery_app/src/core/network_services/service_locator.dart'; import 'package:grocery_app/src/core/routes/routes.dart'; import 'package:grocery_app/src/data/ProductCategoryModel.dart'; import 'package:grocery_app/src/data/allProduct_model.dart'; import 'package:grocery_app/src/data/banners.dart'; import 'package:grocery_app/src/data/best_dealProduct.dart'; import 'package:grocery_app/src/data/product_category.dart'; import 'package:grocery_app/src/data/product_details.dart'; import 'package:grocery_app/src/data/wish_list_model.dart'; import 'package:grocery_app/src/logic/repo/product_repo.dart'; import 'package:grocery_app/utils/constants/shared_pref_utils.dart'; import 'package:grocery_app/utils/extensions/extensions.dart'; import 'package:http/http.dart' as http; class ProductProvider extends ChangeNotifier { final _homeRepo = getIt(); String searchValue = ''; bool isLoadingg = false; List products = []; int page = 1; final int limit = 8; bool hasMore = true; bool iscroll = true; Future gettAllProduct(BuildContext context, String id, bool status, String search, bool first) async { print("kdjfhgkfkjdghkjkdfg"); // if (isLoadingg || !hasMore) return; if (first) { products.clear(); notifyListeners(); } if (id.isNotEmpty) { products.clear(); hasMore = true; } if (status) { isLoadingg = true; } ; notifyListeners(); var data = { "page": page, "limit": limit, "minPrice": "", "minPrice": "", "search": search }; var result = await _homeRepo.getAllProduct(data, context, id); return result.fold( (error) { isLoadingg = false; notifyListeners(); }, (response) { // products = response.data!; // page++; // print( // "jksdhfgkjdfkhjghkjdfhgkjdf ${response.data} ${response.data!.isNotEmpty}"); // if (response.data != null && response.data!.isNotEmpty) { // products.addAll(response.data!); // // products = response.data!; // page++; // } else { // hasMore = false; // } print("jdksgfkgkbfgh ${response}"); if (response.data != null && response.data!.isNotEmpty) { if (id.isNotEmpty) { products = response.data!; } else { products.addAll(response.data!); } page++; if (response.data!.length < limit) { hasMore = false; } } else { hasMore = false; } isLoadingg = false; notifyListeners(); }, ); } Future updateDeviceToken(BuildContext context) async { var fcm = await FirebaseMessaging.instance.getToken(); var data = {"deviceToken": fcm, "deviceTpe": "android"}; print("fcm token ${"hjsdgffghhhh ${data}"}"); var result = await _homeRepo.updateDeviceToken(data, context); return result.fold( (error) { return true; }, (response) { print("token update success"); return true; }, ); } bool isHomeLoadingg = false; List homeproducts = []; Future getHomeProduct(BuildContext context, String id, String search, String minPrice, String maxprice, orderby) async { isHomeLoadingg = true; notifyListeners(); var data; if (maxprice.isNotEmpty) { data = { "minPrice": "${minPrice}", "maxPrice": maxprice, "search": search, "sortBy": orderby }; } else { data = {"minPrice": "${minPrice}", "search": search, "sortBy": orderby}; } var result = await _homeRepo.getAllProduct(data, context, id); return result.fold( (error) { isLoadingg = false; notifyListeners(); }, (response) { homeproducts = response.data!; isHomeLoadingg = false; notifyListeners(); }, ); } ProductDetailsData productDetails = ProductDetailsData(); bool isProductLoading = true; Future getProduuctDetails( BuildContext context, String id, int quantity, String price) async { var data = {}; productDetails = ProductDetailsData(); isProductLoading = true; quantitys = quantity; _totalPrice = quantity * (double.parse(price)); notifyListeners(); var result = await _homeRepo.getProductDetails(data, context, id); return result.fold( (error) { isProductLoading = false; notifyListeners(); }, (response) { productDetails = response!; isProductLoading = false; notifyListeners(); }, ); } List bestdeal = []; bool isBestdealingloading = true; Future getBestDealProduct(BuildContext context, String search) async { isBestdealingloading = true; notifyListeners(); var data = {"minPrice": "", "minPrice": "", "search": search}; var result = await _homeRepo.getBestDealProduct(data, context); return result.fold( (error) { isBestdealingloading = false; notifyListeners(); }, (response) { bestdeal = response.data!; isBestdealingloading = false; notifyListeners(); }, ); } List categoryList = []; bool iscategroyloading = true; Future getAllcategory(BuildContext context) async { var data = {}; var result = await _homeRepo.getAllcategory(data, context); return result.fold( (error) { print("djhgfjdfhjg ${error}"); iscategroyloading = false; notifyListeners(); }, (response) { print("jdshfjghdhfjhgjd"); categoryList = response.data!; iscategroyloading = false; notifyListeners(); }, ); } Future getSubcategory(BuildContext context, String? id) async { var data = {"parentId": id}; print("kdjhgkjfkjgkj ${id}"); var result = await _homeRepo.getSubcategory(data, context); return result.fold( (error) { print("djhgfjdfhjg ${error}"); iscategroyloading = false; notifyListeners(); }, (response) { print("dsfdgdfgfhfghjghjghjghjhkghj"); categoryList = response!; iscategroyloading = false; notifyListeners(); }, ); } List categoriesss = []; ProductCategoryModel? selectedCategory; Future getCategoryByLevel() async { categoriesss.clear(); final result = await _homeRepo.getCategoryByLevel({}); result.fold( (error) { print("Error fetching categories: $error"); notifyListeners(); }, (categoryList) { if (categoryList.isNotEmpty) { final categories = [ProductCategoryModel(id: "all", name: "ALL")]; categories.addAll(categoryList.cast()); categoriesss = categories; } else { print("No categories found."); } notifyListeners(); // Notify UI after update }, ); } void setSelectedCategory(ProductCategoryModel category) { selectedCategory = category; notifyListeners(); } //similarProduct List banner = []; bool isBannerLoading = true; Future getBanners(BuildContext context) async { var data = {}; var result = await _homeRepo.getBanners(data, context); return result.fold( (error) { isBannerLoading = false; notifyListeners(); }, (response) { banner = response.data!; isBannerLoading = false; notifyListeners(); }, ); } Future customerLogOut(BuildContext context) async { context.showLoader(show: true); var data = {}; try { var result = await _homeRepo.customerLogOut(data); context.showLoader(show: false); return result.fold( (error) { // Show error Snackbar ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(error.message), backgroundColor: Colors.red, ), ); return false; // Login failed }, (response) async { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Store created successful!"), backgroundColor: Colors.green, ), ); await SharedPrefUtils.clear(); context.clearAndPush(routePath: MyRoutes.SIGNUP); return true; }, ); } catch (e) { context.showLoader(show: false); print("Unexpected error: $e"); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Something went wrong. Please try again."), backgroundColor: Colors.red, ), ); return false; } } int _activeIndex = 0; int get activeIndex => _activeIndex; void setActiveIndex(int index) { _activeIndex = index; notifyListeners(); } // Mock API call Future addToWish(BuildContext context, String productId) async { var data = { "productId": productId, }; try { var result = await _homeRepo.addToWish(data); return result.fold( (error) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(error.message), backgroundColor: Colors.red, ), ); return false; }, (response) { iswishloading = false; Fluttertoast.showToast( msg: "Wishlist updated successfully!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.green, textColor: Colors.white, fontSize: 14.0, ); return true; }, ); } catch (e) { return false; } } Set wishlist = {}; bool iswishloading = false; Future toggleWishlist(BuildContext context, String productId) async { iswishloading = true; notifyListeners(); try { if (wishlist.contains(productId)) { wishlist.remove(productId); iswishloading = false; } else { var result = await addToWish(context, productId); wishlist.add(productId); } iswishloading = false; notifyListeners(); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Something went wrong. Please try again."), backgroundColor: Colors.red, ), ); } } // void toggleWishlist1(String productId) // { // for (var product in products) { // if (product.id == productId) { // product.isInWishlist = !product.isInWishlist; // Toggle value // notifyListeners(); // Refresh UI // break; // } // } // } // Future addToCart(BuildContext context, String productId) async // { // //context.showLoader(show: true); // var data = // { // "productId": productId, "quantity": 1}; // try { // var result = await _homeRepo.addToCart(data); // return result.fold( // (error) { // ScaffoldMessenger.of(context).showSnackBar( // SnackBar( // content: Text(error.message), // backgroundColor: Colors.red, // ), // ); // return false; // }, // (response) { // Fluttertoast.showToast( // msg: "Wishlist updated successfully!", // toastLength: Toast.LENGTH_SHORT, // gravity: ToastGravity.BOTTOM, // backgroundColor: Colors.green, // textColor: Colors.white, // fontSize: 14.0, // ); // return true; // }, // ); // } catch (e) { // return false; // } // } Set cartItems = {}; Map isLoading = {}; bool isLoadingCart = false; bool iscardAdded = false; Future addToCart( BuildContext context, String productId, int quantity) async { //if (cartItems.contains(productId)) return; // Prevent duplicate additions isLoadingCart = true; isLoading[productId] = true; notifyListeners(); // Notify UI to show loading indicator var data = {"productId": productId, "quantity": quantity}; try { var result = await _homeRepo.addToCart(data); result.fold( (error) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(error.message), backgroundColor: Colors.red, ), ); }, (response) { cartItems.add(productId); // Add product to cart Fluttertoast.showToast( msg: "Added to cart successfully!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.green, textColor: Colors.white, fontSize: 14.0, ); iscardAdded = true; notifyListeners(); // Update UI after adding to cart }, ); } catch (e) { Fluttertoast.showToast( msg: "Insufficient stock!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, backgroundColor: Colors.red, textColor: Colors.white, fontSize: 14.0, ); } finally { isLoadingCart = false; isLoading[productId] = false; notifyListeners(); // Ensure UI updates after operation } } List countList = []; String lastImageurl = ''; Future addToWithCart(BuildContext context, String productId, BestDeal bestdealproduct, url) async { isLoading[productId] = true; notifyListeners(); var data = {"productId": productId, "quantity": 1}; try { var result = await _homeRepo.addToCart(data); result.fold( (error) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(error.message), backgroundColor: Colors.red, ), ); }, (response) { countList.add(bestdealproduct); lastImageurl = url; cartItems.add(productId); // Add product to cart Fluttertoast.showToast( msg: "Added to cart successfully!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.green, textColor: Colors.white, fontSize: 14.0, ); notifyListeners(); // Update UI after adding to cart }, ); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Product already added"), backgroundColor: Colors.red, ), ); } finally { isLoading[productId] = false; notifyListeners(); // Ensure UI updates after operation } } List productDatum = []; String productDatumlastImageurl = ''; Future addToCartWithWishlist(BuildContext context, String productId, ProductDatum productdataum, url) async { isLoading[productId] = true; notifyListeners(); var data = {"productId": productId, "quantity": 1}; try { var result = await _homeRepo.addToCart(data); result.fold( (error) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(error.message), backgroundColor: Colors.red, ), ); }, (response) { productDatum.add(productdataum); productDatumlastImageurl = url; cartItems.add(productId); // Add product to cart Fluttertoast.showToast( msg: "Added to cart successfully!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.green, textColor: Colors.white, fontSize: 14.0, ); notifyListeners(); // Update UI after adding to cart }, ); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Something went wrong"), backgroundColor: Colors.red, ), ); } finally { isLoading[productId] = false; notifyListeners(); // Ensure UI updates after operation } } bool isWishListItemLoadingg = true; List wishListItem = []; int totalItems = 0; Future gettAllWishList(BuildContext context) async { var data = {}; try { var result = await _homeRepo.gettAllWishList(data); return result.fold( (error) { print("sdfgdfgfdggf"); isWishListItemLoadingg = false; notifyListeners(); }, (response) { print("lsjfdgjsdfsdfgkdfkgkjkf"); wishListItem = response.items!; totalItems = response.totalItems; isWishListItemLoadingg = false; notifyListeners(); }, ); } catch (e) { isWishListItemLoadingg = false; notifyListeners(); print("jdsgkdfkghk"); } } ////////////////////////////// product increase //////////////////////////////////// int quantitys = 1; double _unitPrice = 0.0; double _totalPrice = 0.0; int get quantity => quantitys; double get totalPrice => _totalPrice; void setProductPrice(double price) { _unitPrice = price; _totalPrice = _unitPrice * quantitys; notifyListeners(); } int productQuantity = 0; // void increaseQuantity() // { // if(quantity<10) // if (_quantity < 10) // { // // Limit to 10 // _quantity++; // _totalPrice = _unitPrice * _quantity; // notifyListeners(); // } // { // Fluttertoast.showToast( // msg: "Sorry cart successfully!", // toastLength: Toast.LENGTH_SHORT, // gravity: ToastGravity.BOTTOM, // backgroundColor: Colors.green, // textColor: Colors.white, // fontSize: 14.0, // ); // } // } void increaseQuantity() { int maxAllowed = productQuantity >= 100 ? 10 : productQuantity; // Max limit based on stock if (quantitys < maxAllowed) { quantitys++; _totalPrice = _unitPrice * quantitys; notifyListeners(); } else { Fluttertoast.showToast( msg: "Sorry, you can only add up to $maxAllowed items!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: Colors.red, textColor: Colors.white, fontSize: 14.0, ); } } void decreaseQuantity() { if (quantitys > 1) { quantitys--; _totalPrice = _unitPrice * quantitys; notifyListeners(); } } //////////////////////////////////////////////////////////////similar product////////////////////// List similarProductlist = []; Future similarProductprovider(BuildContext context, String id) async { var data = {}; var result = await _homeRepo.similarProduct(data, context, id); return result.fold( (error) { // isLoadingg = false; notifyListeners(); }, (response) { print("jkshdfkhdjkfkjdfkgkjdfjgk ${response}"); similarProductlist = response! as List; // isLoadingg = false; notifyListeners(); }, ); } ///////////////////////////////////////////////////// all filter //////////////////////// int _selectedIndex = 0; int get selectedIndex => _selectedIndex; void setSelectedIndex(BuildContext context, int index) { _selectedIndex = index; notifyListeners(); } Future determinePosition() async { bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { return; } LocationPermission permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { return; } Position position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, ); LatLng currentLatLng = LatLng(position.latitude, position.longitude); _getAddressFromLatLng(position.latitude, position.longitude); } String googleApiKey = "AIzaSyAi3_Dls63iGs7Nccgdm-4FkS0rhT03-4U"; String getCurrentAdd = ''; Future _getAddressFromLatLng(double lat, double lng) async { final String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lng&key=$googleApiKey"; try { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { final data = json.decode(response.body); if (data["status"] == "OK") { var result = data["results"][0]; // First result is most accurate // _RoadController.text = result["formatted_address"]; List components = result["address_components"]; String roadName = ""; String colony = ""; String buildingName = ""; String pincode = ""; for (var component in components) { List types = component["types"]; if (types.contains("route")) { roadName = component["long_name"]; // Road Name } else if (types.contains("sublocality_level_1") || types.contains("locality")) { colony = component["long_name"]; // Colony Name } else if (types.contains("premise") || types.contains("street_number")) { buildingName = component["long_name"]; // Building Name } else if (types.contains("postal_code")) { pincode = component["long_name"]; // Extract Pin Code } } // setState(() { // // _address = formattedAddress; // _roadName = roadName; // _colony = colony; // _buildingName = buildingName; // }); getCurrentAdd = result["formatted_address"] + pincode; notifyListeners(); print( "Full Address: ${result["formatted_address"]} ${response.body} sdfsgd ${pincode}"); print("Road Name: $roadName"); print("Colony: $colony"); print("Building Name: $buildingName"); } else {} } else {} } catch (e) { print("Error fetching address: $e"); } } List _suggestions = []; Timer? _debounce; List get suggestions => _suggestions; /// Debounced Search API Call void searchProducts(String query, BuildContext context) { if (_debounce?.isActive ?? false) _debounce!.cancel(); _debounce = Timer(const Duration(milliseconds: 500), () async { if (query.isNotEmpty) { _fetchSuggestions(query, context); } else { _suggestions.clear(); notifyListeners(); } }); } /// Simulated API Call (Replace with real API) Future _fetchSuggestions(String query, context) async { _suggestions.clear(); notifyListeners(); var data = { "search": query, "page": 1, "limit": 10, }; var result = await _homeRepo.getAllProduct(data, context, ''); return result.fold( (error) { notifyListeners(); }, (response) { print("lkdfjglkfdglkh ${response.data}"); _suggestions.addAll(response.data as Iterable); notifyListeners(); }, ); } void clearSuggestions() { _suggestions.clear(); notifyListeners(); } }