using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Telegram.Bot;
using TeleBot.Services;

namespace TeleBot.Services
{
    public interface IMessageDeliveryService
    {
        Task DeliverPendingMessagesAsync(ITelegramBotClient bot);
        void SetBotClient(ITelegramBotClient botClient);
    }

    public class MessageDeliveryService : IMessageDeliveryService, IHostedService
    {
        private readonly ILittleShopService _shopService;
        private readonly ILogger<MessageDeliveryService> _logger;
        private readonly IConfiguration _configuration;
        private Timer? _deliveryTimer;
        private readonly int _pollIntervalSeconds;
        private ITelegramBotClient? _botClient;

        public MessageDeliveryService(
            ILittleShopService shopService,
            ILogger<MessageDeliveryService> logger,
            IConfiguration configuration)
        {
            _shopService = shopService;
            _logger = logger;
            _configuration = configuration;
            _pollIntervalSeconds = configuration.GetValue<int>("MessageDelivery:PollIntervalSeconds", 30);
        }

        public void SetBotClient(ITelegramBotClient botClient)
        {
            _botClient = botClient;
            _logger.LogInformation("Bot client set for message delivery service");
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Starting Message Delivery Service - polling every {Interval} seconds", _pollIntervalSeconds);
            
            _deliveryTimer = new Timer(CheckAndDeliverMessages, null, TimeSpan.Zero, TimeSpan.FromSeconds(_pollIntervalSeconds));
            
            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _deliveryTimer?.Change(Timeout.Infinite, 0);
            _deliveryTimer?.Dispose();
            _logger.LogInformation("Stopped Message Delivery Service");
            return Task.CompletedTask;
        }

        private async void CheckAndDeliverMessages(object? state)
        {
            try
            {
                _logger.LogInformation("=== Checking for pending messages to deliver ===");
                
                if (_botClient != null)
                {
                    await DeliverPendingMessagesAsync(_botClient);
                }
                else
                {
                    _logger.LogWarning("Bot client not available for message delivery");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error in message delivery timer");
            }
        }

        public async Task DeliverPendingMessagesAsync(ITelegramBotClient bot)
        {
            try
            {
                // Get pending messages from the API
                var pendingMessages = await _shopService.GetPendingMessagesAsync();
                
                if (pendingMessages?.Any() != true)
                {
                    _logger.LogInformation("No pending messages to deliver");
                    return;
                }

                _logger.LogInformation("Found {Count} pending messages to deliver", pendingMessages.Count());

                foreach (var message in pendingMessages.Take(10)) // Limit to 10 messages per batch
                {
                    try
                    {
                        await DeliverMessageAsync(bot, message);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Failed to deliver message {MessageId}", message.Id);
                        
                        // Mark message as failed
                        await _shopService.MarkMessageAsFailedAsync(message.Id, ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking for pending messages");
            }
        }

        private async Task DeliverMessageAsync(ITelegramBotClient bot, CustomerMessage message)
        {
            try
            {
                if (message.TelegramUserId <= 0)
                {
                    throw new InvalidOperationException($"Invalid Telegram User ID: {message.TelegramUserId}");
                }

                // Format the message for Telegram
                var messageText = FormatMessageForTelegram(message);

                // Send message to customer via Telegram
                var sentMessage = await bot.SendTextMessageAsync(
                    chatId: message.TelegramUserId,
                    text: messageText,
                    parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown);

                // Mark message as sent
                await _shopService.MarkMessageAsSentAsync(message.Id, sentMessage.MessageId.ToString());

                _logger.LogInformation("Delivered message {MessageId} to customer {TelegramUserId}", 
                    message.Id, message.TelegramUserId);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to deliver message {MessageId} to Telegram user {TelegramUserId}", 
                    message.Id, message.TelegramUserId);
                throw;
            }
        }

        private static string FormatMessageForTelegram(CustomerMessage message)
        {
            var emoji = message.Type switch
            {
                MessageType.OrderUpdate => "📦",
                MessageType.PaymentReminder => "💰", 
                MessageType.ShippingInfo => "🚚",
                MessageType.CustomerService => "🎧",
                MessageType.SystemAlert => "⚠️",
                _ => "📬"
            };

            var urgentPrefix = message.IsUrgent ? "🚨 *URGENT* " : "";
            
            var formattedMessage = $"{urgentPrefix}{emoji} *{message.Subject}*\n\n{message.Content}";
            
            if (!string.IsNullOrEmpty(message.OrderReference))
            {
                formattedMessage += $"\n\n*Order:* {message.OrderReference}";
            }
            
            formattedMessage += $"\n\n*From: LittleShop Support*";
            
            return formattedMessage;
        }
    }

    // Simplified message structures for TeleBot
    public class CustomerMessage
    {
        public Guid Id { get; set; }
        public Guid CustomerId { get; set; }
        public long TelegramUserId { get; set; }
        public string Subject { get; set; } = string.Empty;
        public string Content { get; set; } = string.Empty;
        public MessageType Type { get; set; }
        public bool IsUrgent { get; set; }
        public string? OrderReference { get; set; }
        public DateTime CreatedAt { get; set; }
        public int Direction { get; set; } // 0 = AdminToCustomer, 1 = CustomerToAdmin
    }

    public class PendingMessageDto
    {
        public Guid Id { get; set; }
        public Guid CustomerId { get; set; }
        public long TelegramUserId { get; set; }
        public string Subject { get; set; } = string.Empty;
        public string Content { get; set; } = string.Empty;
        public int Type { get; set; }
        public bool IsUrgent { get; set; }
        public string? OrderReference { get; set; }
        public DateTime CreatedAt { get; set; }
    }

    public enum MessageType
    {
        OrderUpdate = 0,
        PaymentReminder = 1,
        ShippingInfo = 2,
        CustomerService = 3,
        Marketing = 4,
        SystemAlert = 5
    }
}