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

namespace MBN_STOCK_WEBVIEW.LegacyBridge.Tests;

public sealed class LegacyComparisonBridgeTests
{
    [Theory]
    [InlineData("search-comparison-domestic", "{\"query\":\"삼성\"}", typeof(LegacySearchComparisonDomesticIntent))]
    [InlineData("search-comparison-world", "{\"query\":\"APPLE\"}", typeof(LegacySearchComparisonWorldIntent))]
    [InlineData("select-comparison-domestic", "{\"selectionId\":\"comparison-domestic-0001-0001\"}", typeof(LegacySelectComparisonDomesticIntent))]
    [InlineData("select-comparison-world", "{\"selectionId\":\"comparison-world-0001-0001\"}", typeof(LegacySelectComparisonWorldIntent))]
    [InlineData("select-comparison-fixed", "{\"targetId\":\"kospi\"}", typeof(LegacySelectComparisonFixedIntent))]
    [InlineData("choose-comparison-domestic", "{\"selectionId\":\"comparison-domestic-0001-0001\"}", typeof(LegacyChooseComparisonDomesticIntent))]
    [InlineData("choose-comparison-world", "{\"selectionId\":\"comparison-world-0001-0001\"}", typeof(LegacyChooseComparisonWorldIntent))]
    [InlineData("choose-comparison-fixed", "{\"targetId\":\"kospi\"}", typeof(LegacyChooseComparisonFixedIntent))]
    [InlineData("swap-comparison-targets", "{}", typeof(LegacySwapComparisonTargetsIntent))]
    [InlineData("clear-comparison-targets", "{}", typeof(LegacyClearComparisonTargetsIntent))]
    [InlineData("add-comparison-pair", "{}", typeof(LegacyAddComparisonPairIntent))]
    [InlineData("import-legacy-comparison-pairs", "{}", typeof(LegacyImportComparisonPairsIntent))]
    [InlineData("select-comparison-pair", "{\"rowId\":\"comparison-pair-00000001\"}", typeof(LegacySelectComparisonPairIntent))]
    [InlineData("move-comparison-pair", "{\"direction\":\"up\"}", typeof(LegacyMoveComparisonPairIntent))]
    [InlineData("delete-selected-comparison-pair", "{}", typeof(LegacyDeleteSelectedComparisonPairIntent))]
    [InlineData("delete-all-comparison-pairs", "{}", typeof(LegacyDeleteAllComparisonPairsIntent))]
    [InlineData("activate-comparison-action", "{\"actionId\":\"comparison-candle\"}", typeof(LegacyActivateComparisonActionIntent))]
    public void ComparisonIntentsAreClosed(string type, string payload, Type expected)
    {
        Assert.True(LegacyBridgeProtocol.TryParseIntent(
            $"{{\"type\":\"{type}\",\"payload\":{payload}}}",
            out var intent,
            out _));
        Assert.IsType(expected, intent);
    }

    [Fact]
    public void ComparisonIntentRejectsUnexpectedOrRawIdentityFields()
    {
        Assert.False(LegacyBridgeProtocol.TryParseIntent(
            "{\"type\":\"choose-comparison-domestic\",\"payload\":{\"selectionId\":\"comparison-domestic-0001-0001\",\"stockCode\":\"005930\"}}",
            out _,
            out _));
        Assert.False(LegacyBridgeProtocol.TryParseIntent(
            "{\"type\":\"move-comparison-pair\",\"payload\":{\"direction\":\"sideways\"}}",
            out _,
            out _));
        Assert.False(LegacyBridgeProtocol.TryParseIntent(
            "{\"type\":\"import-legacy-comparison-pairs\",\"payload\":{\"path\":\"C:\\\\untrusted.dat\"}}",
            out _,
            out _));
    }

    [Fact]
    public void State_projects_truncation_and_isolated_row_diagnostics()
    {
        var domestic = new LegacyComparisonSearchSnapshot(
            string.Empty,
            LegacyComparisonSearchStatus.Ready,
            Array.Empty<LegacyComparisonTargetView>(),
            null,
            0,
            string.Empty);
        var world = new LegacyComparisonSearchSnapshot(
            string.Empty,
            LegacyComparisonSearchStatus.Ready,
            [new LegacyComparisonTargetView(
                "comparison-world-0001-0001",
                "ACME, INC",
                "US · ACME",
                LegacyComparisonTargetKind.WorldStock)
            {
                CanSelect = false,
                UnavailableReason = "쉼표 이름은 선택할 수 없습니다."
            }],
            null,
            1_474,
            string.Empty)
        {
            IsTruncated = true,
            IsolatedInvalidRowCount = 16,
            DeferredUnsafeRowCount = 1
        };
        var comparison = new LegacyComparisonWorkflowSnapshot(
            1,
            false,
            domestic,
            world,
            Array.Empty<LegacyComparisonTargetView>(),
            null,
            null,
            null,
            Array.Empty<LegacyComparisonSavedPairView>(),
            null,
            Array.Empty<LegacyComparisonActionView>(),
            string.Empty,
            LegacyOperatorStatusKind.Neutral)
        {
            CanImportLegacyPairs = true,
            LastImport = new LegacyComparisonImportReceipt(
                new string('A', 64),
                8,
                7,
                1,
                8,
                DateTimeOffset.Parse("2026-07-22T12:00:00+09:00"))
        };
        var snapshot = new LegacyOperatorSnapshot(
            1,
            string.Empty,
            Array.Empty<LegacyStockResultRow>(),
            null,
            Array.Empty<LegacyCutViewRow>(),
            Array.Empty<LegacyOperatorPlaylistRow>(),
            null,
            string.Empty,
            LegacyOperatorStatusKind.Neutral,
            Comparison: comparison);

        using var document = JsonDocument.Parse(LegacyBridgeProtocol.SerializeState(snapshot));
        var projected = document.RootElement
            .GetProperty("payload")
            .GetProperty("comparison")
            .GetProperty("worldSearch");

        Assert.True(projected.GetProperty("isTruncated").GetBoolean());
        Assert.Equal(16, projected.GetProperty("isolatedInvalidRowCount").GetInt32());
        Assert.Equal(1, projected.GetProperty("deferredUnsafeRowCount").GetInt32());
        Assert.Equal(1_474, projected.GetProperty("totalRowCount").GetInt32());
        var deferred = projected.GetProperty("results")[0];
        Assert.False(deferred.GetProperty("canSelect").GetBoolean());
        var comparisonWire = document.RootElement
            .GetProperty("payload")
            .GetProperty("comparison");
        Assert.True(comparisonWire.GetProperty("canImportLegacyPairs").GetBoolean());
        Assert.Equal(7, comparisonWire.GetProperty("lastImport")
            .GetProperty("addedPairCount").GetInt32());
        Assert.Contains(
            "쉼표",
            deferred.GetProperty("unavailableReason").GetString(),
            StringComparison.Ordinal);
    }
}
