using System.Linq.Expressions;
using FoodsharingSiegen.Contracts.Entity;
using FoodsharingSiegen.Contracts.Enums;
using FoodsharingSiegen.Contracts.Model;

namespace FoodsharingSiegen.Shared.Helper
{
    public static class FilterHelper
    {
        #region Public Method ApplyFilter

        /// <summary>
        ///     Filters the given prospect list based on the provided filter criteria.
        /// </summary>
        /// <param name="prospectList">
        ///     The list of prospects to be filtered. Can be null.
        /// </param>
        /// <param name="filter">
        ///     The filter criteria used to narrow down the prospect list.
        /// </param>
        /// <returns>
        ///     A filtered list of prospects that meet the criteria specified in the filter.
        /// </returns>
        public static List<Prospect> ApplyFilter(this List<Prospect>? prospectList, ProspectFilter filter)
        {
            if (prospectList == null) return [];

            var filterListQ = prospectList.AsQueryable();
            if (!string.IsNullOrWhiteSpace(filter.Text))
                filterListQ = filterListQ
                    .Where(x =>
                        x.Name.Contains(filter.Text, StringComparison.OrdinalIgnoreCase) ||
                        (!string.IsNullOrWhiteSpace(x.Memo) && x.Memo.Contains(filter.Text, StringComparison.OrdinalIgnoreCase) == true) ||
                        x.FsId.ToString().Contains(filter.Text, StringComparison.OrdinalIgnoreCase)).AsQueryable();

            // Show only prospect with missing StepIn Briefing
            if (filter.WithoutStepInBriefing)
                filterListQ = filterListQ.Where(x => x.Interactions.All(i => i.Type != InteractionType.StepInBriefing));
            
            // Show only prospect with missing IdCheck
            if (filter.WithoutIdCheck)
                filterListQ = filterListQ.Where(x => x.Interactions.All(i => i.Type != InteractionType.IdCheck));
            
            // Show only deleted prospects
            if (filter.DeletedOnly)
                filterListQ = filterListQ.Where(x => x.RecordState == RecordState.Archived);

            // Show only prospects with possible IdCheck
            if (filter.IdCheckPossible)
                filterListQ = filterListQ.Where(x => x.Images != null && x.Images.Count > 0);

            // No Activity Filter
            if (filter.NoActivity) 
                filterListQ = filterListQ.Where(x => DateTime.Now - x.Modified > TimeSpan.FromDays(180));
            
            // Recent Activity Filter
            if (filter.RecentActivity) 
                filterListQ = filterListQ.Where(x => DateTime.Now - x.Modified < TimeSpan.FromDays(180));

            return filterListQ.ToList();
        }

        public static List<Prospect> ApplySort(this List<Prospect>? prospectList, ProspectSortOption sortOption)
        {
            if (prospectList == null) return [];

            return sortOption switch
            {
                ProspectSortOption.NameAscending => prospectList.OrderBy(x => x.Name, StringComparer.OrdinalIgnoreCase).ToList(),
                ProspectSortOption.NameDescending => prospectList.OrderByDescending(x => x.Name, StringComparer.OrdinalIgnoreCase).ToList(),
                ProspectSortOption.ModifiedAscending => prospectList.OrderBy(x => x.Modified ?? x.Created).ToList(),
                ProspectSortOption.ModifiedDescending => prospectList.OrderByDescending(x => x.Modified ?? x.Created).ToList(),
                _ => prospectList
            };
        }

        #endregion
    }
}