using System.Text.Json;
using MBN_STOCK_WEBVIEW.LegacyApplication;

namespace MBN_STOCK_WEBVIEW.LegacyBridge.Tests;

public sealed class LegacyRowDoubleClickBridgeTests
{
    [Theory]
    [InlineData(
        "activate-manual-financial-result",
        "resultId",
        "mf-row-0123456789abcdef",
        typeof(LegacyActivateManualFinancialResultIntent))]
    [InlineData(
        "activate-theme-result",
        "resultId",
        "theme-result-001",
        typeof(LegacyActivateThemeResultIntent))]
    [InlineData(
        "load-named-playlist-by-id",
        "definitionId",
        "named-definition-AAAAAAAAAAAB",
        typeof(LegacyLoadNamedPlaylistByIdIntent))]
    [InlineData(
        "save-current-named-playlist-to",
        "definitionId",
        "named-definition-AAAAAAAAAAAB",
        typeof(LegacySaveCurrentNamedPlaylistToIntent))]
    public void Atomic_row_commands_accept_one_opaque_identity_only(
        string command,
        string property,
        string value,
        Type expectedType)
    {
        var json = JsonSerializer.Serialize(new
        {
            type = command,
            payload = new Dictionary<string, string> { [property] = value }
        });

        Assert.True(LegacyBridgeProtocol.TryParseIntent(json, out var parsed, out _));
        Assert.IsType(expectedType, parsed);
        Assert.False(LegacyBridgeProtocol.TryParseIntent(
            $"{{\"type\":\"{command}\",\"payload\":{{\"{property}\":\"{value}\",\"programCode\":\"00000001\"}}}}",
            out _,
            out _));
        Assert.False(LegacyBridgeProtocol.TryParseIntent(
            $"{{\"type\":\"{command}\",\"payload\":{{\"{property}\":\"../unsafe\"}}}}",
            out _,
            out _));
    }

    [Theory]
    [InlineData(true)]
    [InlineData(false)]
    public void Named_playlist_save_carries_only_the_success_dialog_choice(bool showSavedAlert)
    {
        var json = JsonSerializer.Serialize(new
        {
            type = "save-current-named-playlist-to",
            payload = new
            {
                definitionId = "named-definition-AAAAAAAAAAAB",
                showSavedAlert
            }
        });

        Assert.True(LegacyBridgeProtocol.TryParseIntent(json, out var parsed, out _));
        var save = Assert.IsType<LegacySaveCurrentNamedPlaylistToIntent>(parsed);
        Assert.Equal(showSavedAlert, save.ShowSavedAlert);

        Assert.False(LegacyBridgeProtocol.TryParseIntent(
            "{\"type\":\"save-current-named-playlist-to\",\"payload\":{" +
            "\"definitionId\":\"named-definition-AAAAAAAAAAAB\"," +
            "\"showSavedAlert\":\"yes\"}}",
            out _,
            out _));
    }

    [Fact]
    public void Named_playlist_load_rejects_save_dialog_metadata()
    {
        Assert.True(LegacyBridgeProtocol.TryParseIntent(
            "{\"type\":\"load-named-playlist-by-id\",\"payload\":{" +
            "\"definitionId\":\"named-definition-AAAAAAAAAAEF\"}}",
            out var parsed,
            out _));
        Assert.IsType<LegacyLoadNamedPlaylistByIdIntent>(parsed);

        Assert.False(LegacyBridgeProtocol.TryParseIntent(
            "{\"type\":\"load-named-playlist-by-id\",\"payload\":{" +
            "\"definitionId\":\"named-definition-AAAAAAAAAAEF\"," +
            "\"showSavedAlert\":false}}",
            out _,
            out _));
    }

    [Fact]
    public void Projection_exposes_only_closed_command_receipt_and_opaque_target()
    {
        var snapshot = new LegacyOperatorSnapshot(
            1,
            string.Empty,
            [],
            null,
            [],
            [],
            null,
            string.Empty,
            LegacyOperatorStatusKind.Information,
            CommandResult: new LegacyOperatorCommandResult(
                7,
                "load-named-playlist-by-id",
                "named-definition-AAAAAAAAAAAB",
                true));

        using var document = JsonDocument.Parse(
            LegacyBridgeProtocol.SerializeState(snapshot));
        var result = document.RootElement.GetProperty("payload")
            .GetProperty("commandResult");

        Assert.Equal(7, result.GetProperty("sequence").GetInt64());
        Assert.Equal("load-named-playlist-by-id",
            result.GetProperty("command").GetString());
        Assert.Equal("named-definition-AAAAAAAAAAAB",
            result.GetProperty("targetId").GetString());
        Assert.True(result.GetProperty("succeeded").GetBoolean());
        Assert.DoesNotContain("programCode", result.GetRawText(),
            StringComparison.OrdinalIgnoreCase);
    }
}
