using System;
using System.Diagnostics;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Media;
using Markdig.Syntax.Inlines;
using MarkdownEditor.Constants;

namespace MarkdownEditor.Views.Renderers;

/// <summary>
/// Renders markdown inline elements (bold, italic, links, code, images, etc.).
/// </summary>
public class InlineRenderer
{
    private readonly bool _isDarkMode;
    private readonly double _fontScale;

    /// <summary>
    /// Initializes a new instance of the <see cref="InlineRenderer"/> class.
    /// </summary>
    /// <param name="isDarkMode">Whether the current theme is dark mode.</param>
    /// <param name="fontScale">Font scale factor for text sizing.</param>
    public InlineRenderer(bool isDarkMode = true, double fontScale = 1.0)
    {
        _isDarkMode = isDarkMode;
        _fontScale = fontScale;
    }

    /// <summary>
    /// Builds inline elements from markdown and adds them to the Avalonia inline collection.
    /// </summary>
    /// <param name="inline">The markdown container inline to process.</param>
    /// <param name="inlines">The Avalonia inline collection to add to.</param>
    public void BuildInlines(ContainerInline? inline, InlineCollection inlines)
    {
        if (inline == null) return;

        foreach (var child in inline)
        {
            switch (child)
            {
                case LiteralInline literal:
                    inlines.Add(new Run(literal.Content.ToString()));
                    break;

                case CodeInline code:
                    inlines.Add(CreateCodeInline(code.Content));
                    break;

                case LineBreakInline:
                    inlines.Add(new LineBreak());
                    break;

                case EmphasisInline emphasis:
                    inlines.Add(CreateEmphasisInline(emphasis));
                    break;

                case LinkInline link:
                    AddLinkInline(link, inlines);
                    break;

                case ContainerInline container:
                    BuildInlines(container, inlines);
                    break;
            }
        }
    }

    private Run CreateCodeInline(string content)
    {
        return new Run(content)
        {
            FontFamily = new FontFamily("Consolas,Courier New,monospace"),
            Background = new SolidColorBrush(Color.Parse(_isDarkMode ? "#2D2D2D" : "#F0F0F0")),
            Foreground = new SolidColorBrush(Color.Parse(_isDarkMode ? "#E8E8E8" : "#333333"))
        };
    }

    private Run CreateEmphasisInline(EmphasisInline emphasis)
    {
        var text = MarkdownTextHelper.ExtractText(emphasis);
        var run = new Run(text);

        if (emphasis.DelimiterCount == 2)
        {
            run.FontWeight = FontWeight.Bold;
        }
        else
        {
            run.FontStyle = FontStyle.Italic;
        }

        return run;
    }

    private void AddLinkInline(LinkInline link, InlineCollection inlines)
    {
        if (link.IsImage)
        {
            AddImageInline(link, inlines);
        }
        else
        {
            AddHyperlinkInline(link, inlines);
        }
    }

    private void AddImageInline(LinkInline link, InlineCollection inlines)
    {
        if (link.Url != null && (link.Url.StartsWith("http://") || link.Url.StartsWith("https://")))
        {
            // Remote image - load asynchronously
            var image = new Image
            {
                Stretch = Stretch.Uniform,
                MaxWidth = AppConstants.Layout.ImageMaxWidth,
                Margin = new Thickness(0, 5, 0, 5)
            };

            if (!string.IsNullOrEmpty(link.Title))
            {
                ToolTip.SetTip(image, link.Title);
            }

            LoadImageAsync(image, link.Url);
            inlines.Add(new InlineUIContainer { Child = image });
        }
        else
        {
            // Local images - show placeholder
            inlines.Add(new InlineUIContainer { Child = CreateLocalImagePlaceholder(link) });
        }
    }

    private Border CreateLocalImagePlaceholder(LinkInline link)
    {
        var linkText = MarkdownTextHelper.ExtractText(link);
        var stackPanel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Spacing = 6
        };
        
        // Add image icon indicator
        // Note: Font Awesome icons work great in XAML, but for code-behind rendering
        // we use a simple text indicator. The main UI icons (toolbar, theme toggle) 
        // are already using Font Awesome via XAML.
        var iconText = new TextBlock
        {
            Text = "🖼",
            Foreground = new SolidColorBrush(Color.Parse(AppConstants.Colors.Accent)),
            FontSize = 14,
            VerticalAlignment = VerticalAlignment.Center,
            Margin = new Thickness(0, 0, 4, 0)
        };
        
        // Add text
        var textBlock = new TextBlock
        {
            Text = string.Format(AppConstants.Messages.LocalImagePlaceholder, linkText),
            Foreground = new SolidColorBrush(Color.Parse(AppConstants.Colors.Accent)),
            FontStyle = FontStyle.Italic,
            VerticalAlignment = VerticalAlignment.Center
        };
        
        stackPanel.Children.Add(iconText);
        stackPanel.Children.Add(textBlock);
        
        var placeholder = new Border
        {
            Background = new SolidColorBrush(Color.Parse(_isDarkMode ? "#2D2D2D" : "#F0F0F0")),
            BorderBrush = new SolidColorBrush(Color.Parse(AppConstants.Colors.Accent)),
            BorderThickness = new Thickness(1),
            CornerRadius = new CornerRadius(4),
            Padding = new Thickness(8, 4),
            Margin = new Thickness(0, 5, 0, 5),
            Child = stackPanel
        };

        if (!string.IsNullOrEmpty(link.Title))
        {
            ToolTip.SetTip(placeholder, $"{link.Title}\nPath: {link.Url}");
        }
        else if (!string.IsNullOrEmpty(link.Url))
        {
            ToolTip.SetTip(placeholder, $"Local image: {link.Url}");
        }

        return placeholder;
    }

    private void AddHyperlinkInline(LinkInline link, InlineCollection inlines)
    {
        var linkText = new TextBlock
        {
            Text = MarkdownTextHelper.ExtractText(link),
            Foreground = new SolidColorBrush(Color.Parse(_isDarkMode ? "#8AB4F8" : "#1A73E8")),
            TextDecorations = TextDecorations.Underline,
            Cursor = new Cursor(StandardCursorType.Hand)
        };

        linkText.PointerPressed += (s, e) =>
        {
            try
            {
                if (!string.IsNullOrEmpty(link.Url))
                {
                    Process.Start(new ProcessStartInfo(link.Url) { UseShellExecute = true });
                }
            }
            catch
            {
                // Silently fail if link cannot be opened
            }
        };

        inlines.Add(new InlineUIContainer { Child = linkText });
    }

    private static async void LoadImageAsync(Image image, string url)
    {
        try
        {
            using var httpClient = new System.Net.Http.HttpClient();
            var response = await httpClient.GetAsync(url);
            response.EnsureSuccessStatusCode();

            using var stream = await response.Content.ReadAsStreamAsync();
            using var memoryStream = new System.IO.MemoryStream();
            await stream.CopyToAsync(memoryStream);
            memoryStream.Position = 0;

            image.Source = new Avalonia.Media.Imaging.Bitmap(memoryStream);
        }
        catch
        {
            // Failed to load image - fail silently
        }
    }
}

