using System.Text.Json;
using Managing.Api.Models.Requests;
using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services;
using Managing.Application.Hubs;
using Managing.Domain.Backtests;
using Managing.Domain.Bots;
using Managing.Domain.MoneyManagements;
using Managing.Domain.Scenarios;
using Managing.Domain.Strategies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using MoneyManagementRequest = Managing.Domain.Backtests.MoneyManagementRequest;

namespace Managing.Api.Controllers;

/// <summary>
/// Controller for managing backtest operations.
/// Provides endpoints for creating, retrieving, and deleting backtests.
/// Returns complete backtest configurations for easy bot deployment.
/// Requires authorization for access.
/// </summary>
[ApiController]
[Authorize]
[Route("[controller]")]
[Produces("application/json")]
public class BacktestController : BaseController
{
    private readonly IHubContext<BacktestHub> _hubContext;
    private readonly IBacktester _backtester;
    private readonly IAccountService _accountService;
    private readonly IMoneyManagementService _moneyManagementService;
    private readonly IGeneticService _geneticService;

    /// <summary>
    /// Initializes a new instance of the <see cref="BacktestController"/> class.
    /// </summary>
    /// <param name="hubContext">The SignalR hub context for real-time communication.</param>
    /// <param name="backtester">The service for backtesting strategies.</param>
    /// <param name="scenarioService">The service for managing scenarios.</param>
    /// <param name="accountService">The service for account management.</param>
    /// <param name="moneyManagementService">The service for money management strategies.</param>
    /// <param name="geneticService">The service for genetic algorithm operations.</param>
    /// <param name="backtestRepository">The repository for backtest operations.</param>
    public BacktestController(
        IHubContext<BacktestHub> hubContext,
        IBacktester backtester,
        IAccountService accountService,
        IMoneyManagementService moneyManagementService,
        IGeneticService geneticService,
        IUserService userService) : base(userService)
    {
        _hubContext = hubContext;
        _backtester = backtester;
        _accountService = accountService;
        _moneyManagementService = moneyManagementService;
        _geneticService = geneticService;
    }

    /// <summary>
    /// Retrieves all backtests for the authenticated user.
    /// Each backtest includes the complete TradingBotConfig for easy bot deployment.
    /// </summary>
    /// <returns>A list of backtests with complete configurations.</returns>
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Backtest>>> Backtests()
    {
        var user = await GetUser();
        var backtests = await _backtester.GetBacktestsByUserAsync(user);
        return Ok(backtests);
    }

    /// <summary>
    /// Retrieves a specific backtest by ID for the authenticated user.
    /// This endpoint will also populate the candles for visualization and includes
    /// the complete TradingBotConfig that can be used to start a new bot.
    /// </summary>
    /// <param name="id">The ID of the backtest to retrieve.</param>
    /// <returns>The requested backtest with populated candle data and complete configuration.</returns>
    [HttpGet("{id}")]
    public async Task<ActionResult<Backtest>> Backtest(string id)
    {
        var user = await GetUser();
        var backtest = await _backtester.GetBacktestByIdForUserAsync(user, id);

        if (backtest == null)
        {
            return NotFound($"Backtest with ID {id} not found or doesn't belong to the current user.");
        }

        return Ok(backtest);
    }

    /// <summary>
    /// Deletes a specific backtest by ID for the authenticated user.
    /// </summary>
    /// <param name="id">The ID of the backtest to delete.</param>
    /// <returns>An ActionResult indicating the outcome of the operation.</returns>
    [HttpDelete]
    public async Task<ActionResult> DeleteBacktest(string id)
    {
        var user = await GetUser();
        var result = await _backtester.DeleteBacktestByUserAsync(user, id);
        return Ok(result);
    }

    /// <summary>
    /// Deletes multiple backtests by their IDs for the authenticated user.
    /// </summary>
    /// <param name="request">The request containing the array of backtest IDs to delete.</param>
    /// <returns>An ActionResult indicating the outcome of the operation.</returns>
    [HttpDelete("multiple")]
    public async Task<ActionResult> DeleteBacktests([FromBody] DeleteBacktestsRequest request)
    {
        var user = await GetUser();
        return Ok(await _backtester.DeleteBacktestsByIdsForUserAsync(user, request.BacktestIds));
    }

    /// <summary>
    /// Retrieves all backtests for a specific genetic request ID.
    /// This endpoint is used to view the results of a genetic algorithm optimization.
    /// </summary>
    /// <param name="requestId">The request ID to filter backtests by.</param>
    /// <returns>A list of backtests associated with the specified request ID.</returns>
    [HttpGet]
    [Route("ByRequestId/{requestId}")]
    public async Task<ActionResult<IEnumerable<Backtest>>> GetBacktestsByRequestId(string requestId)
    {
        if (string.IsNullOrEmpty(requestId))
        {
            return BadRequest("Request ID is required");
        }

        var backtests = await _backtester.GetBacktestsByRequestIdAsync(requestId);
        return Ok(backtests);
    }

    /// <summary>
    /// Retrieves paginated backtests for a specific genetic request ID.
    /// This endpoint is used to view the results of a genetic algorithm optimization with pagination support.
    /// </summary>
    /// <param name="requestId">The request ID to filter backtests by.</param>
    /// <param name="page">Page number (defaults to 1)</param>
    /// <param name="pageSize">Number of items per page (defaults to 50, max 100)</param>
    /// <param name="sortBy">Field to sort by (defaults to "score")</param>
    /// <param name="sortOrder">Sort order - "asc" or "desc" (defaults to "desc")</param>
    /// <returns>A paginated list of backtests associated with the specified request ID.</returns>
    [HttpGet]
    [Route("ByRequestId/{requestId}/Paginated")]
    public async Task<ActionResult<PaginatedBacktestsResponse>> GetBacktestsByRequestIdPaginated(
        string requestId,
        int page = 1,
        int pageSize = 50,
        string sortBy = "score",
        string sortOrder = "desc")
    {
        if (string.IsNullOrEmpty(requestId))
        {
            return BadRequest("Request ID is required");
        }

        if (page < 1)
        {
            return BadRequest("Page must be greater than 0");
        }

        if (pageSize < 1 || pageSize > 100)
        {
            return BadRequest("Page size must be between 1 and 100");
        }

        if (sortOrder != "asc" && sortOrder != "desc")
        {
            return BadRequest("Sort order must be 'asc' or 'desc'");
        }

        var (backtests, totalCount) =
            await _backtester.GetBacktestsByRequestIdPaginatedAsync(requestId, page, pageSize, sortBy, sortOrder);

        var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);

        var response = new PaginatedBacktestsResponse
        {
            Backtests = backtests.Select(b => new LightBacktestResponse
            {
                Id = b.Id,
                Config = b.Config,
                FinalPnl = b.FinalPnl,
                WinRate = b.WinRate,
                GrowthPercentage = b.GrowthPercentage,
                HodlPercentage = b.HodlPercentage,
                StartDate = b.StartDate,
                EndDate = b.EndDate,
                MaxDrawdown = b.MaxDrawdown,
                Fees = b.Fees,
                SharpeRatio = b.SharpeRatio,
                Score = b.Score,
                ScoreMessage = b.ScoreMessage
            }),
            TotalCount = totalCount,
            CurrentPage = page,
            PageSize = pageSize,
            TotalPages = totalPages,
            HasNextPage = page < totalPages,
            HasPreviousPage = page > 1
        };

        return Ok(response);
    }

    /// <summary>
    /// Retrieves paginated backtests for the authenticated user.
    /// </summary>
    /// <param name="page">Page number (defaults to 1)</param>
    /// <param name="pageSize">Number of items per page (defaults to 50, max 100)</param>
    /// <param name="sortBy">Field to sort by (defaults to "score")</param>
    /// <param name="sortOrder">Sort order - "asc" or "desc" (defaults to "desc")</param>
    /// <returns>A paginated list of backtests for the user.</returns>
    [HttpGet]
    [Route("Paginated")]
    public async Task<ActionResult<PaginatedBacktestsResponse>> GetBacktestsPaginated(
        int page = 1,
        int pageSize = 50,
        string sortBy = "score",
        string sortOrder = "desc")
    {
        var user = await GetUser();

        if (page < 1)
        {
            return BadRequest("Page must be greater than 0");
        }

        if (pageSize < 1 || pageSize > 100)
        {
            return BadRequest("Page size must be between 1 and 100");
        }

        if (sortOrder != "asc" && sortOrder != "desc")
        {
            return BadRequest("Sort order must be 'asc' or 'desc'");
        }

        var (backtests, totalCount) =
            await _backtester.GetBacktestsByUserPaginatedAsync(user, page, pageSize, sortBy, sortOrder);
        var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);

        var response = new PaginatedBacktestsResponse
        {
            Backtests = backtests.Select(b => new LightBacktestResponse
            {
                Id = b.Id,
                Config = b.Config,
                FinalPnl = b.FinalPnl,
                WinRate = b.WinRate,
                GrowthPercentage = b.GrowthPercentage,
                HodlPercentage = b.HodlPercentage,
                StartDate = b.StartDate,
                EndDate = b.EndDate,
                MaxDrawdown = b.MaxDrawdown,
                Fees = b.Fees,
                SharpeRatio = b.SharpeRatio,
                Score = b.Score,
                ScoreMessage = b.ScoreMessage
            }),
            TotalCount = totalCount,
            CurrentPage = page,
            PageSize = pageSize,
            TotalPages = totalPages,
            HasNextPage = page < totalPages,
            HasPreviousPage = page > 1
        };

        return Ok(response);
    }

    /// <summary>
    /// Runs a backtest with the specified configuration.
    /// Returns a lightweight backtest result for efficient processing.
    /// Use the returned ID to retrieve the full backtest data from the database.
    /// </summary>
    /// <param name="request">The backtest request containing configuration and parameters.</param>
    /// <returns>The lightweight result of the backtest with essential data.</returns>
    [HttpPost]
    [Route("Run")]
    public async Task<ActionResult<LightBacktest>> Run([FromBody] RunBacktestRequest request)
    {
        if (request?.Config == null)
        {
            return BadRequest("Backtest configuration is required");
        }

        if (string.IsNullOrEmpty(request.Config.AccountName))
        {
            return BadRequest("Account name is required");
        }

        if (string.IsNullOrEmpty(request.Config.ScenarioName) && request.Config.Scenario == null)
        {
            return BadRequest("Either scenario name or scenario object is required");
        }

        if (string.IsNullOrEmpty(request.Config.MoneyManagementName) && request.Config.MoneyManagement == null)
        {
            return BadRequest("Either money management name or money management object is required");
        }

        try
        {
            LightBacktest backtestResult = null;
            var account = await _accountService.GetAccount(request.Config.AccountName, true, false);
            var user = await GetUser();

            // Get money management
            MoneyManagement moneyManagement;
            if (!string.IsNullOrEmpty(request.Config.MoneyManagementName))
            {
                moneyManagement =
                    await _moneyManagementService.GetMoneyMangement(user, request.Config.MoneyManagementName);
                if (moneyManagement == null)
                    return BadRequest("Money management not found");
            }
            else
            {
                moneyManagement = Map(request.Config.MoneyManagement);
                moneyManagement?.FormatPercentage();
            }

            // Handle scenario - either from ScenarioRequest or ScenarioName
            Scenario scenario = null;
            if (request.Config.Scenario != null)
            {
                // Convert ScenarioRequest to Scenario domain object
                scenario = new Scenario(request.Config.Scenario.Name, request.Config.Scenario.LoopbackPeriod)
                {
                    User = user
                };

                // Convert IndicatorRequest objects to Indicator domain objects
                foreach (var indicatorRequest in request.Config.Scenario.Indicators)
                {
                    var indicator = new IndicatorBase(indicatorRequest.Name, indicatorRequest.Type)
                    {
                        SignalType = indicatorRequest.SignalType,
                        MinimumHistory = indicatorRequest.MinimumHistory,
                        Period = indicatorRequest.Period,
                        FastPeriods = indicatorRequest.FastPeriods,
                        SlowPeriods = indicatorRequest.SlowPeriods,
                        SignalPeriods = indicatorRequest.SignalPeriods,
                        Multiplier = indicatorRequest.Multiplier,
                        SmoothPeriods = indicatorRequest.SmoothPeriods,
                        StochPeriods = indicatorRequest.StochPeriods,
                        CyclePeriods = indicatorRequest.CyclePeriods,
                        User = user
                    };
                    scenario.AddIndicator(indicator);
                }
            }

            // Convert TradingBotConfigRequest to TradingBotConfig for backtest
            var backtestConfig = new TradingBotConfig
            {
                AccountName = request.Config.AccountName,
                MoneyManagement = moneyManagement,
                Ticker = request.Config.Ticker,
                ScenarioName = request.Config.ScenarioName,
                Scenario = scenario != null
                    ? LightScenario.FromScenario(scenario)
                    : null, // Convert to LightScenario for Orleans
                Timeframe = request.Config.Timeframe,
                IsForWatchingOnly = request.Config.IsForWatchingOnly,
                BotTradingBalance = request.Config.BotTradingBalance,
                IsForBacktest = true,
                CooldownPeriod = request.Config.CooldownPeriod,
                MaxLossStreak = request.Config.MaxLossStreak,
                MaxPositionTimeHours = request.Config.MaxPositionTimeHours,
                FlipOnlyWhenInProfit = request.Config.FlipOnlyWhenInProfit,
                FlipPosition = request.Config.FlipPosition, // Computed based on BotType
                Name = request.Config.Name ??
                       $"Backtest-{request.Config.ScenarioName ?? request.Config.Scenario?.Name ?? "Custom"}-{DateTime.UtcNow:yyyyMMdd-HHmmss}",
                CloseEarlyWhenProfitable = request.Config.CloseEarlyWhenProfitable,
                UseSynthApi = request.Config.UseSynthApi,
                UseForPositionSizing = request.Config.UseForPositionSizing,
                UseForSignalFiltering = request.Config.UseForSignalFiltering,
                UseForDynamicStopLoss = request.Config.UseForDynamicStopLoss
            };

            backtestResult = await _backtester.RunTradingBotBacktest(
                backtestConfig,
                request.StartDate,
                request.EndDate,
                user,
                request.Save,
                request.WithCandles,
                null); // No requestId for regular backtests

            // Note: Notification is handled within the Orleans grain for LightBacktest
            // The full Backtest data can be retrieved from the database using the ID if needed

            return Ok(backtestResult);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error running backtest: {ex.Message}");
        }
    }

    /// <summary>
    /// Creates a bundle backtest request with the specified configurations.
    /// This endpoint creates a request that will be processed by a background worker.
    /// </summary>
    /// <param name="requests">The list of backtest requests to execute.</param>
    /// <param name="name">Display name for the bundle (required).</param>
    /// <returns>The bundle backtest request with ID for tracking progress.</returns>
    [HttpPost]
    [Route("BacktestBundle")]
    public async Task<ActionResult<BundleBacktestRequest>> RunBundle([FromBody] RunBundleBacktestRequest request)
    {
        if (request?.Requests == null || !request.Requests.Any())
        {
            return BadRequest("At least one backtest request is required");
        }

        if (request.Requests.Count > 10)
        {
            return BadRequest("Maximum of 10 backtests allowed per bundle request");
        }

        if (string.IsNullOrWhiteSpace(request.Name))
        {
            return BadRequest("Bundle name is required");
        }

        try
        {
            var user = await GetUser();

            // Validate all requests before creating the bundle
            foreach (var req in request.Requests)
            {
                if (req?.Config == null)
                {
                    return BadRequest("Invalid request: Configuration is required");
                }

                if (string.IsNullOrEmpty(req.Config.AccountName))
                {
                    return BadRequest("Invalid request: Account name is required");
                }

                if (string.IsNullOrEmpty(req.Config.ScenarioName) && req.Config.Scenario == null)
                {
                    return BadRequest("Invalid request: Either scenario name or scenario object is required");
                }

                if (string.IsNullOrEmpty(req.Config.MoneyManagementName) && req.Config.MoneyManagement == null)
                {
                    return BadRequest(
                        "Invalid request: Either money management name or money management object is required");
                }
            }

            // Create the bundle backtest request
            var bundleRequest = new BundleBacktestRequest
            {
                User = user,
                BacktestRequestsJson = JsonSerializer.Serialize(request.Requests),
                TotalBacktests = request.Requests.Count,
                CompletedBacktests = 0,
                FailedBacktests = 0,
                Status = BundleBacktestRequestStatus.Pending,
                Name = request.Name
            };

            _backtester.InsertBundleBacktestRequestForUser(user, bundleRequest);
            return Ok(bundleRequest);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error creating bundle backtest request: {ex.Message}");
        }
    }

    /// <summary>
    /// Retrieves all bundle backtest requests for the authenticated user.
    /// </summary>
    /// <returns>A list of bundle backtest requests with their current status.</returns>
    [HttpGet]
    [Route("Bundle")]
    public async Task<ActionResult<IEnumerable<BundleBacktestRequest>>> GetBundleBacktestRequests()
    {
        var user = await GetUser();
        var bundleRequests = _backtester.GetBundleBacktestRequestsByUser(user);
        return Ok(bundleRequests);
    }

    /// <summary>
    /// Retrieves a specific bundle backtest request by ID for the authenticated user.
    /// </summary>
    /// <param name="id">The ID of the bundle backtest request to retrieve.</param>
    /// <returns>The requested bundle backtest request with current status and results.</returns>
    [HttpGet]
    [Route("Bundle/{id}")]
    public async Task<ActionResult<BundleBacktestRequest>> GetBundleBacktestRequest(string id)
    {
        var user = await GetUser();
        var bundleRequest = _backtester.GetBundleBacktestRequestByIdForUser(user, id);

        if (bundleRequest == null)
        {
            return NotFound($"Bundle backtest request with ID {id} not found or doesn't belong to the current user.");
        }

        return Ok(bundleRequest);
    }

    /// <summary>
    /// Deletes a specific bundle backtest request by ID for the authenticated user.
    /// Also deletes all related backtests associated with this bundle request.
    /// </summary>
    /// <param name="id">The ID of the bundle backtest request to delete.</param>
    /// <returns>An ActionResult indicating the outcome of the operation.</returns>
    [HttpDelete]
    [Route("Bundle/{id}")]
    public async Task<ActionResult> DeleteBundleBacktestRequest(string id)
    {
        var user = await GetUser();

        // First, delete the bundle request
        _backtester.DeleteBundleBacktestRequestByIdForUser(user, id);

        // Then, delete all related backtests
        var backtestsDeleted = await _backtester.DeleteBacktestsByRequestIdAsync(id);

        return Ok(new
        {
            BundleRequestDeleted = true,
            RelatedBacktestsDeleted = backtestsDeleted
        });
    }

    /// <summary>
    /// Subscribes the client to real-time updates for a bundle backtest request via SignalR.
    /// The client will receive LightBacktestResponse objects as new backtests are generated.
    /// </summary>
    /// <param name="requestId">The bundle request ID to subscribe to.</param>
    [HttpPost]
    [Route("Bundle/Subscribe")] // POST /Backtest/Bundle/Subscribe
    public async Task<IActionResult> SubscribeToBundle([FromQuery] string requestId)
    {
        if (string.IsNullOrWhiteSpace(requestId))
            return BadRequest("RequestId is required");

        // Get the connection ID from the SignalR context (assume it's passed via header or query)
        var connectionId = HttpContext.Request.Headers["X-SignalR-ConnectionId"].ToString();
        if (string.IsNullOrEmpty(connectionId))
            return BadRequest("SignalR connection ID is required in X-SignalR-ConnectionId header");

        // Add the connection to the SignalR group for this bundle
        await _hubContext.Groups.AddToGroupAsync(connectionId, $"bundle-{requestId}");
        return Ok(new { Subscribed = true, RequestId = requestId });
    }

    /// <summary>
    /// Unsubscribes the client from real-time updates for a bundle backtest request via SignalR.
    /// </summary>
    /// <param name="requestId">The bundle request ID to unsubscribe from.</param>
    [HttpPost]
    [Route("Bundle/Unsubscribe")] // POST /Backtest/Bundle/Unsubscribe
    public async Task<IActionResult> UnsubscribeFromBundle([FromQuery] string requestId)
    {
        if (string.IsNullOrWhiteSpace(requestId))
            return BadRequest("RequestId is required");

        var connectionId = HttpContext.Request.Headers["X-SignalR-ConnectionId"].ToString();
        if (string.IsNullOrEmpty(connectionId))
            return BadRequest("SignalR connection ID is required in X-SignalR-ConnectionId header");

        await _hubContext.Groups.RemoveFromGroupAsync(connectionId, $"bundle-{requestId}");
        return Ok(new { Unsubscribed = true, RequestId = requestId });
    }

    /// <summary>
    /// Runs a genetic algorithm optimization with the specified configuration.
    /// This endpoint saves the genetic request to the database and returns the request ID.
    /// The actual genetic algorithm execution will be handled by a background service.
    /// </summary>
    /// <param name="request">The genetic algorithm request containing configuration and parameters.</param>
    /// <returns>The genetic request with ID for tracking progress.</returns>
    [HttpPost]
    [Route("Genetic")]
    public async Task<ActionResult<GeneticRequest>> RunGenetic([FromBody] RunGeneticRequest request)
    {
        if (request == null)
        {
            return BadRequest("Genetic request is required");
        }

        if (request.EligibleIndicators == null || !request.EligibleIndicators.Any())
        {
            return BadRequest("At least one eligible indicator is required");
        }

        if (request.StartDate >= request.EndDate)
        {
            return BadRequest("Start date must be before end date");
        }

        if (request.PopulationSize <= 0 || request.Generations <= 0)
        {
            return BadRequest("Population size and generations must be greater than 0");
        }

        if (request.MutationRate < 0 || request.MutationRate > 1)
        {
            return BadRequest("Mutation rate must be between 0 and 1");
        }

        try
        {
            var user = await GetUser();

            // Create genetic request using the GeneticService directly
            var geneticRequest = _geneticService.CreateGeneticRequest(
                user,
                request.Ticker,
                request.Timeframe,
                request.StartDate,
                request.EndDate,
                request.Balance,
                request.PopulationSize,
                request.Generations,
                request.MutationRate,
                request.SelectionMethod,
                request.CrossoverMethod,
                request.MutationMethod,
                request.ElitismPercentage,
                request.MaxTakeProfit,
                request.EligibleIndicators);

            return Ok(geneticRequest);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error creating genetic request: {ex.Message}");
        }
    }

    /// <summary>
    /// Retrieves all genetic requests for the authenticated user.
    /// </summary>
    /// <returns>A list of genetic requests with their current status.</returns>
    [HttpGet]
    [Route("Genetic")]
    public async Task<ActionResult<IEnumerable<GeneticRequest>>> GetGeneticRequests()
    {
        var user = await GetUser();
        var geneticRequests = _geneticService.GetGeneticRequestsByUser(user);
        return Ok(geneticRequests);
    }

    /// <summary>
    /// Retrieves a specific genetic request by ID for the authenticated user.
    /// </summary>
    /// <param name="id">The ID of the genetic request to retrieve.</param>
    /// <returns>The requested genetic request with current status and results.</returns>
    [HttpGet]
    [Route("Genetic/{id}")]
    public async Task<ActionResult<GeneticRequest>> GetGeneticRequest(string id)
    {
        var user = await GetUser();
        var geneticRequest = _geneticService.GetGeneticRequestByIdForUser(user, id);

        if (geneticRequest == null)
        {
            return NotFound($"Genetic request with ID {id} not found or doesn't belong to the current user.");
        }

        return Ok(geneticRequest);
    }

    /// <summary>
    /// Deletes a specific genetic request by ID for the authenticated user.
    /// Also deletes all related backtests associated with this genetic request.
    /// </summary>
    /// <param name="id">The ID of the genetic request to delete.</param>
    /// <returns>An ActionResult indicating the outcome of the operation.</returns>
    [HttpDelete]
    [Route("Genetic/{id}")]
    public async Task<ActionResult> DeleteGeneticRequest(string id)
    {
        var user = await GetUser();

        // First, delete the genetic request
        _geneticService.DeleteGeneticRequestByIdForUser(user, id);

        // Then, delete all related backtests
        var backtestsDeleted = await _backtester.DeleteBacktestsByRequestIdAsync(id);

        return Ok(new
        {
            GeneticRequestDeleted = true,
            RelatedBacktestsDeleted = backtestsDeleted
        });
    }


    public MoneyManagement Map(MoneyManagementRequest moneyManagementRequest)
    {
        return new MoneyManagement
        {
            Name = moneyManagementRequest.Name,
            StopLoss = moneyManagementRequest.StopLoss,
            TakeProfit = moneyManagementRequest.TakeProfit,
            Leverage = moneyManagementRequest.Leverage,
            Timeframe = moneyManagementRequest.Timeframe
        };
    }
}

/// <summary>
/// Request model for running a backtest
/// </summary>
public class RunBacktestRequest
{
    /// <summary>
    /// The trading bot configuration request to use for the backtest
    /// </summary>
    public TradingBotConfigRequest Config { get; set; }

    /// <summary>
    /// The start date for the backtest
    /// </summary>
    public DateTime StartDate { get; set; }

    /// <summary>
    /// The end date for the backtest
    /// </summary>
    public DateTime EndDate { get; set; }

    /// <summary>
    /// Whether to save the backtest results
    /// </summary>
    public bool Save { get; set; } = false;

    /// <summary>
    /// Whether to include candles and indicators values in the response.
    /// Set to false to reduce response size dramatically.
    /// </summary>
    public bool WithCandles { get; set; } = false;
}