using Application.Abstractions.Messaging;
using Application.Abstractions.Data;
using Domain.Entities.Wallets.ValueObject;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Admin.Member.List.Get;

public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response?>
{
    public async Task<Response?> Handle(Query request, CancellationToken ct)
    {
        var member = await db.Member.AsNoTracking().Include(x => x.MemberGrade).Include(x => x.MemberStats).Include(x => x.Channel).Include(x => x.Wallet).ThenInclude(w => w!.Balances).FirstOrDefaultAsync(x => x.ID == request.Id, ct);

        if (member is null)
        {
            return null;
        }

        return new Response
        {
            ID = member.ID,
            SID = member.SID,
            Email = member.Email,
            Name = member.Name,
            FullName = member.FullName,
            FirstName = member.FirstName,
            LastName = member.LastName,
            Phone = member.Phone,
            Birthday = member.Birthday,
            Gender = member.Gender,
            Summary = member.Summary,
            Intro = member.Intro,
            Thumb = member.Thumb,
            Icon = member.Icon,
            MemberGradeID = member.MemberGradeID,
            GradeName = member.MemberGrade?.KorName,
            IsEmailVerified = member.IsEmailVerified,
            IsAuthCertified = member.IsAuthCertified,
            IsDenied = member.IsDenied,
            IsAdmin = member.IsAdmin,
            IsWithdraw = member.IsWithdraw,
            IsCreator = member.IsCreator,
            DeviceInfo = member.DeviceInfo,
            SignupIP = member.SignupIP,
            LastLoginIp = member.LastLoginIp,
            IpAddress = member.IpAddress,
            UserAgent = member.UserAgent,
            LastLoginAt = member.LastLoginAt,
            EmailVerifiedAt = member.EmailVerifiedAt,
            AuthCertifiedAt = member.AuthCertifiedAt,
            DeniedAt = member.DeniedAt,
            DeletedAt = member.DeletedAt,
            UpdatedAt = member.UpdatedAt,
            CreatedAt = member.CreatedAt,
            Following = member.MemberStats?.FollowingCount ?? 0,
            Followed = member.MemberStats?.FollowerCount ?? 0,
            Channel = member.Channel != null ? new Response.ChannelInfo
            {
                SID = member.Channel.SID,
                Name = member.Channel.Name,
                Handle = member.Channel.Handle,
                YouTubeUrl = member.Channel.YouTubeUrl
            } : null,
            Wallet = new Response.WalletInfo
            {
                Balance = (long)(member.Wallet?.GetTotalAvailable().Value ?? 0),
                CreditBalance = (long)(member.Wallet?.GetBalance(WalletBalanceType.Locked).Value ?? 0)
            }
        };
    }
}