using Application.Abstractions.Messaging;
using Application.Abstractions.Cache;
using Application.Abstractions.Crypto;

namespace Application.Features.Api.Crypto.Orderbook.Get;

public sealed class Handler(IUpbitClient upbit, ICacheService cache) : IQueryHandler<Query, Response>
{
    private static readonly TimeSpan _cacheExpiry = TimeSpan.FromSeconds(5);

    public async Task<Response> Handle(Query request, CancellationToken ct)
    {
        var cacheKey = CacheKeys.CryptoOrderbook(request.Market);

        // 캐시 확인
        var cached = await cache.GetAsync<Response>(cacheKey, ct);
        if (cached is not null)
        {
            return cached;
        }

        // Upbit REST API 호출
        var orderbooks = await upbit.GetOrderbookAsync([request.Market], ct);
        if (orderbooks.Count == 0)
        {
            return new Response(0, 0, [], 0, 0);
        }

        var o = orderbooks[0];
        var response = new Response(
            o.TotalAskSize,
            o.TotalBidSize,
            [..o.OrderbookUnits.Select(u => new Response.Unit(
                u.AskPrice,
                u.BidPrice,
                u.AskSize,
                u.BidSize
            ))],
            o.Timestamp,
            o.Level
        );

        // Redis 캐시 저장 (5초)
        await cache.SetAsync(cacheKey, response, _cacheExpiry, ct);

        return response;
    }
}