using Managing.Core;
using Managing.Domain.Candles;
using Managing.Domain.Indicators;
using Managing.Domain.Shared.Rules;
using Managing.Domain.Strategies.Base;
using Skender.Stock.Indicators;
using static Managing.Common.Enums;

namespace Managing.Domain.Strategies.Signals;

public class EmaCrossIndicatorBase : EmaBaseIndicatorBase
{
    public List<LightSignal> Signals { get; set; }

    public EmaCrossIndicatorBase(string name, int period) : base(name, IndicatorType.EmaCross)
    {
        Signals = new List<LightSignal>();
        Period = period;
    }

    public override IndicatorsResultBase GetIndicatorValues(HashSet<Candle> candles)
    {
        return new IndicatorsResultBase()
        {
            Ema = candles.GetEma(Period.Value).ToList()
        };
    }

    public override List<LightSignal> Run(HashSet<Candle> candles)
    {
        if (candles.Count <= Period)
        {
            return null;
        }

        try
        {
            var ema = candles.GetEma(Period.Value).ToList();
            var emaCandles = MapEmaToCandle(ema, candles.TakeLast(Period.Value).ToHashSet());

            if (ema.Count == 0)
                return null;

            var previousCandle = emaCandles[0];
            foreach (var currentCandle in emaCandles.Skip(1))
            {
                if (previousCandle.Close > (decimal)currentCandle.Ema &&
                    currentCandle.Close < (decimal)currentCandle.Ema)
                {
                    AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
                }

                if (previousCandle.Close < (decimal)currentCandle.Ema &&
                    currentCandle.Close > (decimal)currentCandle.Ema)
                {
                    AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
                }

                previousCandle = currentCandle;
            }

            return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
        }
        catch (RuleException)
        {
            return null;
        }
    }

    private void AddSignal(CandleEma candleSignal, TradeDirection direction, Confidence confidence)
    {
        var signal = new LightSignal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
            candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType, Name);
        if (!Signals.Any(s => s.Identifier == signal.Identifier))
        {
            Signals.AddItem(signal);
        }
    }
}