using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using LittleShop.Data;

namespace LittleShop.Services;

public class TelegramBotManagerService : BackgroundService, ITelegramBotManagerService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<TelegramBotManagerService> _logger;
    private readonly ConcurrentDictionary<Guid, BotInstance> _activeBots = new();

    public TelegramBotManagerService(IServiceProvider serviceProvider, ILogger<TelegramBotManagerService> logger)
    {
        _serviceProvider = serviceProvider;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("🤖 Telegram Bot Manager Service starting...");

        try
        {
            // Load all active bots from database
            await LoadActiveBotsAsync();

            // Keep service running
            while (!stoppingToken.IsCancellationRequested)
            {
                // Periodic health checks and cleanup
                await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
                await PerformHealthChecksAsync();
            }
        }
        catch (OperationCanceledException)
        {
            _logger.LogInformation("Telegram Bot Manager Service is stopping.");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error in Telegram Bot Manager Service");
        }
    }

    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Telegram Bot Manager Service started");
        await base.StartAsync(cancellationToken);
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Stopping all Telegram bots...");
        
        foreach (var bot in _activeBots.Values)
        {
            try
            {
                await bot.StopAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error stopping bot {BotId}", bot.BotId);
            }
        }
        
        _activeBots.Clear();
        await base.StopAsync(cancellationToken);
    }

    public async Task<bool> AddBotAsync(Guid botId, string botToken)
    {
        try
        {
            _logger.LogInformation("Adding bot {BotId} to Telegram manager", botId);

            // Validate token first
            using var httpClient = new HttpClient();
            var response = await httpClient.GetAsync($"https://api.telegram.org/bot{botToken}/getMe");
            
            if (!response.IsSuccessStatusCode)
            {
                _logger.LogWarning("Invalid bot token for bot {BotId}", botId);
                return false;
            }

            // Create bot instance (placeholder for now - will implement Telegram.Bot later)
            var botInstance = new BotInstance
            {
                BotId = botId,
                BotToken = botToken,
                IsRunning = false
            };

            _activeBots.TryAdd(botId, botInstance);
            
            _logger.LogInformation("✅ Bot {BotId} added successfully", botId);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to add bot {BotId}", botId);
            return false;
        }
    }

    public async Task<bool> RemoveBotAsync(Guid botId)
    {
        if (_activeBots.TryRemove(botId, out var botInstance))
        {
            await botInstance.StopAsync();
            _logger.LogInformation("Bot {BotId} removed from Telegram manager", botId);
            return true;
        }
        return false;
    }

    public Task<bool> UpdateBotSettingsAsync(Guid botId)
    {
        if (_activeBots.TryGetValue(botId, out var botInstance))
        {
            // Reload settings from database
            _logger.LogInformation("Updating settings for bot {BotId}", botId);
            return Task.FromResult(true);
        }
        return Task.FromResult(false);
    }

    public Task<int> GetActiveBotCount()
    {
        return Task.FromResult(_activeBots.Count(x => x.Value.IsRunning));
    }

    private async Task LoadActiveBotsAsync()
    {
        try
        {
            using var scope = _serviceProvider.CreateScope();
            var botService = scope.ServiceProvider.GetRequiredService<IBotService>();
            
            var activeBots = await botService.GetActiveBots();
            
            _logger.LogInformation("Loading {Count} active bots", activeBots.Count());

        foreach (var bot in activeBots)
        {
            // Look for telegram token in settings
            if (bot.Settings.TryGetValue("telegram", out var telegramSettings) && 
                telegramSettings is System.Text.Json.JsonElement telegramElement &&
                telegramElement.TryGetProperty("botToken", out var tokenElement))
            {
                var token = tokenElement.GetString();
                if (!string.IsNullOrEmpty(token) && token != "YOUR_BOT_TOKEN_HERE")
                {
                    await AddBotAsync(bot.Id, token);
                }
            }
        }
        }
        catch (Microsoft.Data.Sqlite.SqliteException ex) when (ex.Message.Contains("no such table"))
        {
            _logger.LogWarning("Bot tables don't exist yet. Skipping bot loading until database is fully initialized.");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error loading active bots");
        }
    }

    private Task PerformHealthChecksAsync()
    {
        foreach (var kvp in _activeBots)
        {
            try
            {
                // Placeholder for health check logic
                // In real implementation, would ping Telegram API
                _logger.LogDebug("Health check for bot {BotId}", kvp.Key);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Health check failed for bot {BotId}", kvp.Key);
            }
        }
        return Task.CompletedTask;
    }
}

public class BotInstance
{
    public Guid BotId { get; set; }
    public string BotToken { get; set; } = string.Empty;
    public bool IsRunning { get; set; }
    public DateTime StartedAt { get; set; }
    
    public Task StopAsync()
    {
        IsRunning = false;
        return Task.CompletedTask;
    }
}