using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services;
using Managing.Application.Workflows.Flows.Feeds;
using Managing.Application.Workflows.Flows.Strategies;
using Managing.Application.Workflows.Flows.Trading;
using Managing.Domain.Workflows;
using Managing.Domain.Workflows.Synthetics;
using static Managing.Common.Enums;

namespace Managing.Application.Workflows;

public class FlowFactory : IFlowFactory
{
    private readonly IExchangeService _exchangeService;
    private readonly ICacheService _cacheService;
    private readonly ITradingService _tradingService;
    private readonly IAccountService _accountService;

    public FlowFactory(IExchangeService exchangeService, ICacheService cacheService, ITradingService tradingService,
        IAccountService accountService)
    {
        _exchangeService = exchangeService;
        _cacheService = cacheService;
        _tradingService = tradingService;
        _accountService = accountService;
    }

    public IFlow BuildFlow(SyntheticFlow request)
    {
        IFlow flow = request.Type switch
        {
            FlowType.FeedTicker => new FeedTicker(_exchangeService),
            FlowType.RsiDivergence => new RsiDiv(),
            FlowType.OpenPosition => new OpenPosition(_exchangeService, _cacheService, _accountService,
                _tradingService),
            _ => throw new NotImplementedException(),
        };

        flow.Children = new List<IFlow>();
        flow.Parameters = new List<FlowParameter>();

        foreach (var parameter in request.Parameters)
        {
            if (!flow.Parameters.Any(p => p.Name == parameter.Name))
            {
                flow.Parameters.Add(new FlowParameter
                {
                    Name = parameter.Name,
                    Value = parameter.Value
                });
            }
        }

        return flow;
    }
}