using System.Collections.Generic;
using Avalonia.Controls;
using Markdig.Syntax;

namespace MarkdownEditor.Views.Renderers;

/// <summary>
/// Coordinates multiple markdown block renderers to render a complete markdown document.
/// Uses a chain of responsibility pattern to delegate rendering to appropriate renderers.
/// </summary>
public class MarkdownRendererCoordinator
{
    private readonly List<IMarkdownBlockRenderer> _renderers;

    /// <summary>
    /// Initializes a new instance of the <see cref="MarkdownRendererCoordinator"/> class.
    /// </summary>
    /// <param name="isDarkMode">Whether the current theme is dark mode.</param>
    /// <param name="fontScale">Font scale factor for text sizing (1.0 = 14px base).</param>
    public MarkdownRendererCoordinator(bool isDarkMode = true, double fontScale = 1.0)
    {
        var inlineRenderer = new InlineRenderer(isDarkMode, fontScale);
        
        _renderers = new List<IMarkdownBlockRenderer>
        {
            new HeadingRenderer(fontScale),
            new CodeBlockRenderer(isDarkMode, fontScale),
            new ParagraphRenderer(inlineRenderer),
            new ThematicBreakRenderer(isDarkMode),
            new ListRenderer(this),      // Pass coordinator for nested rendering
            new QuoteRenderer(this),     // Pass coordinator for nested rendering
            new TableRenderer(this, isDarkMode, fontScale)      // Pass coordinator for nested rendering
        };
    }

    /// <summary>
    /// Renders a markdown block by delegating to the appropriate renderer.
    /// </summary>
    /// <param name="block">The markdown block to render.</param>
    /// <returns>The rendered Avalonia control, or null if no renderer can handle the block.</returns>
    public Control? RenderBlock(Block block)
    {
        foreach (var renderer in _renderers)
        {
            if (renderer.CanRender(block))
            {
                return renderer.Render(block);
            }
        }

        return null;
    }

    /// <summary>
    /// Renders multiple markdown blocks into a collection of controls.
    /// </summary>
    /// <param name="blocks">The markdown blocks to render.</param>
    /// <returns>A collection of rendered controls.</returns>
    public IEnumerable<Control> RenderBlocks(IEnumerable<Block> blocks)
    {
        var controls = new List<Control>();
        foreach (var block in blocks)
        {
            var control = RenderBlock(block);
            if (control != null)
            {
                controls.Add(control);
            }
        }
        return controls;
    }
}

