using Managing.Domain.Candles;
using Managing.Domain.Strategies.Signals;
using Managing.Domain.Workflows;
using Newtonsoft.Json;
using static Managing.Common.Enums;

namespace Managing.Application.Workflows.Flows.Strategies;

public class RsiDiv : FlowBase
{
    public override List<IFlow> Children { get; set; }
    public override List<FlowParameter> Parameters { get; set; }
    public override Guid ParentId { get; }
    public override Guid Id { get; }
    public override string Output { get; set; }
    public override string Name => "Rsi Divergence";
    public override string Description => "This flow will take a feed of candle an run the RSI Divergence";
    public override FlowType Type => FlowType.RsiDivergence;
    public override List<FlowOutput> AcceptedInputs => new() { FlowOutput.Candles };
    public override List<FlowOutput> OutputTypes => new() { FlowOutput.Signal };
    public RsiDivParameters RsiDivParameters { get; set; }

    public async override Task Execute(string input)
    {
        if (string.IsNullOrEmpty(input))
        {
            throw new ArgumentException($"'{nameof(input)}' cannot be null or empty.", nameof(input));
        }

        MapParameters();
        var candles = JsonConvert.DeserializeObject<HashSet<Candle>>(input);

        var strategy = new RsiDivergenceStrategy(Name, RsiDivParameters.Period);
        strategy.UpdateCandles(candles);
        strategy.Run();

        Output = JsonConvert.SerializeObject(strategy.Signals);

        if (Children != null && Children.Count > 0)
        {
            foreach (var child in Children)
            {
                await child.Execute(Output);
            }
        }
    }

    public override void MapParameters()
    {
        RsiDivParameters = new RsiDivParameters();
        foreach (var param in Parameters)
        {
            if (param.Name == nameof(RsiDivParameters.Period))
                RsiDivParameters.Period = int.Parse(param.Value);
            if (param.Name == nameof(RsiDivParameters.Timeframe))
                RsiDivParameters.Timeframe = (Timeframe)Enum.Parse(typeof(Timeframe), param.Value);
        }
    }
}

public class RsiDivParameters
{
    public int Period { get; set; }
    public Timeframe Timeframe { get; set; }
}