@using Ardalis.GuardClauses
@using SharpIDE.Application.Features.Run
@using SharpIDE.Application.Features.SolutionDiscovery
@using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence

@inject RunService RunService

@if (SolutionModel is null)
{
	return;
}
<style>
	.mud-collapse-entering{
		transition-duration: 0.0s !important;
	}
	.mud-collapse-exiting{
		transition-duration: 0.0s !important;
	}
</style>

<MudTreeView T="ISharpIdeNode" Dense="true" ExpandOnClick="true" SelectedValue="@SelectedNode" SelectedValueChanged="@SelectedNodeChanged">
	<MudTreeViewItem T="ISharpIdeNode" TextTypo="Typo.body2" Expanded="true" Icon="@Icons.Material.Filled.Folder" IconColor="Color.Primary" Value="@SolutionModel" Text="@SolutionModel.Name">
		@foreach (var folder in SolutionModel.SlnFolders)
		{
			@GetSolutionFolderFragment(folder)
		}
		@foreach (var project in SolutionModel.Projects)
		{
			@GetProjectFragment(project)
		}
	</MudTreeViewItem>
</MudTreeView>

<MudMenu PositionAtCursor @ref="_contextMenuRef" Dense="true" Modal="false">
	<MudMenuItem Icon="@Icons.Material.Filled.PlayArrow" IconColor="Color.Success" Label="Run" OnClick="@RunProject" />
	<MudMenuItem Label="Build" />
	<MudMenuItem Label="Rebuild" />
	<MudMenuItem Label="Clean" />
	<MudMenuItem Label="Restore" />
</MudMenu>

@code {
	[Parameter, EditorRequired]
	public SharpIdeSolutionModel SolutionModel { get; set; } = null!;

	[Parameter, EditorRequired]
	public ISharpIdeNode? SelectedNode { get; set; } = null!;

	[Parameter]
	public EventCallback<ISharpIdeNode?> SelectedNodeChanged { get; set; }

	private MudMenu _contextMenuRef = null!;
	private SharpIdeProjectModel? _contextMenuProject;

	private async Task OpenProjectContextMenu(MouseEventArgs args, SharpIdeProjectModel project)
	{
		_contextMenuProject = null;
		_contextMenuProject = project;
		await _contextMenuRef.OpenMenuAsync(args);
	}

	private async Task RunProject()
	{
		Guard.Against.Null(_contextMenuProject, nameof(_contextMenuProject));
		await RunService.RunProject(_contextMenuProject);
	}

	private RenderFragment GetSolutionFolderFragment(SharpIdeSolutionFolder slnFolder) =>
		@<text>
			 <MudTreeViewItem T="ISharpIdeNode" TextTypo="Typo.body2" Icon="@Icons.Material.Filled.Folder" IconColor="Color.Primary" Value="@slnFolder" Text="@slnFolder.Name" @bind-Expanded="@slnFolder.Expanded">
				 @if (slnFolder.Expanded)
				 {
					 @foreach (var childFolder in slnFolder.Folders)
					 {
						 @GetSolutionFolderFragment(childFolder)
					 }
					 @foreach (var childProject in slnFolder.Projects)
					 {
						 @GetProjectFragment(childProject)
					 }
					 @foreach(var file in slnFolder.Files)
					 {
						 @GetFileFragment(file)
					 }
				 }
			 </MudTreeViewItem>
		</text>;

	private RenderFragment GetProjectFragment(SharpIdeProjectModel project) =>
		@<text>
			 <div @onclick="@(async s => await OpenProjectContextMenu(s, project))" @oncontextmenu="@(async s => await OpenProjectContextMenu(s, project))" @oncontextmenu:preventDefault @oncontextmenu:stopPropagation>
				 <MudTreeViewItem T="ISharpIdeNode" TextTypo="Typo.body2" Icon="@Icons.Custom.FileFormats.FileCode" IconColor="Color.Success" Text="@project.Name" Value="project" @bind-Expanded="@project.Expanded">
					 @if (project.Expanded)
					 {
						 @foreach (var folder in project.Folders)
						 {
							 @GetFolderFragment(folder)
						 }

						 @foreach (var file in project.Files)
						 {
							 @GetFileFragment(file)
						 }
					 }
				 </MudTreeViewItem>
			 </div>
		 </text>;

	private RenderFragment GetFolderFragment(SharpIdeFolder folder) =>
		@<text>
			 <MudTreeViewItem T="ISharpIdeNode" TextTypo="Typo.body2" Icon="@Icons.Material.Filled.Folder" IconColor="Color.Default" @bind-Expanded="folder.Expanded" Text="@folder.Name" Value="@folder">
				 @if (folder.Expanded)
				 {
					 @foreach (var subFolder in folder.Folders)
					 {
						 @GetFolderFragment(subFolder)
					 }
					 @foreach (var file in folder.Files)
					 {
						 @GetFileFragment(file)
					 }
				 }
			 </MudTreeViewItem>

	</text>;

	private RenderFragment GetFileFragment(SharpIdeFile file) =>
		@<text>
			 <MudTreeViewItem T="ISharpIdeNode" Icon="@Icons.Custom.FileFormats.FileCode" TextTypo="Typo.body2" Text="@file.Name" Value="@file"/>
		</text>;

}
