using Exilion.TradingAtomics;
using Managing.Domain.Accounts;
using Managing.Domain.Candles;
using Managing.Domain.Statistics;
using static Managing.Common.Enums;

namespace Managing.Domain.Shared.Helpers;

public static class TradingHelpers
{
    public static decimal GetHodlPercentage(Candle candle1, Candle candle2)
    {
        return candle2.Close * 100 / candle1.Close - 100;
    }

    public static decimal GetGrowthFromInitalBalance(decimal balance, decimal finalPnl)
    {
        var growth = balance + finalPnl;

        return growth * 100 / balance - 100;
    }

    public static PerformanceMetrics GetStatistics(Dictionary<DateTime, decimal> pnls)
    {
        var priceSeries = new TimePriceSeries(pnls.DistinctBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value));

        return priceSeries.CalculatePerformanceMetrics();
    }

    public static decimal GetFeeAmount(decimal fee, decimal amount)
    {
        return fee * amount;
    }

    public static decimal GetFeeAmount(decimal fee, decimal amount, TradingExchanges exchange)
    {
        if (exchange.Equals(TradingExchanges.Evm))
            return fee;

        return GetFeeAmount(fee, amount);
    }

    public static bool IsAGoodTrader(Trader trader)
    {
        return trader.Winrate > 30
               && trader.TradeCount > 8
               && trader.AverageWin > Math.Abs(trader.AverageLoss)
               && trader.Pnl > 0;
    }

    public static bool IsABadTrader(Trader trader)
    {
        return trader.Winrate < 30
               && trader.TradeCount > 8
               && trader.AverageWin * 3 < Math.Abs(trader.AverageLoss)
               && trader.Pnl < 0;
    }

    public static List<Trader> FindBadTrader(this List<Trader> traders)
    {
        var filteredTrader = new List<Trader>();
        foreach (var trader in traders)
        {
            if (IsABadTrader(trader))
            {
                filteredTrader.Add(trader);
            }
        }

        return filteredTrader;
    }

    public static List<Trader> FindGoodTrader(this List<Trader> traders)
    {
        var filteredTrader = new List<Trader>();
        foreach (var trader in traders)
        {
            if (IsAGoodTrader(trader))
            {
                filteredTrader.Add(trader);
            }
        }

        return filteredTrader;
    }

    public static List<Trader> MapToTraders(this List<Account> accounts)
    {
        var traders = new List<Trader>();
        foreach (var account in accounts)
        {
            traders.Add(new Trader
            {
                Address = account.Key
            });
        }

        return traders;
    }
}