using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Telegram.Bot;
using Telegram.Bot.Polling;
using Telegram.Bot.Types;
using Telegram.Bot.Exceptions;
using Telegram.Bot.Types.Enums;
using TeleBot.Handlers;
using TeleBot.Services;

namespace TeleBot
{
    public class TelegramBotService : IHostedService
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<TelegramBotService> _logger;
        private readonly IServiceProvider _serviceProvider;
        private readonly ICommandHandler _commandHandler;
        private readonly ICallbackHandler _callbackHandler;
        private readonly IMessageHandler _messageHandler;
        private readonly IMessageDeliveryService _messageDeliveryService;
        private ITelegramBotClient? _botClient;
        private CancellationTokenSource? _cancellationTokenSource;
        
        public TelegramBotService(
            IConfiguration configuration,
            ILogger<TelegramBotService> logger,
            IServiceProvider serviceProvider,
            ICommandHandler commandHandler,
            ICallbackHandler callbackHandler,
            IMessageHandler messageHandler,
            IMessageDeliveryService messageDeliveryService)
        {
            _configuration = configuration;
            _logger = logger;
            _serviceProvider = serviceProvider;
            _commandHandler = commandHandler;
            _callbackHandler = callbackHandler;
            _messageHandler = messageHandler;
            _messageDeliveryService = messageDeliveryService;
        }
        
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            var botToken = _configuration["Telegram:BotToken"];
            if (string.IsNullOrEmpty(botToken) || botToken == "YOUR_BOT_TOKEN_HERE")
            {
                _logger.LogError("Bot token not configured. Please set Telegram:BotToken in appsettings.json");
                return;
            }
            
            _botClient = new TelegramBotClient(botToken);
            _cancellationTokenSource = new CancellationTokenSource();
            
            var receiverOptions = new ReceiverOptions
            {
                AllowedUpdates = Array.Empty<UpdateType>(),
                ThrowPendingUpdates = true
            };
            
            _botClient.StartReceiving(
                HandleUpdateAsync,
                HandleErrorAsync,
                receiverOptions,
                cancellationToken: _cancellationTokenSource.Token
            );
            
            var me = await _botClient.GetMeAsync(cancellationToken);
            _logger.LogInformation("Bot started: @{Username} ({Id})", me.Username, me.Id);
            
            // Set bot client for message delivery service
            if (_messageDeliveryService is MessageDeliveryService deliveryService)
            {
                deliveryService.SetBotClient(_botClient);
            }
        }
        
        public Task StopAsync(CancellationToken cancellationToken)
        {
            _cancellationTokenSource?.Cancel();
            _logger.LogInformation("Bot stopped");
            return Task.CompletedTask;
        }
        
        private async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
        {
            try
            {
                if (update.Type == UpdateType.Message && update.Message != null)
                {
                    var message = update.Message;
                    
                    // Handle commands
                    if (message.Text != null && message.Text.StartsWith("/"))
                    {
                        var parts = message.Text.Split(' ', 2);
                        var command = parts[0].ToLower();
                        var args = parts.Length > 1 ? parts[1] : null;
                        
                        await _commandHandler.HandleCommandAsync(botClient, message, command, args);
                    }
                    else
                    {
                        // Handle regular messages (for checkout flow, etc.)
                        await _messageHandler.HandleMessageAsync(botClient, message);
                    }
                }
                else if (update.Type == UpdateType.CallbackQuery && update.CallbackQuery != null)
                {
                    await _callbackHandler.HandleCallbackAsync(botClient, update.CallbackQuery);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error handling update {UpdateId}", update.Id);
            }
        }
        
        private Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
        {
            var errorMessage = exception switch
            {
                ApiRequestException apiException => $"Telegram API Error: [{apiException.ErrorCode}] {apiException.Message}",
                _ => exception.ToString()
            };
            
            _logger.LogError(exception, "Bot error: {ErrorMessage}", errorMessage);
            return Task.CompletedTask;
        }
    }
}