using System.Collections.Concurrent; using FrontOffice.BFF.Products.Protobuf.Protos.Products; namespace FrontOffice.Main.Utilities; public record Product( long Id, string Title, string Description, string ImageUrl, long Price, int Discount = 0, int Rate = 0, int RemainingCount = 0); public class ProductService { private static readonly List _seed = new() { new(1, "ماسک پزشکی سه‌لایه", "ماسک سه‌لایه با فیلتراسیون بالا مناسب برای محیط‌های عمومی.", "/images/store/mask.jpg", 49000), new(2, "دستکش لاتکس", "دستکش لاتکس مناسب معاینات پزشکی، بدون پودر.", "/images/store/gloves.jpg", 89000), new(3, "محلول ضدعفونی کننده", "محلول ضدعفونی بر پایه الکل ۷۰٪ مناسب دست و سطوح.", "/images/store/sanitizer.jpg", 69000), new(4, "تب‌سنج دیجیتال", "تب‌سنج دیجیتال با دقت بالا و نمایشگر LCD.", "/images/store/thermometer.jpg", 299000), new(5, "فشارسنج دیجیتال", "فشارسنج بازویی دیجیتال با حافظه داخلی.", "/images/store/bp-monitor.jpg", 1259000) }; private readonly ConcurrentDictionary _cache = new(); private readonly ProductsContract.ProductsContractClient _client; public ProductService(ProductsContract.ProductsContractClient client) { _client = client; foreach (var p in _seed) _cache[p.Id] = p; } public async Task> GetProductsAsync(string? query = null) { try { var resp = await _client.GetAllProductsByFilterAsync(new GetAllProductsByFilterRequest { Filter = new GetAllProductsByFilterFilter { Title = query ?? string.Empty, Description = query ?? string.Empty, ShortInfomation = query ?? string.Empty, FullInformation = query ?? string.Empty } }); return MapAndCache(resp.Models); } catch { IEnumerable list = _cache.Values; if (!string.IsNullOrWhiteSpace(query)) { var q = query.Trim(); list = list.Where(p => p.Title.Contains(q, StringComparison.OrdinalIgnoreCase) || p.Description.Contains(q, StringComparison.OrdinalIgnoreCase)); } return list.OrderBy(p => p.Id).ToList(); } } public async Task GetByIdAsync(long id) { if (_cache.TryGetValue(id, out var cached)) return cached; try { // No single-get endpoint exposed: fetch list and pick var resp = await _client.GetAllProductsByFilterAsync(new GetAllProductsByFilterRequest { Filter = new GetAllProductsByFilterFilter() }); var list = MapAndCache(resp.Models); return list.FirstOrDefault(x => x.Id == id); } catch { _cache.TryGetValue(id, out var result); return result; } } private List MapAndCache(Google.Protobuf.Collections.RepeatedField models) { var list = new List(); foreach (var m in models) { var p = new Product( Id: m.Id, Title: m.Title ?? string.Empty, Description: m.Description ?? string.Empty, ImageUrl: string.IsNullOrWhiteSpace(m.ImagePath) ? string.Empty : UrlUtility.DownloadUrl + m.ImagePath, Price: m.Price, Discount: m.Discount, Rate: m.Rate, RemainingCount: m.RemainingCount ); _cache[p.Id] = p; list.Add(p); } return list; } }