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

/// <summary>
/// Task 24: the template editor exposes a Native Alarm Sources subsection (a new
/// tab) for authoring read-only native alarm bindings. <c>TemplateEdit</c> is a
/// heavyweight page (~10 injected services with their own graphs); like the other
/// TemplateEdit coverage in this suite (see <c>TestRunWarningTests</c>), these are
/// structural assertions over the component source that pin the subsection's
/// wiring — the tab, the authoring form (connection dropdown, source reference,
/// filter, lock), and the repository-direct CRUD calls — so it cannot silently
/// regress. The CRUD behaviour itself is covered end-to-end by the ManagementActor
/// native-alarm-source handler tests.
/// </summary>
public class TemplateNativeAlarmSourceEditorTests
{
    private static string DesignComponentsRoot
    {
        get
        {
            var dir = AppContext.BaseDirectory;
            for (var i = 0; i < 6 && dir is not null; i++)
                dir = Directory.GetParent(dir)?.FullName;
            return Path.Combine(dir!, "src", "ZB.MOM.WW.ScadaBridge.CentralUI",
                "Components", "Pages", "Design");
        }
    }

    private static string TemplateEditMarkup
        => File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateEdit.razor"));

    // M10 residual: the authoring form moved out of the page into the dialog body
    // component hosted by IDialogService.ShowAsync. The field-level assertions
    // below follow it there; the tab, the connection filtering, and the CRUD
    // wiring all still live on the page.
    private static string NativeSourceDialogMarkup
        => File.ReadAllText(Path.Combine(DesignComponentsRoot, "TemplateNativeAlarmSourceDialog.razor"));

    [Fact]
    public void TemplateEditor_HasNativeAlarmsTab()
    {
        var markup = TemplateEditMarkup;
        Assert.Contains("_activeTab = \"native-alarms\"", markup);
        Assert.Contains("Native Alarms", markup);
        Assert.Contains("RenderNativeAlarmsTab", markup);
        Assert.Contains("Native Alarm Sources", markup);
    }

    [Fact]
    public void NativeAlarmsForm_HasConnectionSourceFilterAndLockFields()
    {
        var pageMarkup = TemplateEditMarkup;
        // Connection dropdown filtered to alarm-capable protocols via the
        // single-source-of-truth Commons helper. The OpcUa/MxGateway literal set
        // now lives in AlarmCapableProtocols (Commons) — pinned by
        // AlarmCapableProtocolsTests — so this page only needs to delegate to it.
        Assert.Contains("_alarmCapableConnections", pageMarkup);
        Assert.Contains("AlarmCapableProtocols.IsAlarmCapable", pageMarkup);
        // …and hands the filtered list to the dialog body.
        Assert.Contains("AlarmCapableConnections=", pageMarkup);

        // The authoring form fields now live in the dialog body component.
        var dialogMarkup = NativeSourceDialogMarkup;
        Assert.Contains("@bind=\"_nasName\"", dialogMarkup);
        Assert.Contains("@bind=\"_nasConnection\"", dialogMarkup);
        Assert.Contains("@bind=\"_nasSourceRef\"", dialogMarkup);
        Assert.Contains("@bind=\"_nasFilter\"", dialogMarkup);
        Assert.Contains("@bind=\"_nasIsLocked\"", dialogMarkup);
    }

    [Fact]
    public void NativeAlarmsForm_IsHostedByTheDialogService()
    {
        // M10 residual: the page-embedded modal is gone — the form opens through
        // IDialogService.ShowAsync so the host owns the backdrop, focus trap,
        // Escape, and focus restoration.
        var pageMarkup = TemplateEditMarkup;
        Assert.Contains("<TemplateNativeAlarmSourceDialog", pageMarkup);
        Assert.DoesNotContain("_showNativeSourceForm", pageMarkup);

        // The body renders no chrome of its own (no backdrop / modal shell).
        var dialogMarkup = NativeSourceDialogMarkup;
        Assert.DoesNotContain("sb-modal-backdrop", dialogMarkup);
        Assert.Contains("DialogContext<bool> Context", dialogMarkup);
    }

    [Fact]
    public void NativeAlarmsCrud_WiresRepositoryAddUpdateDeleteWithSave()
    {
        var markup = TemplateEditMarkup;
        Assert.Contains("AddTemplateNativeAlarmSourceAsync", markup);
        Assert.Contains("UpdateTemplateNativeAlarmSourceAsync", markup);
        Assert.Contains("DeleteTemplateNativeAlarmSourceAsync", markup);
        Assert.Contains("GetNativeAlarmSourcesByTemplateIdAsync", markup);
        Assert.Contains("SaveChangesAsync", markup);
        // Add/edit/delete handlers are wired to the UI.
        Assert.Contains("OpenAddNativeSourceDialog", markup);
        Assert.Contains("OpenEditNativeSourceDialog", markup);
        Assert.Contains("SaveNativeSourceDraftAsync", markup);
        Assert.Contains("DeleteNativeSource", markup);
    }
}
