using System.Linq.Expressions;
using System.Linq.Dynamic.Core;
using CMSMicroservice.Domain.Common;

namespace CMSMicroservice.Application.Common.Extensions;

public static class SortByExtensions
{
    public static IQueryable<TSource> ApplyOrder<TSource>(this IQueryable<TSource> source,
        string? sortBy) where TSource : BaseAuditableEntity
    {
        if (sortBy is null or "")
        {
            return source.OrderByDescending(p => p.Created);
        }

        return source.OrderBy(NormalizeSortBy(sortBy));
    }

    /// <summary>
    /// موجودی‌دارها اول، سپس سورت درخواستی کاربر (یا Created desc اگر SortBy خالی باشد).
    /// </summary>
    public static IQueryable<TSource> ApplyOrderWithInStockPriority<TSource>(
        this IQueryable<TSource> source,
        string? sortBy,
        Expression<Func<TSource, bool>> isInStock) where TSource : BaseAuditableEntity
    {
        var ordered = source.OrderByDescending(isInStock);
        if (string.IsNullOrWhiteSpace(sortBy))
            return ordered.ThenByDescending(p => p.Created);

        return ordered.ThenBy(NormalizeSortBy(sortBy));
    }

    /// <summary>
    /// Dynamic LINQ treats "-Created" as unary minus on DateTime (invalid).
    /// Project convention: leading '-' means descending sort.
    /// </summary>
    private static string NormalizeSortBy(string sortBy)
    {
        sortBy = sortBy.Trim();
        if (sortBy.StartsWith('-') && sortBy.Length > 1)
        {
            return $"{sortBy[1..]} descending";
        }

        if (sortBy.StartsWith('+') && sortBy.Length > 1)
        {
            return $"{sortBy[1..]} ascending";
        }

        return sortBy;
    }
}
