using Managing.Domain.Backtests;
using Managing.Domain.Users;
using static Managing.Common.Enums;

namespace Managing.Application.Abstractions.Services;

/// <summary>
/// Service for managing genetic algorithm requests
/// </summary>
public interface IGeneticService
{
    /// <summary>
    /// Creates a new genetic request for a user
    /// </summary>
    /// <param name="user">The user creating the request</param>
    /// <param name="ticker">The ticker to optimize for</param>
    /// <param name="timeframe">The timeframe to use</param>
    /// <param name="startDate">The start date for the backtest period</param>
    /// <param name="endDate">The end date for the backtest period</param>
    /// <param name="balance">The starting balance</param>
    /// <param name="populationSize">The population size for the genetic algorithm</param>
    /// <param name="generations">The number of generations to evolve</param>
    /// <param name="mutationRate">The mutation rate (0.0 - 1.0)</param>
    /// <param name="selectionMethod">The selection method to use</param>
    /// <param name="crossoverMethod">The crossover method to use</param>
    /// <param name="mutationMethod">The mutation method to use</param>
    /// <param name="elitismPercentage">The percentage of elite individuals to preserve</param>
    /// <param name="maxTakeProfit">The maximum take profit percentage</param>
    /// <param name="eligibleIndicators">The list of eligible indicators</param>
    /// <returns>The created genetic request</returns>
    GeneticRequest CreateGeneticRequest(
        User user,
        Ticker ticker,
        Timeframe timeframe,
        DateTime startDate,
        DateTime endDate,
        decimal balance,
        int populationSize,
        int generations,
        double mutationRate,
        GeneticSelectionMethod selectionMethod,
        GeneticCrossoverMethod crossoverMethod,
        GeneticMutationMethod mutationMethod,
        int elitismPercentage,
        double maxTakeProfit,
        List<IndicatorType> eligibleIndicators);

    /// <summary>
    /// Gets all genetic requests for a user
    /// </summary>
    /// <param name="user">The user to get requests for</param>
    /// <returns>Collection of genetic requests</returns>
    IEnumerable<GeneticRequest> GetGeneticRequestsByUser(User user);

    /// <summary>
    /// Gets a specific genetic request by ID for a user
    /// </summary>
    /// <param name="user">The user</param>
    /// <param name="id">The request ID</param>
    /// <returns>The genetic request or null if not found</returns>
    GeneticRequest GetGeneticRequestByIdForUser(User user, string id);

    /// <summary>
    /// Updates a genetic request
    /// </summary>
    /// <param name="geneticRequest">The genetic request to update</param>
    Task UpdateGeneticRequestAsync(GeneticRequest geneticRequest);

    /// <summary>
    /// Deletes a genetic request by ID for a user
    /// </summary>
    /// <param name="user">The user</param>
    /// <param name="id">The request ID</param>
    void DeleteGeneticRequestByIdForUser(User user, string id);

    /// <summary>
    /// Gets all genetic requests by status across all users
    /// </summary>
    /// <param name="status">The status to filter by</param>
    /// <returns>Collection of genetic requests</returns>
    Task<List<GeneticRequest>> GetGeneticRequestsAsync(GeneticRequestStatus status);

    /// <summary>
    /// Runs the genetic algorithm for a specific request
    /// </summary>
    /// <param name="request">The genetic request to process</param>
    /// <param name="cancellationToken">Cancellation token to stop the algorithm</param>
    /// <returns>The genetic algorithm result</returns>
    Task<GeneticAlgorithmResult> RunGeneticAlgorithm(GeneticRequest request, CancellationToken cancellationToken = default);
} 