using Managing.Application.Abstractions;
using Managing.Core;
using MediatR;
using Microsoft.Extensions.Logging;
using static Managing.Common.Enums;

namespace Managing.Application.ManageBot;

public class LoadBackupBotCommandHandler : IRequestHandler<LoadBackupBotCommand, string>
{
    private readonly IBotService _botService;
    private readonly ILogger<LoadBackupBotCommandHandler> _logger;

    public LoadBackupBotCommandHandler(
        ILogger<LoadBackupBotCommandHandler> logger, IBotService botService)
    {
        _logger = logger;
        _botService = botService;
    }

    public Task<string> Handle(LoadBackupBotCommand request, CancellationToken cancellationToken)
    {
        var backupBots = _botService.GetSavedBots().ToList();
        _logger.LogInformation("Loading {Count} backup bots.", backupBots.Count);

        var result = new Dictionary<string, BotStatus>();
        bool anyBackupStarted = false;
        bool anyBotActive = false;

        foreach (var backupBot in backupBots)
        {
            try
            {
                if (backupBot.LastStatus == BotStatus.Down)
                {
                    _logger.LogInformation("Skipping backup bot {Identifier} as it is marked as Down.",
                        backupBot.Identifier);
                    continue;
                }

                var activeBot = _botService.GetActiveBots().FirstOrDefault(b => b.Identifier == backupBot.Identifier);

                if (activeBot == null)
                {
                    _logger.LogInformation("No active instance found for bot {Identifier}. Starting backup...",
                        backupBot.Identifier);

                    // Start the bot from backup
                    _botService.StartBotFromBackup(backupBot);

                    // Wait a short time to allow the bot to initialize
                    Thread.Sleep(1000);

                    // Try to get the active bot multiple times to ensure it's properly started
                    int attempts = 0;
                    const int maxAttempts = 5;

                    while (attempts < maxAttempts)
                    {
                        activeBot = _botService.GetActiveBots()
                            .FirstOrDefault(b => b.Identifier == backupBot.Identifier);
                        if (activeBot != null)
                        {
                            result[activeBot.Identifier] = BotStatus.Up;
                            anyBackupStarted = true;
                            _logger.LogInformation("Backup bot {Identifier} started successfully.",
                                backupBot.Identifier);
                            break;
                        }

                        attempts++;
                        if (attempts < maxAttempts)
                        {
                            Thread.Sleep(1000); // Wait another second before next attempt
                        }
                    }

                    if (activeBot == null)
                    {
                        result[backupBot.Identifier] = BotStatus.Down;
                        _logger.LogWarning("Backup bot {Identifier} failed to start after {MaxAttempts} attempts.",
                            backupBot.Identifier, maxAttempts);
                    }
                }
                else
                {
                    var status = MiscExtensions.ParseEnum<BotStatus>(activeBot.GetStatus());
                    result[activeBot.Identifier] = status;
                    anyBotActive = true;
                    _logger.LogInformation("Bot {Identifier} is already active with status {Status}.",
                        activeBot.Identifier,
                        status);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error loading bot {Identifier}. Deleting its backup.", backupBot.Identifier);
                result[backupBot.Identifier] = BotStatus.Down;
            }
        }

        var summary = string.Join(", ", result.Select(b => $"{b.Key}: {b.Value}"));
        _logger.LogInformation("Bot loading completed. Summary: {Summary}", summary);

        // Determine final status
        BotStatus finalStatus = anyBackupStarted
            ? BotStatus.Backup
            : anyBotActive
                ? BotStatus.Up
                : BotStatus.Down;

        _logger.LogInformation("Final aggregate bot status: {FinalStatus}", finalStatus);

        return Task.FromResult(finalStatus.ToString());
    }
}

public class LoadBackupBotCommand : IRequest<string>
{
}