using Managing.Application.Abstractions.Repositories;
using Managing.Application.Abstractions.Services;
using Managing.Domain.Accounts;
using Managing.Domain.Candles;
using Microsoft.Extensions.Logging;
using static Managing.Common.Enums;

namespace Managing.Application.Trading;

public class PricesService : IPricesService
{
    private readonly ILogger<PricesService> _logger;
    private readonly IExchangeService _exchangeService;
    private readonly IAccountService _accountService;
    private readonly ICandleRepository _candleRepository;

    public PricesService(
        ILogger<PricesService> logger,
        IExchangeService exchangeService,
        ICandleRepository candleRepository,
        IAccountService accountService)
    {
        _logger = logger;
        _exchangeService = exchangeService;
        _candleRepository = candleRepository;
        _accountService = accountService;
    }

    public async Task UpdatePrice(TradingExchanges exchange, Ticker ticker, Timeframe timeframe)
    {
        try
        {
            var account = new Account()
            {
                Exchange = exchange,
            };

            if (account == null)
                throw new Exception($"Enable to found account for exchange {exchange}");

            var lastCandles =
                await _candleRepository.GetCandles(exchange, ticker, timeframe, DateTime.UtcNow.AddDays(-30), limit: 1)
                .ConfigureAwait(false);
                
            var lastCandle = lastCandles.LastOrDefault();
            var startDate = lastCandle != null ? lastCandle.Date : new DateTime(2017, 1, 1);

            List<Candle> newCandles =
                await _exchangeService.GetCandles(account, ticker, startDate, timeframe, true)
                .ConfigureAwait(false);

            var candlesToInsert = lastCandle == null 
                ? newCandles 
                : newCandles.Where(c => c.Date > lastCandle.Date);

            var candlesInserted = 0;

            foreach (var newCandle in candlesToInsert)
            {
                await _candleRepository.InsertCandle(newCandle).ConfigureAwait(false);
                candlesInserted++;
            }

            if (candlesInserted > 0)
                _logger.LogInformation("[{exchange}][{ticker}][{timeframe}] New candles inserted : {candlesInserted}", exchange, ticker, timeframe, candlesInserted);
        }
        catch (Exception ex)
        {
            SentrySdk.CaptureException(ex);
            _logger.LogError("[{exchange}][{ticker}][{timeframe}] Error : {ex.Message} |  {ex.StackTrace}", exchange, ticker, timeframe, ex.Message, ex.StackTrace);
        }
    }
}