using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Primitives; namespace FrontOffice.Main.Utilities; public enum ProductSortOption { PriceDesc, PriceAsc, Newest, Title } /// /// وضعیت لیست فروشگاه در query string — فقط برای /products و /discount-store. /// public sealed class ShopListQueryState { public string Query { get; init; } = string.Empty; public string? Sort { get; init; } public long? CategoryId { get; init; } public int Pages { get; init; } = 1; public static ShopListQueryState Parse(Uri uri) { var q = QueryHelpers.ParseQuery(uri.Query); return new ShopListQueryState { Query = GetString(q, "q") ?? string.Empty, Sort = GetString(q, "sort"), CategoryId = GetLong(q, "category"), Pages = Math.Max(1, GetInt(q, "pages") ?? 1) }; } public string ToRelativeUrl(string path) { var dict = new Dictionary(); if (!string.IsNullOrWhiteSpace(Query)) dict["q"] = Query.Trim(); if (!string.IsNullOrWhiteSpace(Sort) && !string.Equals(Sort, "price-desc", StringComparison.OrdinalIgnoreCase)) dict["sort"] = Sort; if (CategoryId is > 0) dict["category"] = CategoryId.Value.ToString(); if (Pages > 1) dict["pages"] = Pages.ToString(); return dict.Count == 0 ? path : QueryHelpers.AddQueryString(path, dict!); } public bool Matches(ShopListQueryState other) => string.Equals(Query?.Trim() ?? "", other.Query?.Trim() ?? "", StringComparison.Ordinal) && string.Equals(NormalizeSort(Sort), NormalizeSort(other.Sort), StringComparison.OrdinalIgnoreCase) && CategoryId == other.CategoryId && Pages == other.Pages; public static string NormalizeSort(string? sort) => string.IsNullOrWhiteSpace(sort) ? "price-desc" : sort.Trim().ToLowerInvariant(); public static string ToSortKey(ProductSortOption option) => option switch { ProductSortOption.PriceAsc => "price-asc", ProductSortOption.Newest => "newest", ProductSortOption.Title => "title", _ => "price-desc" }; public static ProductSortOption ParseSortOption(string? sort) => NormalizeSort(sort) switch { "price-asc" => ProductSortOption.PriceAsc, "newest" => ProductSortOption.Newest, "title" => ProductSortOption.Title, _ => ProductSortOption.PriceDesc }; public static string ToApiSortBy(ProductSortOption option) => option switch { ProductSortOption.PriceAsc => "price asc", ProductSortOption.Newest => "id desc", ProductSortOption.Title => "title asc", _ => "price desc" }; private static string? GetString(Dictionary q, string key) => q.TryGetValue(key, out var v) ? v.FirstOrDefault() : null; private static long? GetLong(Dictionary q, string key) => long.TryParse(GetString(q, key), out var n) ? n : null; private static int? GetInt(Dictionary q, string key) => int.TryParse(GetString(q, key), out var n) ? n : null; }