@implements IDisposable

@inject IJSRuntime JsRuntime

<div class="folder-item" @onclick:stopPropagation @onclick:preventDefault @onclick="Click" @oncontextmenu="Click">
    <input id="@ItemId" type="radio" name="@RadioName" hidden>
    @for (int i = 0; i < Model.Level; i++)
    {
        <div class="indent-guide"></div>
    }
    <div class="folder-icon">
        <span class="mdi @Icon"></span>
    </div>
    <HierachyItemName Model="Model" />
    <HierachyItemDiagnostics Model="Model" />
    <HierachyItemModified Model="Model" />
</div>

@if (IsExpaned)
{
    @foreach (var model in Model.Folders)
    {
        <FolderItem Model="model" />
    }
    @foreach (var model in Model.Files)
    {
        <FileItem Model="model" />
    }
}

@code {
    [CascadingParameter]
    private ScriptWorkspace Workspace { get; set; } = null!;

    [CascadingParameter(Name = "HierachyItemRadioName")]
    protected string RadioName { get; set; } = "script-explorer-item";

    [Parameter, EditorRequired]
    public ScriptFolderModel Model { get; set; } = default!;

    Guid ItemId = Guid.NewGuid();

    public bool IsExpaned { get; private set; }
    private string Icon => IsExpaned ? "mdi-chevron-down" : "mdi-chevron-right";

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if (firstRender)
        {
            Model.OnChildrenChanged += OnChildrenChanged;
        }
    }

    private void OnChildrenChanged()
    {
        this.InvokeAsync(() =>
        {
            StateHasChanged();
        });
    }

    private async Task Click()
    {
        await JsRuntime.InvokeVoidAsync("SetRadioChecked", ItemId);

        if (Workspace.SelectFolder(this.Model)) return;

        if (IsExpaned)
        {
            Collapse();
        }
        else
        {
            Expand();
        }
    }

    public void Collapse()
    {
        IsExpaned = false;
        StateHasChanged();
    }

    public void Expand()
    {
        IsExpaned = true;
        StateHasChanged();
    }

    public void Dispose()
    {
        Model.OnChildrenChanged -= OnChildrenChanged;
        GC.SuppressFinalize(this);
    }
}
