using System.Data; using Managing.Application.Abstractions; using Managing.Application.Abstractions.Services; using Managing.Domain.Scenarios; using Managing.Domain.Strategies; using Managing.Domain.Users; using Microsoft.Extensions.Logging; using static Managing.Common.Enums; namespace Managing.Application.Scenarios { public class ScenarioService : IScenarioService { private readonly ILogger _logger; private readonly ITradingService _tradingService; public ScenarioService(ILogger logger, ITradingService tradingService) { _logger = logger; _tradingService = tradingService; } public async Task CreateScenario(string name, List strategies, int? loopbackPeriod = 1) { var scenario = new Scenario(name, loopbackPeriod); foreach (var strategy in strategies) { scenario.AddIndicator(await _tradingService.GetIndicatorByNameAsync(strategy)); } try { await _tradingService.InsertScenarioAsync(scenario); } catch (Exception ex) { _logger.LogError(ex.Message); throw new Exception("Cannot create scenario"); } return scenario; } public async Task> GetScenariosAsync() { return await _tradingService.GetScenariosAsync(); } public async Task> GetIndicatorsAsync() { return await _tradingService.GetIndicatorsAsync(); } public async Task DeleteScenarioAsync(string name) { try { await _tradingService.DeleteScenarioAsync(name); return true; } catch (Exception ex) { _logger.LogError(ex.Message); return false; } } public async Task UpdateScenario(string name, List strategies, int? loopbackPeriod) { try { var scenario = await _tradingService.GetScenarioByNameAsync(name); scenario.Indicators.Clear(); foreach (var strategy in strategies) { scenario.AddIndicator(await _tradingService.GetIndicatorByNameAsync(strategy)); } scenario.LoopbackPeriod = loopbackPeriod ?? 1; await _tradingService.UpdateScenarioAsync(scenario); return true; } catch (Exception e) { Console.WriteLine(e); return false; } } public async Task UpdateStrategy(IndicatorType indicatorType, string name, int? period, int? fastPeriods, int? slowPeriods, int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods) { try { var strategy = await _tradingService.GetIndicatorByNameAsync(name); strategy.Type = indicatorType; strategy.Period = period; strategy.FastPeriods = fastPeriods; strategy.SlowPeriods = slowPeriods; strategy.SignalPeriods = signalPeriods; strategy.Multiplier = multiplier; strategy.StochPeriods = stochPeriods; strategy.SmoothPeriods = smoothPeriods; strategy.CyclePeriods = cyclePeriods; await _tradingService.UpdateIndicatorAsync(strategy); return true; } catch (Exception e) { Console.WriteLine(e); return false; } } public async Task> GetScenariosByUserAsync(User user) { return await _tradingService.GetScenariosByUserAsync(user); } public async Task CreateScenarioForUser(User user, string name, List strategies, int? loopbackPeriod = 1) { var scenario = new Scenario(name, loopbackPeriod ?? 1) { User = user }; foreach (var strategyName in strategies) { var strategy = await _tradingService.GetIndicatorByNameAsync(strategyName); if (strategy != null && strategy.User?.Name == user.Name) { scenario.AddIndicator(strategy); } } await _tradingService.InsertScenarioAsync(scenario); return scenario; } public async Task> GetIndicatorsByUserAsync(User user) { var indicators = await GetIndicatorsAsync(); return indicators.Where(s => s.User?.Name == user.Name); } public async Task DeleteIndicatorByUser(User user, string name) { var strategy = await _tradingService.GetIndicatorByNameAsync(name); if (strategy != null && strategy.User?.Name == user.Name) { await _tradingService.DeleteIndicatorAsync(strategy.Name); return true; } return false; } public async Task DeleteScenarioByUser(User user, string name) { try { var scenarios = await GetScenariosByUserAsync(user); foreach (var scenario in scenarios.Where(s => s.Name == name)) { await _tradingService.DeleteScenarioAsync(scenario.Name); } return true; } catch (Exception ex) { _logger.LogError(ex.Message); return false; } } public async Task DeleteScenariosByUser(User user) { try { var scenarios = await GetScenariosByUserAsync(user); foreach (var scenario in scenarios) { await _tradingService.DeleteScenarioAsync(scenario.Name); } return true; } catch (Exception ex) { _logger.LogError(ex.Message); return false; } } public async Task GetScenarioByUser(User user, string name) { var scenario = await _tradingService.GetScenarioByNameAsync(name); return scenario != null && scenario.User?.Name == user.Name ? scenario : null; } public async Task CreateIndicatorForUser(User user, IndicatorType type, string name, int? period = null, int? fastPeriods = null, int? slowPeriods = null, int? signalPeriods = null, double? multiplier = null, int? stochPeriods = null, int? smoothPeriods = null, int? cyclePeriods = null) { var existingIndicator = await _tradingService.GetIndicatorByNameUserAsync(name, user); if (existingIndicator != null) { throw new DuplicateNameException("An indicator with this name already exists for the user."); } else { var indicator = new IndicatorBase(name, type) { Period = period, FastPeriods = fastPeriods, SlowPeriods = slowPeriods, SignalPeriods = signalPeriods, Multiplier = multiplier, StochPeriods = stochPeriods, SmoothPeriods = smoothPeriods, CyclePeriods = cyclePeriods, User = user }; await _tradingService.InsertIndicatorAsync(indicator); return indicator; } } public async Task DeleteStrategiesByUser(User user) { try { var strategies = await GetIndicatorsByUserAsync(user); foreach (var strategy in strategies) { await _tradingService.DeleteIndicatorAsync(strategy.Name); } return true; } catch (Exception ex) { _logger.LogError(ex.Message); return false; } } public async Task UpdateScenarioByUser(User user, string name, List strategies, int? loopbackPeriod) { var scenario = await _tradingService.GetScenarioByNameAsync(name); if (scenario == null || scenario.User?.Name != user.Name) { return false; } scenario.Indicators.Clear(); scenario.LoopbackPeriod = loopbackPeriod ?? 1; foreach (var strategyName in strategies) { var strategy = await _tradingService.GetIndicatorByNameAsync(strategyName); if (strategy != null && strategy.User?.Name == user.Name) { scenario.AddIndicator(strategy); } } await _tradingService.UpdateScenarioAsync(scenario); return true; } public async Task UpdateIndicatorByUser(User user, IndicatorType indicatorType, string name, int? period, int? fastPeriods, int? slowPeriods, int? signalPeriods, double? multiplier, int? stochPeriods, int? smoothPeriods, int? cyclePeriods) { var strategy = await _tradingService.GetIndicatorByNameAsync(name); if (strategy == null || strategy.User?.Name != user.Name) { return false; } // Use the existing update strategy logic var result = await UpdateStrategy(indicatorType, name, period, fastPeriods, slowPeriods, signalPeriods, multiplier, stochPeriods, smoothPeriods, cyclePeriods); return result; } public async Task GetScenarioByNameAndUserAsync(string scenarioName, User user) { var scenario = await _tradingService.GetScenarioByNameUserAsync(scenarioName, user); if (scenario == null) { throw new InvalidOperationException($"Scenario {scenarioName} not found for user {user.Name}"); } return scenario; } } }