@using System.Collections.Immutable
@using Microsoft.CodeAnalysis
@using SharpIDE.Application.Features.Analysis
@using SharpIDE.Application.Features.SolutionDiscovery
@using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence

@inject RoslynAnalysis RoslynAnalysis

@if (_diagnostics.Length is not 0)
{
	<MudTreeViewItem T="string" TextTypo="Typo.body2" EndTextTypo="Typo.caption" Expanded="false" Icon="@Icons.Material.Filled.Code" IconColor="Color.Success" Value="@ProjectModel.Name" Text="@ProjectModel.Name" EndText="@($"{_diagnostics.Length} diagnostics")">
		@foreach (var diagnostic in _diagnostics)
		{
			<MudTreeViewItem T="string" TextTypo="Typo.body2" OnClick="@(async () => await OpenDocumentContainingDiagnostic(diagnostic.Diagnostic))" Icon="@Icons.Material.Filled.Warning" IconColor="@GetDiagnosticIconColour(diagnostic.Diagnostic)" Value="@diagnostic.ToString()">
				<BodyContent>
					<MudText Typo="Typo.body2">
						@diagnostic.Diagnostic.GetMessage()
						<MudText Typo="Typo.caption" Style="color: var(--mud-palette-gray-dark)">@diagnostic.Diagnostic.Id</MudText>
					</MudText>
				</BodyContent>
			</MudTreeViewItem>
		}
	</MudTreeViewItem>
}

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

	[Parameter]
	public EventCallback<SharpIdeFile> OnFileSelected { get; set; }

	private ImmutableArray<SharpIdeDiagnostic> _diagnostics = [];

	private static Color GetDiagnosticIconColour(Diagnostic diagnostic) => diagnostic.Severity switch
	{
		DiagnosticSeverity.Error => Color.Error,
		DiagnosticSeverity.Warning => Color.Warning,
		DiagnosticSeverity.Info => Color.Info,
		_ => Color.Info
	};

	private async Task OpenDocumentContainingDiagnostic(Diagnostic diagnostic)
	{
		// TODO: probably store a flat list of all files in each project to avoid recursion
		var file = ProjectModel.Files
			.Concat(ProjectModel.Folders.SelectMany(f => f.GetAllFiles()))
			.Single(s => s.Path == diagnostic.Location.SourceTree?.GetMappedLineSpan(diagnostic.Location.SourceSpan).Path);

		await OnFileSelected.InvokeAsync(file);
	}

	protected override async Task OnInitializedAsync()
	{
		var diagnostics = await RoslynAnalysis.GetProjectDiagnostics(ProjectModel);
		_diagnostics = diagnostics;
	}
}
