using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Admin.Crypto.News.Article.Search
{
    public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
    {
        public async Task<Response> Handle(Query request, CancellationToken ct)
        {
            var query = db.RssNewsArticle.AsNoTracking().Include(x => x.RssFeedSource).AsQueryable();

            if (request.RssFeedSourceID.HasValue)
            {
                query = query.Where(x => x.RssFeedSourceID == request.RssFeedSourceID.Value);
            }

            if (!string.IsNullOrWhiteSpace(request.Keyword))
            {
                var kw = request.Keyword.Trim();
                query = query.Where(x => x.Title.Contains(kw) || (x.Description != null && x.Description.Contains(kw)));
            }

            var total = await query.CountAsync(ct);

            var list = await query
                .OrderByDescending(x => x.PublishedAt ?? x.CreatedAt)
                .Skip((request.PageNum - 1) * request.PerPage)
                .Take(request.PerPage)
                .Select(x => new
                {
                    x.ID,
                    FeedSourceName = x.RssFeedSource.Name,
                    x.Title,
                    x.Author,
                    x.Link,
                    x.PublishedAt,
                    x.CreatedAt
                })
                .ToListAsync(ct);

            var startNum = total - ((request.PageNum - 1) * request.PerPage);

            return new Response(
                total,
                [..list.Select((c, i) => new Response.Row(
                    Num: startNum - i,
                    c.ID,
                    c.FeedSourceName,
                    c.Title,
                    c.Author,
                    c.Link,
                    c.PublishedAt,
                    c.CreatedAt
                ))]
            );
        }
    }
}