using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Primitives;

namespace FrontOffice.Main.Utilities;

public enum ProductSortOption
{
    PriceDesc,
    PriceAsc,
    Newest,
    Title
}

/// <summary>
/// وضعیت لیست فروشگاه در query string — فقط برای /products و /discount-store.
/// </summary>
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<string, string?>();
        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<string, StringValues> q, string key) =>
        q.TryGetValue(key, out var v) ? v.FirstOrDefault() : null;

    private static long? GetLong(Dictionary<string, StringValues> q, string key) =>
        long.TryParse(GetString(q, key), out var n) ? n : null;

    private static int? GetInt(Dictionary<string, StringValues> q, string key) =>
        int.TryParse(GetString(q, key), out var n) ? n : null;
}
