using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Application.Common.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace CMSMicroservice.Application.TagCQ.Queries.GetAllTags;

public class GetAllTagsQueryHandler : IRequestHandler<GetAllTagsQuery, GetAllTagsResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<GetAllTagsQueryHandler> _logger;

    public GetAllTagsQueryHandler(
        IApplicationDbContext context,
        ILogger<GetAllTagsQueryHandler> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<GetAllTagsResponseDto> Handle(GetAllTagsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.Tags
            .Where(x => !x.IsDeleted);

        // فیلترها
        if (request.IsActive.HasValue)
        {
            query = query.Where(x => x.IsActive == request.IsActive.Value);
        }

        if (!string.IsNullOrEmpty(request.SearchTerm))
        {
            var searchTerm = request.SearchTerm.ToLower();
            query = query.Where(x => x.Name.ToLower().Contains(searchTerm) 
                || x.Title.ToLower().Contains(searchTerm));
        }

        var totalCount = await query.CountAsync(cancellationToken);

        // مرتب‌سازی
        query = request.OrderByDescending
            ? query.OrderByDescending(x => x.SortOrder).ThenByDescending(x => x.Created)
            : query.OrderBy(x => x.SortOrder).ThenBy(x => x.Created);

        // صفحه‌بندی
        var tags = await query
            .Skip((request.PageNumber - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(x => new TagDto
            {
                Id = x.Id,
                Name = x.Name,
                Title = x.Title,
                Description = x.Description,
                IsActive = x.IsActive,
                SortOrder = x.SortOrder,
                ProductCount = x.ProductTags.Count(p => !p.IsDeleted),
                Created = x.Created
            })
            .ToListAsync(cancellationToken);

        var metaData = new MetaData
        {
            TotalCount = totalCount,
            PageSize = request.PageSize,
            CurrentPage = request.PageNumber,
            TotalPage = (int)Math.Ceiling(totalCount / (double)request.PageSize),
            HasNext = request.PageNumber < (int)Math.Ceiling(totalCount / (double)request.PageSize),
            HasPrevious = request.PageNumber > 1
        };

        _logger.LogInformation("Retrieved {Count} tags. Total: {Total}", tags.Count, totalCount);

        return new GetAllTagsResponseDto
        {
            MetaData = metaData,
            Tags = tags
        };
    }
}
