using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

namespace SelectPdf.Samples
{
    public interface IComponentHtmlRenderer
    {
        // Renders a Blazor component to a complete HTML document string,
        // wrapping the component output inside the same <html><head><body>
        // shell used by the live MainLayout. Used by CurrentWebPageToPdf to
        // capture the form (with the values entered in the page controls)
        // and convert it to PDF.
        Task<string> RenderToFullPageAsync<TComponent>(IDictionary<string, object> parameters, string baseUrl)
            where TComponent : IComponent;
    }

    public sealed class ComponentHtmlRenderer : IComponentHtmlRenderer
    {
        private readonly HtmlRenderer _htmlRenderer;

        public ComponentHtmlRenderer(HtmlRenderer htmlRenderer)
        {
            _htmlRenderer = htmlRenderer;
        }

        public Task<string> RenderToFullPageAsync<TComponent>(IDictionary<string, object> parameters, string baseUrl)
            where TComponent : IComponent
        {
            return _htmlRenderer.Dispatcher.InvokeAsync(async () =>
            {
                var paramView = ParameterView.FromDictionary(parameters);
                var output = await _htmlRenderer.RenderComponentAsync<TComponent>(paramView);
                string componentMarkup = output.ToHtmlString();

                // Wrap in the shared SelectPdf.Web design-system shell so the
                // captured PDF matches the rest of the sample (full inner-page
                // layout — chrome + "All samples" side rail + C# code panel +
                // assets/css/spdf.css), not the legacy theme. The component's
                // type name is the page slug (e.g. CurrentWebPageToPdf), which
                // both highlights the rail item and locates the .razor source
                // for the code panel — mirroring MainLayout.TryReadSampleCode.
                string slug = typeof(TComponent).Name;
                string codeHtml = TryReadSampleCode(slug);
                return SamplePageShell.Wrap(componentMarkup, baseUrl, slug, codeHtml);
            });
        }

        // Reads the .razor source for the rendered page from disk and
        // pretty-prints it via ColorCode, mirroring MainLayout.TryReadSampleCode
        // so the converter-captured PDF shows the same "Sample code · C#" panel
        // the live page does. Returns "" on any error so the panel hides cleanly.
        private static string TryReadSampleCode(string slug)
        {
            try
            {
                if (string.IsNullOrEmpty(slug))
                {
                    return string.Empty;
                }
                string razorPath = System.IO.Path.Combine(
                    ServerInfo.ServerPath, "Components", "Pages", slug + ".razor");
                if (!System.IO.File.Exists(razorPath))
                {
                    return string.Empty;
                }
                string code = System.IO.File.ReadAllText(razorPath);
                return new ColorCode.HtmlFormatter().GetHtmlString(code, ColorCode.Languages.CSharp);
            }
            catch
            {
                return string.Empty;
            }
        }
    }
}
