using System;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components;
using static FastReport.Web.Blazor.Export.BlazorConstants;

namespace FastReport.Web.Blazor.Export
{
    public class RenderContext
    {
        internal int Seq
        { 
            get;
            private set;
        }

        internal RenderTreeBuilder Builder
        {
            get;
        }

        private EventHandler<OnClickEventArgs> OnClick
        {
            get;
        }

        public RenderContext(int seq, RenderTreeBuilder builder) : this(builder)
        {
            Seq = seq;
        }

        public RenderContext(RenderTreeBuilder builder, EventHandler<OnClickEventArgs> eventHandler)
            : this(builder)
        {
            OnClick = eventHandler;
        }

        public RenderContext(RenderTreeBuilder builder)
        {
            Builder = builder;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private int GetSequence()
        {
            return Seq++;
        }

        internal void AddMarkupContent(string markupContent)
        {
            Builder.AddMarkupContent(GetSequence(), markupContent);
        }

        internal void AddContent(RenderFragment fragment)
        {
            Builder.AddContent(GetSequence(), fragment);
        }

        internal void AddContent(MarkupString markupContent)
        {
            Builder.AddContent(GetSequence(), markupContent);
        }

        internal void AddContent(string textContent)
        {
            Builder.AddContent(GetSequence(), textContent);
        }

        internal void AddAttribute(string name, string value)
        {
            Builder.AddAttribute(GetSequence(), name, value);
        }

        internal void AddAttribute(string name, object value)
        {
            Builder.AddAttribute(GetSequence(), name, value);
        }

        internal void AddAttribute(string name, MulticastDelegate value)
        {
            Builder.AddAttribute(GetSequence(), name, value);
        }

        internal void AddOnClick(OnClickEventArgs click)
        {
            Builder.AddAttribute(GetSequence(), ONCLICK, (Action)(() =>
            {
                OnClick?.Invoke(null, click);
            }));
        }

        internal void AddAction(string actionName, Action<ReportComponentBase> action)
        {
            Builder.AddAttribute(GetSequence(), actionName, action);
        }

        internal void AddOnChange(OnClickEventArgs click)
        {
            Builder.AddAttribute(GetSequence(), ONCHANGE, (Action)(() =>
            {
                OnClick?.Invoke(null, click);
            }));
        }

        internal void AddAttribute(string name, EventCallback<OnClickEventArgs> value)
        {
            Builder.AddAttribute(GetSequence(), name, value);
        }

        internal void OpenElement(string elementName)
        {
            Builder.OpenElement(GetSequence(), elementName);
        }

        internal void OpenComponent<T>() where T : IComponent
        {
            Builder.OpenComponent<T>(GetSequence());
        }

        internal void CloseElement()
        {
            Builder.CloseElement();
        }

        internal void CloseComponent()
        {
            Builder.CloseComponent();
        }
    }
}
