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

namespace CMSMicroservice.Application.PublicMessageCQ.Queries.GetAllMessages;

public class GetAllMessagesQueryHandler : IRequestHandler<GetAllMessagesQuery, GetAllMessagesResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<GetAllMessagesQueryHandler> _logger;

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

    public async Task<GetAllMessagesResponseDto> Handle(GetAllMessagesQuery request, CancellationToken cancellationToken)
    {
        var now = DateTime.Now;

        // Query پایه
        var query = _context.PublicMessages
            .Where(x => !x.IsDeleted);

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

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

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

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

        if (request.EndDate.HasValue)
        {
            query = query.Where(x => x.Created <= request.EndDate.Value);
        }

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

        // تعداد کل
        var totalCount = await query.CountAsync(cancellationToken);

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

        // صفحه‌بندی
        var messages = await query
            .Skip((request.PageNumber - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(x => new AdminPublicMessageDto
            {
                Id = x.Id,
                Title = x.Title,
                Content = x.Content,
                Type = x.Type,
                TypeName = GetTypeName(x.Type),
                Priority = x.Priority,
                PriorityName = GetPriorityName(x.Priority),
                IsActive = x.IsActive,
                StartsAt = x.StartsAt,
                ExpiresAt = x.ExpiresAt,
                CreatedByUserId = x.CreatedByUserId,
                ViewCount = x.ViewCount,
                LinkUrl = x.LinkUrl,
                LinkText = x.LinkText,
                Created = x.Created,
                LastModified = x.LastModified,
                IsExpired = x.ExpiresAt < now
            })
            .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} messages. Total: {Total}",
            messages.Count,
            totalCount
        );

        return new GetAllMessagesResponseDto
        {
            MetaData = metaData,
            Messages = messages
        };
    }

    private static string GetTypeName(MessageType type)
    {
        return type switch
        {
            MessageType.Announcement => "اطلاعیه",
            MessageType.News => "اخبار",
            MessageType.Warning => "هشدار",
            MessageType.Promotion => "تبلیغات",
            MessageType.SystemUpdate => "به‌روزرسانی سیستم",
            MessageType.Event => "رویداد",
            _ => "نامشخص"
        };
    }

    private static string GetPriorityName(MessagePriority priority)
    {
        return priority switch
        {
            MessagePriority.Low => "کم",
            MessagePriority.Medium => "متوسط",
            MessagePriority.High => "بالا",
            MessagePriority.Urgent => "فوری",
            _ => "نامشخص"
        };
    }
}
