@namespace ScadaLink.CentralUI.Components.Forms
@using ScadaLink.Commons.Types.DataConnections
@using ScadaLink.Commons.Types.Flattening

<div class="opcua-endpoint-editor">
    <h6 class="text-muted border-bottom pb-1">@Title</h6>

    @if (IsLegacy)
    {
        <div class="alert alert-warning py-1 small mb-2">
            This connection was migrated from a legacy format.
            Review the settings and Save to update.
        </div>
    }

    <div class="row g-2 mb-2">
        <div class="col-md-7">
            <label class="form-label small">Endpoint URL</label>
            <input type="text" class="form-control form-control-sm"
                   @bind="Config.EndpointUrl"
                   placeholder="opc.tcp://host:4840" />
            @RenderFieldError("EndpointUrl")
        </div>
        <div class="col-md-3">
            <label class="form-label small">Security Mode</label>
            <select class="form-select form-select-sm" @bind="Config.SecurityMode">
                <option value="@OpcUaSecurityMode.None">None</option>
                <option value="@OpcUaSecurityMode.Sign">Sign</option>
                <option value="@OpcUaSecurityMode.SignAndEncrypt">Sign &amp; Encrypt</option>
            </select>
        </div>
        <div class="col-md-2 d-flex align-items-end">
            <div class="form-check">
                <input class="form-check-input" type="checkbox"
                       id="@($"{IdPrefix}-autoaccept")"
                       @bind="Config.AutoAcceptUntrustedCerts" />
                <label class="form-check-label small"
                       for="@($"{IdPrefix}-autoaccept")">Auto-accept certs</label>
            </div>
        </div>
    </div>

    <div class="text-muted small mt-2 mb-1">Authentication</div>
    @if (Config.UserIdentity is null)
    {
        <button type="button" class="btn btn-outline-secondary btn-sm mb-2"
                @onclick="EnableAuthentication">Enable Authentication</button>
    }
    else
    {
        <div class="row g-2 mb-2">
            <div class="col-md-3">
                <label class="form-label small">Token type</label>
                <select class="form-select form-select-sm" @bind="Config.UserIdentity.TokenType">
                    <option value="@OpcUaUserTokenType.Anonymous">Anonymous</option>
                    <option value="@OpcUaUserTokenType.UsernamePassword">Username / Password</option>
                    <option value="@OpcUaUserTokenType.X509Certificate">X.509 Certificate</option>
                </select>
            </div>
            @if (Config.UserIdentity.TokenType == OpcUaUserTokenType.UsernamePassword)
            {
                <div class="col-md-3">
                    <label class="form-label small">Username</label>
                    <input type="text" class="form-control form-control-sm"
                           @bind="Config.UserIdentity.Username" />
                    @RenderFieldError("UserIdentity.Username")
                </div>
                <div class="col-md-3">
                    <label class="form-label small">Password</label>
                    <input type="password" class="form-control form-control-sm"
                           @bind="Config.UserIdentity.Password" />
                </div>
            }
            else if (Config.UserIdentity.TokenType == OpcUaUserTokenType.X509Certificate)
            {
                <div class="col-md-4">
                    <label class="form-label small">Certificate path</label>
                    <input type="text" class="form-control form-control-sm"
                           @bind="Config.UserIdentity.CertificatePath"
                           placeholder="/etc/scadalink/pki/client.pfx" />
                    @RenderFieldError("UserIdentity.CertificatePath")
                </div>
                <div class="col-md-3">
                    <label class="form-label small">Certificate password</label>
                    <input type="password" class="form-control form-control-sm"
                           @bind="Config.UserIdentity.CertificatePassword" />
                </div>
            }
            <div class="col-md-3 d-flex align-items-end">
                <button type="button" class="btn btn-outline-danger btn-sm"
                        @onclick="() => Config.UserIdentity = null">
                    Remove Authentication
                </button>
            </div>
        </div>
    }

    <div class="text-muted small mt-2 mb-1">Timing</div>
    <div class="row g-2 mb-2">
        <div class="col-md-3">
            <label class="form-label small">Session timeout (ms)</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.SessionTimeoutMs" min="1" />
            @RenderFieldError("SessionTimeoutMs")
        </div>
        <div class="col-md-3">
            <label class="form-label small">Operation timeout (ms)</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.OperationTimeoutMs" min="1" />
            @RenderFieldError("OperationTimeoutMs")
        </div>
    </div>

    <div class="text-muted small mt-2 mb-1">Subscription</div>
    <div class="row g-2 mb-2">
        <div class="col-md-3">
            <label class="form-label small">Publishing interval (ms)</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.PublishingIntervalMs" min="1" />
            @RenderFieldError("PublishingIntervalMs")
        </div>
        <div class="col-md-3">
            <label class="form-label small">Sampling interval (ms)</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.SamplingIntervalMs" min="1" />
            @RenderFieldError("SamplingIntervalMs")
        </div>
        <div class="col-md-2">
            <label class="form-label small">Queue size</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.QueueSize" min="1" />
            @RenderFieldError("QueueSize")
        </div>
        <div class="col-md-2">
            <label class="form-label small">Keep-alive count</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.KeepAliveCount" min="1" />
            @RenderFieldError("KeepAliveCount")
        </div>
        <div class="col-md-2">
            <label class="form-label small">Lifetime count</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.LifetimeCount" min="1" />
            @RenderFieldError("LifetimeCount")
        </div>
        <div class="col-md-3">
            <label class="form-label small">Max notifications / publish</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.MaxNotificationsPerPublish" min="1" />
            @RenderFieldError("MaxNotificationsPerPublish")
        </div>
    </div>

    <div class="text-muted small mt-2 mb-1">Advanced subscription</div>
    <div class="row g-2 mb-2">
        <div class="col-md-3">
            <label class="form-label small">Subscription display name</label>
            <input type="text" class="form-control form-control-sm"
                   @bind="Config.SubscriptionDisplayName" />
            @RenderFieldError("SubscriptionDisplayName")
        </div>
        <div class="col-md-2">
            <label class="form-label small">Subscription priority</label>
            <input type="number" class="form-control form-control-sm"
                   @bind="Config.SubscriptionPriority" min="0" max="255" />
        </div>
        <div class="col-md-3">
            <label class="form-label small">Timestamps to return</label>
            <select class="form-select form-select-sm" @bind="Config.TimestampsToReturn">
                <option value="@OpcUaTimestampsToReturn.Source">Source</option>
                <option value="@OpcUaTimestampsToReturn.Server">Server</option>
                <option value="@OpcUaTimestampsToReturn.Both">Both</option>
            </select>
        </div>
        <div class="col-md-2 d-flex align-items-end">
            <div class="form-check">
                <input class="form-check-input" type="checkbox"
                       id="@($"{IdPrefix}-discardoldest")"
                       @bind="Config.DiscardOldest" />
                <label class="form-check-label small"
                       for="@($"{IdPrefix}-discardoldest")">Discard oldest</label>
            </div>
        </div>
    </div>

    <div class="text-muted small mt-2 mb-1">Deadband filter</div>
    @if (Config.Deadband is null)
    {
        <button type="button" class="btn btn-outline-secondary btn-sm mb-2"
                @onclick="EnableDeadband">Enable Deadband</button>
    }
    else
    {
        <div class="row g-2 mb-2">
            <div class="col-md-3">
                <label class="form-label small">Type</label>
                <select class="form-select form-select-sm" @bind="Config.Deadband.Type">
                    <option value="@OpcUaDeadbandType.Absolute">Absolute</option>
                    <option value="@OpcUaDeadbandType.Percent">Percent</option>
                </select>
            </div>
            <div class="col-md-3">
                <label class="form-label small">Value</label>
                <input type="number" step="0.01" class="form-control form-control-sm"
                       @bind="Config.Deadband.Value" min="0" />
                @RenderFieldError("Deadband.Value")
            </div>
            <div class="col-md-3 d-flex align-items-end">
                <button type="button" class="btn btn-outline-danger btn-sm"
                        @onclick="() => Config.Deadband = null">
                    Remove Deadband
                </button>
            </div>
        </div>
    }

    <div class="text-muted small mt-2 mb-1">Heartbeat</div>
    @if (Config.Heartbeat is null)
    {
        <button type="button" class="btn btn-outline-secondary btn-sm mb-2"
                @onclick="EnableHeartbeat">Enable Heartbeat</button>
    }
    else
    {
        <div class="row g-2 mb-2">
            <div class="col-md-6">
                <label class="form-label small">Tag path</label>
                <input type="text" class="form-control form-control-sm"
                       @bind="Config.Heartbeat.TagPath"
                       placeholder="Sensors.Heartbeat" />
                @RenderFieldError("Heartbeat.TagPath")
            </div>
            <div class="col-md-3">
                <label class="form-label small">Max silence (s)</label>
                <input type="number" class="form-control form-control-sm"
                       @bind="Config.Heartbeat.MaxSilenceSeconds" min="1" />
                @RenderFieldError("Heartbeat.MaxSilenceSeconds")
            </div>
            <div class="col-md-3 d-flex align-items-end">
                <button type="button" class="btn btn-outline-danger btn-sm"
                        @onclick="() => Config.Heartbeat = null">
                    Remove Heartbeat
                </button>
            </div>
        </div>
    }
</div>

@code {
    [Parameter, EditorRequired] public OpcUaEndpointConfig Config { get; set; } = default!;
    [Parameter] public string Title { get; set; } = "Endpoint";
    [Parameter] public string IdPrefix { get; set; } = "endpoint";
    [Parameter] public bool IsLegacy { get; set; }
    [Parameter] public ValidationResult? Errors { get; set; }

    private void EnableHeartbeat() =>
        Config.Heartbeat = new OpcUaHeartbeatConfig();

    private void EnableAuthentication() =>
        Config.UserIdentity = new OpcUaUserIdentityConfig();

    private void EnableDeadband() =>
        Config.Deadband = new OpcUaDeadbandConfig();

    private RenderFragment? RenderFieldError(string field)
    {
        var match = Errors?.Errors.FirstOrDefault(e =>
            e.EntityName != null
            && (e.EntityName == field || e.EntityName.EndsWith("." + field)));
        return match is null
            ? null
            : @<div class="text-danger small">@match.Message</div>;
    }
}
