@using ZB.MOM.WW.OtOpcUa.AdminUI.Clients
@using ZB.MOM.WW.OtOpcUa.Commons.Messages.Admin
@inject AdminProbeService Probe
@implements IDisposable

<div class="d-inline-flex align-items-center gap-2">
    <button type="button" class="btn btn-outline-primary btn-sm" disabled="@_busy" @onclick="OnClickAsync">
        @if (_busy) { <span class="spinner-border spinner-border-sm me-1"></span> }
        Test Connect
    </button>

    @if (_result is not null)
    {
        @if (_result.Ok)
        {
            <span class="chip chip-ok" title="@($"Probe succeeded in {_result.LatencyMs:F0} ms")">
                OK &middot; @_result.LatencyMs?.ToString("F0") ms
            </span>
        }
        else
        {
            <span class="chip chip-bad" title="@_result.Message">
                Failed &middot; @TruncatedMessage()
            </span>
        }
    }
</div>

@code {
    /// <summary>Driver type key — must match an installed <c>IDriverProbe.DriverType</c>.</summary>
    [Parameter, EditorRequired] public string DriverType { get; set; } = "";

    /// <summary>Callback that returns the current form config as JSON. Called at click time.</summary>
    [Parameter, EditorRequired] public Func<string> GetConfigJson { get; set; } = () => "{}";

    /// <summary>Per-probe timeout forwarded to the actor (actor clamps to [1, 60] s). Default 10 s.</summary>
    [Parameter] public int TimeoutSeconds { get; set; } = 10;

    private bool _busy;
    private TestDriverConnectResult? _result;
    private System.Timers.Timer? _clearTimer;

    private async Task OnClickAsync()
    {
        _busy = true;
        _result = null;
        StateHasChanged();
        try
        {
            var json = GetConfigJson() ?? "{}";
            _result = await Probe.TestAsync(DriverType, json, TimeoutSeconds);
        }
        catch (Exception ex)
        {
            _result = new TestDriverConnectResult(false, ex.Message, null, Guid.Empty);
        }
        finally
        {
            _busy = false;
            ScheduleClear();
            StateHasChanged();
        }
    }

    private void ScheduleClear()
    {
        _clearTimer?.Dispose();
        _clearTimer = new System.Timers.Timer(30_000) { AutoReset = false };
        _clearTimer.Elapsed += async (_, _) =>
        {
            _result = null;
            await InvokeAsync(StateHasChanged);
        };
        _clearTimer.Start();
    }

    private string TruncatedMessage()
        => _result?.Message is null ? "" :
            (_result.Message.Length > 60 ? _result.Message[..60] + "…" : _result.Message);

    public void Dispose() => _clearTimer?.Dispose();
}
