using System.Linq;
using Kavita.Models.DTOs.Filtering;
using Kavita.Models.Entities;
using Microsoft.EntityFrameworkCore;
namespace Kavita.Database.Extensions;
public static class SeriesSortExtensions
{
///
/// Applies the correct sort based on
///
///
///
///
///
public static IQueryable Sort(this IQueryable query, int userId, SortOptions? sortOptions)
{
// If no sort options, default to using SortName
sortOptions ??= new SortOptions()
{
IsAscending = true,
SortField = SortField.SortName
};
query = sortOptions.SortField switch
{
SortField.SortName => query.DoOrderBy(s => s.SortName.ToLower(), sortOptions),
SortField.CreatedDate => query.DoOrderBy(s => s.Created, sortOptions),
SortField.LastModifiedDate => query.DoOrderBy(s => s.LastModified, sortOptions),
SortField.LastChapterAdded => query.DoOrderBy(s => s.LastChapterAdded, sortOptions),
SortField.TimeToRead => query.DoOrderBy(s => s.AvgHoursToRead, sortOptions),
SortField.ReleaseYear => query.DoOrderBy(s => s.Metadata.ReleaseYear, sortOptions),
SortField.ReadProgress => query.DoOrderBy(s => s.Progress.Where(p => p.SeriesId == s.Id && p.AppUserId == userId)
.Select(p => p.LastModifiedUtc)
.Max(), sortOptions),
SortField.AverageRating => query.DoOrderBy(s => s.ExternalSeriesMetadata.ExternalRatings
.Where(p => p.SeriesId == s.Id).Average(p => p.AverageScore), sortOptions),
SortField.UserRating => query.DoOrderBy(s => s.Ratings.Where(r => r.SeriesId == s.Id && r.AppUserId == userId).Max(r => r.Rating), sortOptions)
.ThenBy(s => s.SortName.ToLower()),
SortField.Random => query.DoOrderBy(s => EF.Functions.Random(), sortOptions),
_ => query
};
return query;
}
}