namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;

public sealed class LegacyComparisonConfirmationNativeContractTests
{
    private static readonly string RepositoryRoot = FindRepositoryRoot();
    private static readonly string Controller = File.ReadAllText(Path.Combine(
        RepositoryRoot,
        "src",
        "MBN_STOCK_WEBVIEW.LegacyApplication",
        "LegacyOperatorController.cs"));
    private static readonly string MainWindow = File.ReadAllText(Path.Combine(
        RepositoryRoot,
        "src",
        "MBN_STOCK_WEBVIEW.LegacyParityApp",
        "MainWindow.xaml.cs"));
    private static readonly string App = File.ReadAllText(Path.Combine(
        RepositoryRoot,
        "src",
        "MBN_STOCK_WEBVIEW.LegacyParityApp",
        "Web",
        "app.js"));
    private static readonly string Markup = File.ReadAllText(Path.Combine(
        RepositoryRoot,
        "src",
        "MBN_STOCK_WEBVIEW.LegacyParityApp",
        "Web",
        "index.html"));

    [Fact]
    public void Uc3DeleteAllUsesTheExactNativeMessageBoxContract()
    {
        var request = Slice(
            Controller,
            "public async Task<LegacyOperatorSnapshot> DeleteComparisonPairAsync(",
            "public LegacyOperatorSnapshot ActivateComparisonAction(");

        Assert.Contains("if (_dialog is not null)", request, StringComparison.Ordinal);
        Assert.Contains("PendingNativeConfirmation.ForComparisonDeleteAll(", request,
            StringComparison.Ordinal);
        Assert.Contains("\"모두 삭제하겠습니까?\"", request, StringComparison.Ordinal);
        Assert.Contains("\"MmoneyCoder\"", request, StringComparison.Ordinal);
        Assert.Contains("IsConfirmation: true", request, StringComparison.Ordinal);
        Assert.DoesNotContain("DeleteAllPairsAsync", request, StringComparison.Ordinal);
    }

    [Fact]
    public void NativeModalAllowsOnlyReadyAndItsEmptyYesOrNoDecision()
    {
        Assert.Contains(
            "_controller.Current.Dialog?.IsConfirmation == true",
            MainWindow,
            StringComparison.Ordinal);
        Assert.Contains(
            "intent is not LegacyReadyIntent and",
            MainWindow,
            StringComparison.Ordinal);
        Assert.Contains(
            "not LegacyConfirmNativeDialogIntent and",
            MainWindow,
            StringComparison.Ordinal);
        Assert.Contains(
            "not LegacyCancelNativeDialogIntent",
            MainWindow,
            StringComparison.Ordinal);
        Assert.Contains("? \"confirm-native-dialog\"", App, StringComparison.Ordinal);
        Assert.Contains("send(\"cancel-native-dialog\", {});", App,
            StringComparison.Ordinal);
        Assert.DoesNotContain(
            "window.confirm(\"저장된 종목 비교쌍을 모두 삭제하겠습니까?\")",
            App,
            StringComparison.Ordinal);
        Assert.Contains(
            "if (modal === legacyAlertDialog) return dialogOk;",
            App,
            StringComparison.Ordinal);
        Assert.Contains(
            "modalFocusManager.getActiveModal() === legacyAlertDialog &&\n          !legacyDialogIsConfirmation",
            App.Replace("\r\n", "\n", StringComparison.Ordinal),
            StringComparison.Ordinal);
        Assert.True(
            Markup.IndexOf("id=\"legacy-dialog-ok\"", StringComparison.Ordinal) <
            Markup.IndexOf("id=\"legacy-dialog-no\"", StringComparison.Ordinal));
        Assert.Contains(
            "dialogOk.textContent = legacyDialogIsConfirmation ? \"예\" : \"확인\"",
            App,
            StringComparison.Ordinal);
        Assert.Contains(">아니요</button>", Markup, StringComparison.Ordinal);
    }

    private static string Slice(string source, string startToken, string endToken)
    {
        var start = source.IndexOf(startToken, StringComparison.Ordinal);
        var end = source.IndexOf(endToken, start + startToken.Length,
            StringComparison.Ordinal);
        Assert.True(start >= 0 && end > start);
        return source[start..end];
    }

    private static string FindRepositoryRoot()
    {
        var directory = new DirectoryInfo(AppContext.BaseDirectory);
        while (directory is not null)
        {
            if (File.Exists(Path.Combine(directory.FullName, "MBN_STOCK_WEBVIEW.sln")))
            {
                return directory.FullName;
            }

            directory = directory.Parent;
        }

        throw new DirectoryNotFoundException("Could not locate the repository root.");
    }
}
