using Managing.Domain.Accounts;
using Managing.Domain.Candles;
using Managing.Domain.Statistics;
using Managing.Domain.Trades;
using static Managing.Common.Enums;

namespace Managing.Application.Abstractions.Services;

public interface IExchangeService
{
    Task<Trade> OpenTrade(
        Account account,
        Ticker ticker,
        TradeDirection direction,
        decimal price,
        decimal quantity,
        decimal? leverage = null,
        TradeType tradeType = TradeType.Limit,
        bool reduceOnly = false,
        bool isForPaperTrading = false,
        DateTime? currentDate = null,
        bool ioc = true,
        decimal? stopLossPrice = null,
        decimal? takeProfitPrice = null);

    Task<decimal> GetBalance(Account account, bool isForPaperTrading = false);
    Task<List<Balance>> GetBalances(Account account, bool isForPaperTrading = false);
    Task<decimal> GetPrice(Account account, Ticker ticker, DateTime date);
    Task<Trade> GetTrade(Account account, string order, Ticker ticker);

    Task<List<Candle>> GetCandles(Account account, Ticker ticker, DateTime startDate, Timeframe interval,
        bool isFirstCall = false);

    Task<Trade> OpenStopLoss(Account account, Ticker ticker, TradeDirection originalDirection, decimal stopLossPrice,
        decimal quantity, bool isForPaperTrading = false, DateTime? currentDate = null);

    Task<List<Ticker>> GetTickers(Timeframe timeframe);

    Task<Trade> OpenTakeProfit(Account account, Ticker ticker, TradeDirection originalDirection,
        decimal takeProfitPrice,
        decimal quantity, bool isForPaperTrading = false, DateTime? currentDate = null);

    Task<Trade> ClosePosition(Account account, Position position, decimal lastPrice, bool isForPaperTrading = false);
    decimal GetVolume(Account account, Ticker ticker);
    Task<List<Trade>> GetTrades(Account account, Ticker ticker);
    Task<bool> CancelOrder(Account account, Ticker ticker);
    decimal GetFee(Account account, bool isForPaperTrading = false);
    Task<Candle> GetCandle(Account account, Ticker ticker, DateTime date);
    Task<decimal> GetQuantityInPosition(Account account, Ticker ticker);

    Task<HashSet<Candle>> GetCandlesInflux(TradingExchanges exchange, Ticker ticker, DateTime startDate,
        Timeframe timeframe, int? limit = null);

    Task<HashSet<Candle>> GetCandlesInflux(TradingExchanges exchange, Ticker ticker, DateTime startDate,
        Timeframe timeframe, DateTime endDate, int? limit = null);

    Task<decimal> GetBestPrice(Account account, Ticker ticker, decimal lastPrice, decimal quantity,
        TradeDirection direction);

    Orderbook GetOrderbook(Account account, Ticker ticker);

    Trade BuildEmptyTrade(Ticker ticker, decimal price, decimal quantity, TradeDirection direction, decimal? leverage,
        TradeType tradeType, DateTime dateTime, TradeStatus tradeStatus = TradeStatus.PendingOpen);

    Task<List<Trade>> GetOpenOrders(Account account, Ticker ticker);
    Task<Trade> GetTrade(string reference, string orderId, Ticker ticker);
    Task<List<FundingRate>> GetFundingRates();
    Task<IEnumerable<Position>> GetBrokerPositions(Account account);
}