using MediatR;
using TakeoutSaaS.Application.App.Personal.Dto;
using TakeoutSaaS.Application.App.Personal.Queries;
using TakeoutSaaS.Application.App.Personal.Services;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Results;

namespace TakeoutSaaS.Application.App.Personal.Handlers;

/// <summary>
/// 分页查询个人消息摘要处理器。
/// </summary>
public sealed class SearchPersonalNotificationsQueryHandler(
    PersonalContextService personalContextService,
    ITenantNotificationRepository tenantNotificationRepository)
    : IRequestHandler<SearchPersonalNotificationsQuery, PagedResult<PersonalNotificationDto>>
{
    /// <summary>
    /// 处理查询。
    /// </summary>
    /// <param name="request">查询请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>消息摘要分页结果。</returns>
    public async Task<PagedResult<PersonalNotificationDto>> Handle(SearchPersonalNotificationsQuery request, CancellationToken cancellationToken)
    {
        // 1. 获取上下文并解析分页
        var context = personalContextService.GetRequiredContext();
        var page = request.Page <= 0 ? 1 : request.Page;
        var pageSize = request.PageSize <= 0 ? 20 : Math.Min(request.PageSize, 50);

        // 2. 查询通知
        var notifications = await tenantNotificationRepository.SearchAsync(
            context.TenantId,
            severity: null,
            unreadOnly: request.UnreadOnly,
            from: null,
            to: null,
            cancellationToken);

        // 3. 排序分页并映射
        var ordered = notifications.OrderByDescending(static x => x.SentAt).ToList();
        var items = ordered
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .Select(static x => new PersonalNotificationDto
            {
                NotificationId = x.Id,
                Title = x.Title,
                Category = x.Severity.ToString().ToLowerInvariant(),
                IsRead = x.ReadAt.HasValue,
                SentAt = x.SentAt
            })
            .ToList();

        // 4. 返回结果
        return new PagedResult<PersonalNotificationDto>(items, page, pageSize, ordered.Count);
    }
}
