@using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit

@* Execution-chain tree (Audit Log ParentExecutionId feature, Task 10).
   A custom recursive Blazor tree: the host hands in the FLAT ExecutionTreeNode
   list the repository returns; this component assembles it into a tree (joining
   ParentExecutionId → a parent's ExecutionId), then renders depth-first.

   Recursion is expressed by the component rendering <ExecutionTree> for each
   child subtree. To keep that recursion finite even on corrupt/cyclic input,
   the assembled subtree is computed ONCE at the root (Depth == 0) and threaded
   downward via the PreBuiltRoots parameter — child instances never re-run the
   flat-list assembly, and the assembly itself tracks visited ExecutionIds so a
   cycle is broken on first revisit. *@

@if (_rootsToRender.Count == 0)
{
    return;
}

<ul class="execution-tree @(Depth == 0 ? "execution-tree--root" : "")"
    data-test="execution-tree@(Depth == 0 ? "" : "-subtree")">
    @foreach (var subtree in _rootsToRender)
    {
        var node = subtree.Node;
        var isCurrent = node.ExecutionId == ArrivedFromExecutionId;
        var isStub = node.RowCount == 0;
        <li class="execution-tree-item" @key="node.ExecutionId">
            <div class="execution-tree-node @(isCurrent ? "execution-tree-node--current" : "") @(isStub ? "execution-tree-node--stub" : "")"
                 data-test="tree-node-@node.ExecutionId">
                @if (subtree.Children.Count > 0)
                {
                    <button type="button"
                            class="execution-tree-toggle"
                            data-test="tree-toggle-@node.ExecutionId"
                            aria-expanded="@(IsExpanded(node.ExecutionId) ? "true" : "false")"
                            aria-label="@(IsExpanded(node.ExecutionId) ? "Collapse" : "Expand") child executions"
                            @onclick="() => ToggleExpand(node.ExecutionId)">
                        <span class="execution-tree-toggle-glyph" aria-hidden="true">
                            @(IsExpanded(node.ExecutionId) ? "−" : "+")
                        </span>
                    </button>
                }
                else
                {
                    <span class="execution-tree-toggle execution-tree-toggle--leaf" aria-hidden="true"></span>
                }

                <div class="execution-tree-body"
                     @ondblclick="() => OnNodeActivated.InvokeAsync(node.ExecutionId)">
                    <div class="execution-tree-headline">
                        <a class="execution-tree-link font-monospace"
                           data-test="tree-node-link-@node.ExecutionId"
                           href="@AuditLogUrl(node.ExecutionId)"
                           title="Open the Audit Log filtered to execution @node.ExecutionId">
                            @ShortId(node.ExecutionId)
                        </a>
                        @if (isCurrent)
                        {
                            <span class="badge text-bg-primary execution-tree-tag"
                                  data-test="tree-current-tag-@node.ExecutionId">Arrived from</span>
                        }
                        @if (isStub)
                        {
                            <span class="badge text-bg-secondary execution-tree-tag"
                                  data-test="stub-node-@node.ExecutionId">No audited actions</span>
                        }
                        else
                        {
                            <span class="execution-tree-rowcount text-muted small"
                                  data-test="tree-rowcount-@node.ExecutionId">
                                @node.RowCount audit @(node.RowCount == 1 ? "row" : "rows")
                            </span>
                        }
                    </div>

                    @if (isStub)
                    {
                        <div class="execution-tree-meta text-muted small">
                            Execution with no audited actions — referenced as a parent, but it
                            emitted no audit rows of its own (or its rows have been purged).
                        </div>
                    }
                    else
                    {
                        <div class="execution-tree-meta small">
                            <span class="execution-tree-meta-item">
                                <span class="text-muted">Source</span>
                                @(node.SourceSiteId ?? "—")@(node.SourceInstanceId is null ? "" : " / " + node.SourceInstanceId)
                            </span>
                            @if (node.Channels.Count > 0)
                            {
                                <span class="execution-tree-meta-item">
                                    <span class="text-muted">Channels</span>
                                    @string.Join(", ", node.Channels)
                                </span>
                            }
                            @if (node.Statuses.Count > 0)
                            {
                                <span class="execution-tree-meta-item">
                                    <span class="text-muted">Statuses</span>
                                    @string.Join(", ", node.Statuses)
                                </span>
                            }
                            <span class="execution-tree-meta-item">
                                <span class="text-muted">Time span</span>
                                @FormatSpan(node.FirstOccurredAtUtc, node.LastOccurredAtUtc)
                            </span>
                        </div>
                    }
                </div>
            </div>

            @if (subtree.Children.Count > 0 && IsExpanded(node.ExecutionId))
            {
                @* Recurse: each child subtree is already assembled, so the
                   nested instance renders directly from PreBuiltRoots and skips
                   the flat-list assembly entirely. *@
                <ExecutionTree PreBuiltRoots="subtree.Children"
                               ArrivedFromExecutionId="ArrivedFromExecutionId"
                               OnNodeActivated="OnNodeActivated"
                               Depth="Depth + 1" />
            }
        </li>
    }
</ul>
