using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Services;
using Managing.Application.ManageBot.Commands;
using Managing.Common;
using Managing.Domain.Users;
using MediatR;

namespace Managing.Application.ManageBot
{
    /// <summary>
    /// Handler for retrieving all agents and their strategies
    /// </summary>
    public class GetAllAgentsCommandHandler : IRequestHandler<GetAllAgentsCommand, Dictionary<User, List<ITradingBot>>>
    {
        private readonly IBotService _botService;
        private readonly IAccountService _accountService;

        public GetAllAgentsCommandHandler(IBotService botService, IAccountService accountService)
        {
            _botService = botService;
            _accountService = accountService;
        }

        public async Task<Dictionary<User, List<ITradingBot>>> Handle(GetAllAgentsCommand request,
            CancellationToken cancellationToken)
        {
            var result = new Dictionary<User, List<ITradingBot>>();
            var allActiveBots = _botService.GetActiveBots();

            // Group bots by user
            foreach (var bot in allActiveBots)
            {
                if (bot.User == null)
                {
                    // Skip bots without a user (this shouldn't happen, but just to be safe)
                    continue;
                }

                // Apply time filtering if needed (except for "Total")
                if (request.TimeFilter != "Total")
                {
                    // Check if this bot had activity within the specified time range
                    if (!BotHasActivityInTimeRange(bot, request.TimeFilter))
                    {
                        continue; // Skip this bot if it doesn't have activity in the time range
                    }
                }

                // Add the bot to the user's list
                if (!result.ContainsKey(bot.User))
                {
                    result[bot.User] = new List<ITradingBot>();
                }

                result[bot.User].Add(bot);
            }

            return result;
        }

        /// <summary>
        /// Checks if a bot has had trading activity within the specified time range
        /// </summary>
        private bool BotHasActivityInTimeRange(ITradingBot bot, string timeFilter)
        {
            // Convert time filter to a DateTime
            DateTime cutoffDate = DateTime.UtcNow;

            switch (timeFilter)
            {
                case "24H":
                    cutoffDate = DateTime.UtcNow.AddHours(-24);
                    break;
                case "3D":
                    cutoffDate = DateTime.UtcNow.AddDays(-3);
                    break;
                case "1W":
                    cutoffDate = DateTime.UtcNow.AddDays(-7);
                    break;
                case "1M":
                    cutoffDate = DateTime.UtcNow.AddMonths(-1);
                    break;
                case "1Y":
                    cutoffDate = DateTime.UtcNow.AddYears(-1);
                    break;
                default:
                    // Default to "Total" (no filtering)
                    return true;
            }

            // Check if there are any positions with activity after the cutoff date
            return bot.Positions.Any(p =>
                p.Date >= cutoffDate ||
                (p.Open.Date >= cutoffDate) ||
                (p.StopLoss.Status == Enums.TradeStatus.Filled && p.StopLoss.Date >= cutoffDate) ||
                (p.TakeProfit1.Status == Enums.TradeStatus.Filled && p.TakeProfit1.Date >= cutoffDate) ||
                (p.TakeProfit2 != null && p.TakeProfit2.Status == Enums.TradeStatus.Filled &&
                 p.TakeProfit2.Date >= cutoffDate));
        }
    }
}