@implements IDisposable
@rendermode InteractiveServer
@using Wave.Utilities

@inject IStringLocalizer<AdvancedMarkdownEditor> Localizer

<section class="grid grid-cols-1 lg:grid-cols-2 gap-x-8 gap-y-4">
	<div class="flex">
		<div class="join join-vertical min-h-96 h-full w-full">
			<Toolbar>
				<ToolbarSection>
					<ToolbarButton onclick="window.insertBeforeSelection('# ', true);"
								   title="@Localizer["Tools_H1_Tooltip"]">
						<strong>@Localizer["Tools_H1_Label"]</strong>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('## ', true);"
								   title="@Localizer["Tools_H2_Tooltip"]">
						<strong>@Localizer["Tools_H2_Label"]</strong>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('### ', true);"
								   title="@Localizer["Tools_H3_Tooltip"]">
						<strong>@Localizer["Tools_H3_Label"]</strong>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('#### ', true);"
								   title="@Localizer["Tools_H4_Tooltip"]">
						@Localizer["Tools_H4_Label"]
					</ToolbarButton>
				</ToolbarSection>
				<ToolbarSection>
					<ToolbarButton onclick="window.insertBeforeAndAfterSelection('**');"
								   title="@Localizer["Tools_Bold_Tooltip"]">
						<strong>B</strong>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeAndAfterSelection('*')"
								   title="@Localizer["Tools_Italic_Tooltip"]">
						<em>I</em>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeAndAfterSelection('++')"
								   title="@Localizer["Tools_Underline_Tooltip"]">
						<u>U</u>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeAndAfterSelection('~~')"
								   title="@Localizer["Tools_StrikeThrough_Tooltip"]">
						<del>@Localizer["Tools_StrikeThrough_Label"]</del>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeAndAfterSelection('==')"
								   title="@Localizer["Tools_Mark_Tooltip"]">
						<mark>@Localizer["Tools_Mark_Label"]</mark>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('> ', true)"
								   title="@Localizer["Tools_Cite_Tooltip"]">
						| <em>@Localizer["Tools_Cite_Label"]</em>
					</ToolbarButton>
				</ToolbarSection>
				<ToolbarSection>
					<ToolbarButton onclick="window.insertBeforeSelection('1. ', true)">
						1.
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('a. ', true)">
						a.
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('A. ', true)">
						A.
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('i. ', true)">
						i.
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeSelection('I. ', true)">
						I.
					</ToolbarButton>
				</ToolbarSection>
				<ToolbarSection>
					<ToolbarButton onclick="window.insertBeforeAndAfterSelection('`')"
								   title="@Localizer["Tools_CodeLine_Tooltip"]">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4">
							<path fill-rule="evenodd" d="M14.447 3.026a.75.75 0 0 1 .527.921l-4.5 16.5a.75.75 0 0 1-1.448-.394l4.5-16.5a.75.75 0 0 1 .921-.527ZM16.72 6.22a.75.75 0 0 1 1.06 0l5.25 5.25a.75.75 0 0 1 0 1.06l-5.25 5.25a.75.75 0 1 1-1.06-1.06L21.44 12l-4.72-4.72a.75.75 0 0 1 0-1.06Zm-9.44 0a.75.75 0 0 1 0 1.06L2.56 12l4.72 4.72a.75.75 0 0 1-1.06 1.06L.97 12.53a.75.75 0 0 1 0-1.06l5.25-5.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" />
						</svg>
					</ToolbarButton>
					<ToolbarButton onclick="window.insertBeforeAndAfterSelection('\n```\n')"
								   title="@Localizer["Tools_CodeBlock_Tooltip"]">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-4 h-4">
							<path fill-rule="evenodd" d="M3 6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V6Zm14.25 6a.75.75 0 0 1-.22.53l-2.25 2.25a.75.75 0 1 1-1.06-1.06L15.44 12l-1.72-1.72a.75.75 0 1 1 1.06-1.06l2.25 2.25c.141.14.22.331.22.53Zm-10.28-.53a.75.75 0 0 0 0 1.06l2.25 2.25a.75.75 0 1 0 1.06-1.06L8.56 12l1.72-1.72a.75.75 0 1 0-1.06-1.06l-2.25 2.25Z" clip-rule="evenodd" />
						</svg>
					</ToolbarButton>
				</ToolbarSection>
			</Toolbar>
			@ChildContent
		</div>
	</div>
    <div class="bg-base-200 p-2">
        @if (!string.IsNullOrWhiteSpace(Title)) {
            <h2 class="text-2xl lg:text-4xl font-bold mb-6 hyphens-auto">@Title</h2>
        }
        @if (!string.IsNullOrWhiteSpace(Markdown)) {
            <div class="prose prose-neutral max-w-none hyphens-auto text-justify">
                @HtmlPreview
            </div>
        } else {
            <div class="flex flex-col gap-4">
                <div class="skeleton h-4 w-full"></div>
                <div class="skeleton h-4 w-full"></div>
                <div class="skeleton h-32 w-full"></div>
                <div class="skeleton h-4 w-full"></div>
                <div class="skeleton h-4 w-full"></div>
                <div class="skeleton h-4 w-full"></div>
            </div>
        }
        </div>
</section>

<SectionContent SectionName="scripts">
</SectionContent>

@code {
    [Parameter]
    public required Func<string?> MarkdownCallback { get; set; }
    [Parameter]
    public string? Title { get; set; }
    [Parameter]
    public required RenderFragment ChildContent { get; set; }

    private string? Markdown { get; set; }
    private MarkupString HtmlPreview { get; set; } = new();

    private CancellationTokenSource? Token { get; set; }
    private Timer? Timer { get; set; }

    protected override void OnInitialized() {
        Timer = new Timer(_ => {
            UpdateHtml();
        }, null, TimeSpan.FromMilliseconds(250), TimeSpan.FromSeconds(1));
    }

    private void UpdateHtml() {
        try {
            string? markdown = MarkdownCallback.Invoke();
            if (string.IsNullOrWhiteSpace(markdown)) return;

            Token?.Cancel();
            Token = new CancellationTokenSource();

            string html = MarkdownUtilities.Parse(markdown);
            Markdown = markdown;
            HtmlPreview = new MarkupString(html);
            InvokeAsync(StateHasChanged);
        } catch (Exception ex) {
            Console.Error.WriteLine(ex);
        } finally {
            Token = null;
        }
    }

    public void Dispose() {
        Timer?.Dispose();
        Timer = null;
    }

}
