using MediatR;
using TakeoutSaaS.Application.App.SystemParameters.Dto;
using TakeoutSaaS.Application.App.SystemParameters.Queries;
using TakeoutSaaS.Domain.SystemParameters.Repositories;
using TakeoutSaaS.Shared.Abstractions.Results;

namespace TakeoutSaaS.Application.App.SystemParameters.Handlers;

/// <summary>
/// 系统参数列表查询处理器。
/// </summary>
public sealed class SearchSystemParametersQueryHandler(ISystemParameterRepository repository)
    : IRequestHandler<SearchSystemParametersQuery, PagedResult<SystemParameterDto>>
{
    private readonly ISystemParameterRepository _repository = repository;

    /// <inheritdoc />
    public async Task<PagedResult<SystemParameterDto>> Handle(SearchSystemParametersQuery request, CancellationToken cancellationToken)
    {
        var parameters = await _repository.SearchAsync(request.Keyword, request.IsEnabled, cancellationToken);

        var sorted = ApplySorting(parameters, request.SortBy, request.SortDescending);
        var paged = sorted
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .ToList();

        var items = paged.Select(MapToDto).ToList();
        return new PagedResult<SystemParameterDto>(items, request.Page, request.PageSize, parameters.Count);
    }

    private static IOrderedEnumerable<Domain.SystemParameters.Entities.SystemParameter> ApplySorting(
        IReadOnlyCollection<Domain.SystemParameters.Entities.SystemParameter> parameters,
        string? sortBy,
        bool sortDescending)
    {
        return sortBy?.ToLowerInvariant() switch
        {
            "key" => sortDescending
                ? parameters.OrderByDescending(x => x.Key)
                : parameters.OrderBy(x => x.Key),
            "sortorder" => sortDescending
                ? parameters.OrderByDescending(x => x.SortOrder)
                : parameters.OrderBy(x => x.SortOrder),
            "updatedat" => sortDescending
                ? parameters.OrderByDescending(x => x.UpdatedAt ?? x.CreatedAt)
                : parameters.OrderBy(x => x.UpdatedAt ?? x.CreatedAt),
            "isenabled" => sortDescending
                ? parameters.OrderByDescending(x => x.IsEnabled)
                : parameters.OrderBy(x => x.IsEnabled),
            _ => sortDescending
                ? parameters.OrderByDescending(x => x.CreatedAt)
                : parameters.OrderBy(x => x.CreatedAt)
        };
    }

    private static SystemParameterDto MapToDto(Domain.SystemParameters.Entities.SystemParameter parameter) => new()
    {
        Id = parameter.Id,
        TenantId = parameter.TenantId,
        Key = parameter.Key,
        Value = parameter.Value,
        Description = parameter.Description,
        SortOrder = parameter.SortOrder,
        IsEnabled = parameter.IsEnabled,
        CreatedAt = parameter.CreatedAt,
        UpdatedAt = parameter.UpdatedAt
    };
}
