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

namespace Application.Features.Api.Crypto.Candle.GetDays;

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

    public async Task<Response> Handle(Query request, CancellationToken ct)
    {
        var count = Math.Clamp(request.Count, 1, 200);
        var cacheKey = CacheKeys.CryptoCandle(request.Market, "d");

        // 캐시 확인
        var cached = await cache.GetAsync<List<Response.CandleItem>>(cacheKey, ct);
        if (cached is { Count: > 0 })
        {
            return new Response(cached);
        }

        // Upbit REST API 호출
        var candles = await upbit.GetDayCandlesAsync(request.Market, count, ct);

        var items = candles
            .OrderBy(c => c.CandleDateTimeUtc)
            .Select(c => new Response.CandleItem(
                c.CandleDateTimeUtc,
                c.CandleDateTimeKst,
                c.OpeningPrice,
                c.HighPrice,
                c.LowPrice,
                c.TradePrice,
                c.Timestamp,
                c.CandleAccTradePrice,
                c.CandleAccTradeVolume,
                c.PrevClosingPrice ?? 0,
                c.ChangePrice ?? 0,
                c.ChangeRate ?? 0
            ))
            .ToList();

        // Redis 캐시 저장 (5분)
        if (items.Count > 0)
        {
            await cache.SetAsync(cacheKey, items, _cacheExpiry, ct);
        }

        return new Response(items);
    }
}