@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
@using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy
@using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers
@using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers.Pickers

<div class="row g-2">
    <div class="col-md-4"><label class="form-label">Device host</label>
        <input class="form-control form-control-sm mono" value="@_m.DeviceHostAddress" placeholder="ab://host" @onchange="@(e => Update(() => _m.DeviceHostAddress = e.Value?.ToString() ?? string.Empty))" /></div>
    <div class="col-md-5">
        <label class="form-label">Address</label>
        <div class="input-group input-group-sm">
            <input class="form-control form-control-sm mono" value="@_m.Address" placeholder="e.g. N7:0, B3:0/0" @onchange="@(e => Update(() => _m.Address = e.Value?.ToString() ?? string.Empty))" />
            <button type="button" class="btn btn-outline-secondary" @onclick="@(() => _showPicker = true)">Build</button>
        </div>
    </div>
    <div class="col-md-3"><label class="form-label">Data type</label>
        <select class="form-select form-select-sm" value="@_m.DataType" @onchange="@(e => Update(() => _m.DataType = ParseEnum(e.Value, AbLegacyDataType.Int)))">
            @foreach (var v in Enum.GetValues<AbLegacyDataType>()) { <option value="@v">@v</option> }
        </select></div>
    <div class="col-12">
        <div class="form-check">
            <input type="checkbox" class="form-check-input" id="ablegacy-writable"
                   checked="@(_m.Writable ?? true)"
                   @onchange="@(e => Update(() => _m.Writable = e.Value is bool b && b))" />
            <label class="form-check-label small" for="ablegacy-writable">Writable (uncheck for a read-only tag)</label>
        </div>
    </div>
</div>

@if (_showPicker)
{
    <DriverTagPicker @bind-Visible="_showPicker"
                     Title="AB Legacy address builder"
                     CurrentAddress="@_pickerAddress"
                     OnPickAddress="@OnAddressPicked">
        <AbLegacyAddressPickerBody CurrentAddress="@_pickerAddress"
                                   CurrentAddressChanged="@((s) => _pickerAddress = s)" />
    </DriverTagPicker>
}

@code {
    [Parameter] public string? ConfigJson { get; set; }
    [Parameter] public EventCallback<string> ConfigJsonChanged { get; set; }
    /// <summary>DriverType of the selected driver — lets browse-capable pickers open a universal session.</summary>
    [Parameter] public string DriverType { get; set; } = "";
    /// <summary>Live accessor for the selected driver's DriverConfig JSON (browse connect config).</summary>
    [Parameter] public Func<string> GetDriverConfigJson { get; set; } = () => "{}";

    private AbLegacyTagConfigModel _m = new();
    private string? _lastConfigJson;
    private bool _showPicker;
    private string _pickerAddress = "";

    // Re-parse only when the incoming JSON actually changes, so an unrelated parent re-render
    // (Blazor Server live-status pushes do this) can't reset the user's in-progress edits.
    protected override void OnParametersSet()
    {
        if (ConfigJson == _lastConfigJson) { return; }
        _lastConfigJson = ConfigJson;
        _m = AbLegacyTagConfigModel.FromJson(ConfigJson);
    }

    // TryParse so a bad/empty change value can never throw into the Blazor circuit — it falls back.
    private static TEnum ParseEnum<TEnum>(object? v, TEnum fallback) where TEnum : struct, Enum
        => Enum.TryParse<TEnum>(v?.ToString(), out var r) ? r : fallback;

    private async Task Update(Action apply)
    {
        apply();
        await ConfigJsonChanged.InvokeAsync(_m.ToJson());
    }

    private async Task OnAddressPicked(string address)
    {
        if (!string.IsNullOrWhiteSpace(address))
            await Update(() => _m.Address = address);
    }
}
