@* Create/edit modal for a UNS area, wired straight into IUnsTreeService. The host page owns
   visibility and supplies the parent cluster (create) or the loaded AreaEditDto (edit) plus the
   served-by cluster list. On a successful save it raises OnSaved so the host can reload the tree. *@
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Components.Forms
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns
@inject IUnsTreeService Svc

@if (Visible)
{
    <div class="modal-backdrop fade show" style="display:block"></div>
    <div class="modal fade show" tabindex="-1" role="dialog" style="display:block">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <EditForm Model="_form" OnValidSubmit="SaveAsync" FormName="areaModal">
                    <DataAnnotationsValidator />
                    <div class="modal-header">
                        <h5 class="modal-title">@(IsNew ? "New UNS area" : "Edit UNS area")</h5>
                        <button type="button" class="btn-close" aria-label="Close" @onclick="CancelAsync"></button>
                    </div>
                    <div class="modal-body">
                        <div class="mb-3">
                            <label class="form-label" for="area-id">UnsAreaId</label>
                            <InputText id="area-id" @bind-Value="_form.UnsAreaId" disabled="@(!IsNew)"
                                       class="form-control form-control-sm mono" />
                            <ValidationMessage For="@(() => _form.UnsAreaId)" />
                        </div>
                        <div class="mb-3">
                            <label class="form-label" for="area-name">Name</label>
                            <InputText id="area-name" @bind-Value="_form.Name" class="form-control form-control-sm" />
                            <ValidationMessage For="@(() => _form.Name)" />
                        </div>
                        <div class="mb-3">
                            <label class="form-label" for="area-cluster">Served by cluster</label>
                            <InputSelect id="area-cluster" @bind-Value="_form.ClusterId" class="form-select form-select-sm">
                                @foreach (var (id, display) in Clusters)
                                {
                                    <option value="@id">@display</option>
                                }
                            </InputSelect>
                            <ValidationMessage For="@(() => _form.ClusterId)" />
                        </div>
                        <div class="mb-3">
                            <label class="form-label" for="area-notes">Notes</label>
                            <InputTextArea id="area-notes" @bind-Value="_form.Notes" class="form-control form-control-sm" rows="3" />
                        </div>
                        @if (!string.IsNullOrWhiteSpace(_error))
                        {
                            <div class="text-danger small mt-2">@_error</div>
                        }
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-outline-secondary" @onclick="CancelAsync" disabled="@_busy">Cancel</button>
                        <button type="submit" class="btn btn-primary" disabled="@_busy">
                            @if (_busy) { <span class="spinner-border spinner-border-sm me-1"></span> }
                            @(IsNew ? "Create" : "Save changes")
                        </button>
                    </div>
                </EditForm>
            </div>
        </div>
    </div>
}

@code {
    /// <summary>Whether the modal is shown. The host owns this flag.</summary>
    [Parameter] public bool Visible { get; set; }

    /// <summary><c>true</c> to create a new area; <c>false</c> to edit <see cref="Existing"/>.</summary>
    [Parameter] public bool IsNew { get; set; }

    /// <summary>The parent cluster id used to default the served-by select on create.</summary>
    [Parameter] public string? ClusterId { get; set; }

    /// <summary>The area being edited, when <see cref="IsNew"/> is <c>false</c>.</summary>
    [Parameter] public AreaEditDto? Existing { get; set; }

    /// <summary>The selectable served-by clusters as <c>(Id, Display)</c> pairs.</summary>
    [Parameter] public IReadOnlyList<(string Id, string Display)> Clusters { get; set; } = Array.Empty<(string, string)>();

    /// <summary>Raised after a successful create/save so the host can reload and close.</summary>
    [Parameter] public EventCallback OnSaved { get; set; }

    /// <summary>Raised when the user cancels so the host can close.</summary>
    [Parameter] public EventCallback OnCancel { get; set; }

    private FormModel _form = new();
    private bool _busy;
    private string? _error;

    protected override void OnParametersSet()
    {
        // Rebuild the working form whenever the host (re)opens the modal for a fresh target.
        if (IsNew)
        {
            _form = new FormModel { ClusterId = ClusterId ?? "" };
        }
        else if (Existing is not null)
        {
            _form = new FormModel
            {
                UnsAreaId = Existing.UnsAreaId,
                Name = Existing.Name,
                Notes = Existing.Notes,
                ClusterId = Existing.ClusterId,
            };
        }
        _error = null;
    }

    private async Task SaveAsync()
    {
        _busy = true;
        _error = null;
        try
        {
            var result = IsNew
                ? await Svc.CreateAreaAsync(_form.ClusterId, _form.UnsAreaId, _form.Name, _form.Notes)
                : await Svc.UpdateAreaAsync(_form.UnsAreaId, _form.Name, _form.Notes, _form.ClusterId, Existing!.RowVersion);

            if (result.Ok)
            {
                await OnSaved.InvokeAsync();
            }
            else
            {
                _error = result.Error;
            }
        }
        finally
        {
            _busy = false;
        }
    }

    private Task CancelAsync() => OnCancel.InvokeAsync();

    private sealed class FormModel
    {
        [Required, RegularExpression("^[A-Za-z0-9_-]+$")] public string UnsAreaId { get; set; } = "";
        [Required] public string Name { get; set; } = "";
        [Required] public string ClusterId { get; set; } = "";
        public string? Notes { get; set; }
    }
}
