using Bunit;
using Microsoft.AspNetCore.Components;
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;

namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Shared;

/// <summary>
/// Regression tests for CentralUI-018. <c>TreeView</c>'s storage-restore path
/// called <c>JsonSerializer.Deserialize</c> on the raw <c>treeviewStorage</c>
/// payload outside any try block — a corrupt payload threw an uncaught
/// <c>JsonException</c> during <c>OnAfterRenderAsync</c>, breaking the
/// component. The fix guards the deserialize and ignores a corrupt payload.
/// </summary>
public class TreeViewStorageResilienceTests : BunitContext
{
    private record TestNode(string Key, string Label, List<TestNode> Children);

    private static List<TestNode> Roots() => new()
    {
        new("a", "Alpha", new() { new("a1", "Alpha-1", new()) }),
        new("b", "Beta", new()),
    };

    private IRenderedComponent<TreeView<TestNode>> BuildTree()
        => Render<TreeView<TestNode>>(parameters => parameters
            .Add(p => p.Items, Roots())
            .Add(p => p.ChildrenSelector, n => n.Children)
            .Add(p => p.HasChildrenSelector, n => n.Children.Count > 0)
            .Add(p => p.KeySelector, n => n.Key)
            .Add(p => p.NodeContent, (RenderFragment<TestNode>)(node => b =>
                b.AddMarkupContent(0, $"<span>{node.Label}</span>")))
            .Add(p => p.StorageKey, "corrupt-tree"));

    [Fact]
    public void StorageRestore_CorruptJsonPayload_DoesNotThrow_AndStillRenders()
    {
        // A garbage payload that is not valid JSON for a List<string>.
        JSInterop.Setup<string?>("treeviewStorage.load", _ => true)
            .SetResult("{not json at all]");
        JSInterop.SetupVoid("treeviewStorage.save", _ => true);

        // Pre-fix: OnAfterRenderAsync threw JsonException out of the unguarded
        // Deserialize call. Post-fix: the corrupt payload is ignored.
        var cut = BuildTree();

        Assert.Contains("Alpha", cut.Markup);
        Assert.Contains("Beta", cut.Markup);
    }

    [Fact]
    public void StorageRestore_WrongShapeJson_DoesNotThrow()
    {
        // Valid JSON, but not a List<string> — an object, not an array.
        JSInterop.Setup<string?>("treeviewStorage.load", _ => true)
            .SetResult("{\"unexpected\": true}");
        JSInterop.SetupVoid("treeviewStorage.save", _ => true);

        var cut = BuildTree();

        Assert.Contains("Alpha", cut.Markup);
    }
}
