@using XtermBlazor

<style>
	.xterm-underline-5.xterm-underline-5 { /* Specificity hack lol */
		text-decoration: dotted underline;
	}
</style>

<div style="width: 100%; height: 100%; overflow: visible">
	<Xterm @ref="@_terminalRef" Options="@_options" Style="height: calc(100% - 1px)" Addons="@_addons" OnFirstRender="@OnFirstRender"/>
</div>

@code {
	private Xterm _terminalRef = null!;

	private readonly TerminalOptions _options = new TerminalOptions
	{
		CursorBlink = true,
		CursorStyle = CursorStyle.Bar,
		Columns = 140,
		FontFamily = "Cascadia Mono",
		FontWeightBold = "400",
		Theme =
		{
			BrightGreen = "#98c379",
			BrightRed = "#e06c75",
			Foreground = "#dcdfe4",
			Background = "#282c34",
		},
	};

	private HashSet<string> _addons = ["addon-fit"];

	private TaskCompletionSource _firstRenderTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

	public async Task Write(byte[] line)
	{
		if (_firstRenderTask.Task.IsCompleted is false) await _firstRenderTask.Task;
		await _terminalRef.Write(line);
	}
	public async Task Write(string line)
	{
		if (_firstRenderTask.Task.IsCompleted is false) await _firstRenderTask.Task;
		await _terminalRef.Write(line);
	}

	public async Task Clear()
	{
		if (_firstRenderTask.Task.IsCompleted is false) await _firstRenderTask.Task;
		if (_terminalRef is not null)
		{
			await _terminalRef.Reset();
			await InvokeAsync(StateHasChanged);
		}
	}

	private async Task OnFirstRender()
	{
		await _terminalRef.Addon("addon-fit").InvokeVoidAsync("fit");
		_firstRenderTask.SetResult();
		_ = Task.Run(async () =>
		{
			try
			{
				while (true)
				{
					await Task.Delay(500).ConfigureAwait(false);
					await InvokeAsync(async () =>
					{
						await _terminalRef.Addon("addon-fit").InvokeVoidAsync("fit");
					});
				}

			}
			catch (Exception e)
			{
				await DispatchExceptionAsync(e);
			}
		});
	}
}
