using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using LittleShop.Client.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.InputFiles;
using Telegram.Bot.Types.ReplyMarkups;

namespace TeleBot.Services
{
    public interface IProductCarouselService
    {
        Task SendProductCarouselAsync(ITelegramBotClient botClient, long chatId, PagedResult<Product> products, string? categoryName = null, int currentPage = 1);
        Task SendSingleProductWithImageAsync(ITelegramBotClient botClient, long chatId, Product product);
        Task<InputOnlineFile?> GetProductImageAsync(Product product);
        Task<bool> IsImageUrlValidAsync(string imageUrl);
    }

    public class ProductCarouselService : IProductCarouselService
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<ProductCarouselService> _logger;
        private readonly HttpClient _httpClient;
        private readonly string _imageCachePath;

        public ProductCarouselService(
            IConfiguration configuration,
            ILogger<ProductCarouselService> logger,
            HttpClient httpClient)
        {
            _configuration = configuration;
            _logger = logger;
            _httpClient = httpClient;
            _imageCachePath = Path.Combine(Environment.CurrentDirectory, "image_cache");
            
            // Ensure cache directory exists
            Directory.CreateDirectory(_imageCachePath);
        }

        public async Task SendProductCarouselAsync(ITelegramBotClient botClient, long chatId, PagedResult<Product> products, string? categoryName = null, int currentPage = 1)
        {
            try
            {
                if (!products.Items.Any())
                {
                    await botClient.SendTextMessageAsync(
                        chatId,
                        "No products available in this category.",
                        replyMarkup: MenuBuilder.CategoryNavigationMenu(null)
                    );
                    return;
                }

                // Send products as media group (carousel) - max 10 items per group
                var productBatches = products.Items.Chunk(10);
                
                foreach (var batch in productBatches)
                {
                    var mediaGroup = new List<InputMediaPhoto>();
                    var productButtons = new List<InlineKeyboardButton[]>();

                    foreach (var product in batch)
                    {
                        // Get product image
                        var image = await GetProductImageAsync(product);
                        
                        if (image != null)
                        {
                            // Create photo with caption
                            var caption = FormatProductCaption(product);
                            var photo = new InputMediaPhoto(image)
                            {
                                Caption = caption,
                                ParseMode = Telegram.Bot.Types.Enums.ParseMode.Markdown
                            };
                            mediaGroup.Add(photo);
                        }
                        else
                        {
                            // If no image, send as text message instead
                            await botClient.SendTextMessageAsync(
                                chatId,
                                FormatProductCaption(product),
                                parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
                                replyMarkup: MenuBuilder.SingleProductMenu(product.Id)
                            );
                        }

                        // Add button for this product
                        productButtons.Add(new[] 
                        { 
                            InlineKeyboardButton.WithCallbackData(
                                $"🛒 {product.Name} - ${product.Price:F2}", 
                                $"product:{product.Id}"
                            ) 
                        });
                    }

                    // Send media group if we have images
                    if (mediaGroup.Any())
                    {
                        try
                        {
                            await botClient.SendMediaGroupAsync(chatId, mediaGroup);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogWarning(ex, "Failed to send media group, falling back to individual messages");
                            
                            // Fallback: send individual messages
                            foreach (var product in batch)
                            {
                                await SendSingleProductWithImageAsync(botClient, chatId, product);
                            }
                        }
                    }

                    // Send navigation buttons
                    var navigationButtons = new List<InlineKeyboardButton[]>();
                    
                    // Add product buttons
                    navigationButtons.AddRange(productButtons);
                    
                    // Add pagination if needed
                    if (products.TotalPages > 1)
                    {
                        var paginationButtons = new List<InlineKeyboardButton>();
                        
                        if (products.HasPreviousPage)
                        {
                            paginationButtons.Add(InlineKeyboardButton.WithCallbackData(
                                "⬅️ Previous", 
                                $"products:page:{currentPage - 1}"
                            ));
                        }
                        
                        paginationButtons.Add(InlineKeyboardButton.WithCallbackData(
                            $"Page {currentPage}/{products.TotalPages}", 
                            "noop"
                        ));
                        
                        if (products.HasNextPage)
                        {
                            paginationButtons.Add(InlineKeyboardButton.WithCallbackData(
                                "Next ➡️", 
                                $"products:page:{currentPage + 1}"
                            ));
                        }
                        
                        navigationButtons.Add(paginationButtons.ToArray());
                    }
                    
                    // Add main navigation
                    navigationButtons.Add(new[] 
                    { 
                        InlineKeyboardButton.WithCallbackData("🛒 View Cart", "cart"),
                        InlineKeyboardButton.WithCallbackData("⬅️ Back to Categories", "browse")
                    });
                    
                    navigationButtons.Add(new[] 
                    { 
                        InlineKeyboardButton.WithCallbackData("🏠 Main Menu", "menu")
                    });

                    var replyMarkup = new InlineKeyboardMarkup(navigationButtons);
                    
                    await botClient.SendTextMessageAsync(
                        chatId,
                        $"📦 *Products in {categoryName ?? "All Categories"}*\n\n" +
                        $"Showing {batch.Count()} products (Page {currentPage} of {products.TotalPages})",
                        parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
                        replyMarkup: replyMarkup
                    );
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error sending product carousel");
                
                // Fallback to text-only product list
                await botClient.SendTextMessageAsync(
                    chatId,
                    MessageFormatter.FormatProductList(products, categoryName),
                    parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
                    replyMarkup: MenuBuilder.ProductListMenu(products, null, currentPage)
                );
            }
        }

        public async Task SendSingleProductWithImageAsync(ITelegramBotClient botClient, long chatId, Product product)
        {
            try
            {
                var image = await GetProductImageAsync(product);
                
                if (image != null)
                {
                    await botClient.SendPhotoAsync(
                        chatId,
                        image,
                        caption: FormatProductCaption(product),
                        parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
                        replyMarkup: MenuBuilder.ProductDetailMenu(product)
                    );
                }
                else
                {
                    // Fallback to text message
                    await botClient.SendTextMessageAsync(
                        chatId,
                        MessageFormatter.FormatProductDetail(product),
                        parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
                        replyMarkup: MenuBuilder.ProductDetailMenu(product)
                    );
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error sending single product with image");
                
                // Fallback to text message
                await botClient.SendTextMessageAsync(
                    chatId,
                    MessageFormatter.FormatProductDetail(product),
                    parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
                    replyMarkup: MenuBuilder.ProductDetailMenu(product)
                );
            }
        }

        public async Task<InputOnlineFile?> GetProductImageAsync(Product product)
        {
            try
            {
                if (!product.Photos.Any())
                {
                    return null;
                }

                // Get the first photo
                var photo = product.Photos.First();
                var imageUrl = photo.Url;

                if (string.IsNullOrEmpty(imageUrl) || !await IsImageUrlValidAsync(imageUrl))
                {
                    return null;
                }

                // Check if image is already cached
                var cacheKey = $"{product.Id}_{photo.Id}";
                var cachedPath = Path.Combine(_imageCachePath, $"{cacheKey}.jpg");
                
                if (File.Exists(cachedPath))
                {
                    return new InputOnlineFile(File.OpenRead(cachedPath), $"{product.Name}.jpg");
                }

                // Download and cache the image
                var imageBytes = await _httpClient.GetByteArrayAsync(imageUrl);
                await File.WriteAllBytesAsync(cachedPath, imageBytes);

                return new InputOnlineFile(File.OpenRead(cachedPath), $"{product.Name}.jpg");
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Failed to get product image for product {ProductId}", product.Id);
                return null;
            }
        }

        public async Task<bool> IsImageUrlValidAsync(string imageUrl)
        {
            try
            {
                if (string.IsNullOrEmpty(imageUrl))
                    return false;

                var response = await _httpClient.HeadAsync(imageUrl);
                return response.IsSuccessStatusCode && 
                       response.Content.Headers.ContentType?.MediaType?.StartsWith("image/") == true;
            }
            catch
            {
                return false;
            }
        }

        private string FormatProductCaption(Product product)
        {
            var caption = $"🛍️ *{product.Name}*\n";
            caption += $"💰 *${product.Price:F2}*\n";
            
            if (!string.IsNullOrEmpty(product.Description))
            {
                var desc = product.Description.Length > 200 
                    ? product.Description.Substring(0, 197) + "..." 
                    : product.Description;
                caption += $"\n_{desc}_";
            }
            
            if (!string.IsNullOrEmpty(product.CategoryName))
            {
                caption += $"\n\n📁 {product.CategoryName}";
            }

            return caption;
        }
    }
}
