using CMSMicroservice.Application.Common.Exceptions;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Enums;
using MediatR;

namespace CMSMicroservice.Application.PackageCQ.Queries.GetUserPackageStatus;

public class GetUserPackageStatusQueryHandler : IRequestHandler<GetUserPackageStatusQuery, UserPackageStatusDto>
{
    private readonly IApplicationDbContext _context;

    public GetUserPackageStatusQueryHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<UserPackageStatusDto> Handle(GetUserPackageStatusQuery request, CancellationToken cancellationToken)
    {
        // 1. دریافت اطلاعات کاربر
        var user = await _context.Users
            .Include(u => u.UserWallets)
            .FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);

        if (user == null)
            throw new NotFoundException(nameof(User), request.UserId);

        // 2. دریافت عضویت باشگاه
        var clubMembership = await _context.ClubMemberships
            .FirstOrDefaultAsync(c => c.UserId == user.Id && c.IsActive, cancellationToken);

        // 3. دریافت آخرین سفارش پکیج
        var lastPackageOrder = await _context.UserOrders
            .Where(o => o.UserId == user.Id && o.PackageId != null)
            .OrderByDescending(o => o.Created)
            .FirstOrDefaultAsync(cancellationToken);

        // 4. بارگذاری پکیج پایه برای بررسی شرایط فعالسازی
        var basePackage = await _context.Packages
            .FirstOrDefaultAsync(p => p.IsBasePackage && !p.IsDeleted, cancellationToken);

        var wallet = user.UserWallets.FirstOrDefault();

        // 5. بررسی شرایط فعالسازی باشگاه
        var canActivate =
            user.PackagePurchaseMethod != PackagePurchaseMethod.None &&
            clubMembership == null &&
            wallet != null &&
            basePackage != null &&
            wallet.Balance >= basePackage.Price;

        return new UserPackageStatusDto
        {
            UserId = user.Id,
            PackagePurchaseMethod = user.PackagePurchaseMethod.ToString(),
            HasPurchasedPackage = user.PackagePurchaseMethod != PackagePurchaseMethod.None,
            IsClubMemberActive = clubMembership?.IsActive ?? false,
            WalletBalance = wallet?.Balance ?? 0,
            DiscountBalance = wallet?.DiscountBalance ?? 0,
            CanActivateClubMembership = canActivate,
            LastOrderNumber = lastPackageOrder?.Id.ToString(),
            LastPurchaseDate = lastPackageOrder?.Created
        };
    }
}
