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

namespace Application.Features.Api.Crypto.Market.GetAll;

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

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

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

        // Upbit REST API 호출
        var markets = await upbit.GetMarketsAsync(ct);

        var items = markets
            .Select(m => new Response.MarketItem(
                m.Market,
                m.KoreanName,
                m.EnglishName,
                new Response.MarketEvent(
                    m.MarketEvent.Warning,
                    new Response.MarketCaution(
                        m.MarketEvent.Caution.PriceFluctuations,
                        m.MarketEvent.Caution.TradingVolumeSoaring,
                        m.MarketEvent.Caution.DepositAmountSoaring,
                        m.MarketEvent.Caution.GlobalPriceDifferences,
                        m.MarketEvent.Caution.ConcentrationOfSmallAccounts
                    )
                )
            ))
            .ToList();

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

        return new Response(items);
    }
}