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

namespace Application.Features.Api.Member.Wallet.GetMyTransactions;

public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
{
    public async Task<Response> Handle(Query request, CancellationToken ct)
    {
        var wallet = await db.Wallet.AsNoTracking().FirstOrDefaultAsync(w => w.MemberID == request.MemberID, ct);
        if (wallet is null)
        {
            return new Response
            {
                Total = 0,
                List = []
            };
        }

        var query = db.WalletTransaction.AsNoTracking().Where(t => t.WalletKey == wallet.WalletKey);

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

        var total = await query.CountAsync(ct);
        var skip = (request.Page - 1) * request.PerPage;

        var list = await query
            .OrderByDescending(t => t.ID)
            .Skip(skip)
            .Take(request.PerPage)
            .Select(t => new
            {
                t.ID,
                TxType = t.TxType.ToString(),
                BalanceType = t.BalanceType.ToString(),
                Amount = (long)t.Amount.Value,
                BalanceAfter = (long)t.BalanceAfter.Value,
                t.Reason,
                t.RefID,
                t.Memo,
                t.CreatedAt
            })
            .ToListAsync(ct);

        return new Response
        {
            Total = total,
            List = [..list.Select(t => new Response.Row
            {
                ID = t.ID,
                TxType = t.TxType,
                BalanceType = t.BalanceType,
                Amount = t.Amount,
                BalanceAfter = t.BalanceAfter,
                Reason = t.Reason,
                RefID = t.RefID,
                Memo = t.Memo,
                CreatedAt = t.CreatedAt
            })]
        };
    }
}