@* Dispatch page: reads DriverInstance.DriverType and dispatches to the matching typed editor
   via <DynamicComponent> using _componentMap. Shows an error panel when the driver type has
   no registered typed page. *@
@page "/clusters/{ClusterId}/drivers/{DriverInstanceId}"
@attribute [Microsoft.AspNetCore.Authorization.Authorize]
@rendermode RenderMode.InteractiveServer
@using Microsoft.EntityFrameworkCore
@using ZB.MOM.WW.OtOpcUa.Configuration
@using ZB.MOM.WW.OtOpcUa.Configuration.Entities
@inject IDbContextFactory<OtOpcUaConfigDbContext> DbFactory

@if (!_loaded)
{
    <p>Loading…</p>
}
else if (_existing is null)
{
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h4 class="mb-0">Edit driver instance &middot; <span class="mono">@ClusterId</span></h4>
        <a href="/clusters/@ClusterId/drivers" class="btn btn-outline-secondary btn-sm">Cancel</a>
    </div>
    <ClusterNav ClusterId="@ClusterId" ActiveTab="drivers" />
    <section class="panel notice rise" style="animation-delay:.02s">
        Driver instance <span class="mono">@DriverInstanceId</span> was not found in cluster <span class="mono">@ClusterId</span>.
    </section>
}
else if (ResolveComponentType() is { } pageType)
{
    <DynamicComponent Type="pageType" Parameters="BuildParameters()" />
}
else
{
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h4 class="mb-0">Edit driver instance &middot; <span class="mono">@ClusterId</span></h4>
        <a href="/clusters/@ClusterId/drivers" class="btn btn-outline-secondary btn-sm">Cancel</a>
    </div>
    <ClusterNav ClusterId="@ClusterId" ActiveTab="drivers" />
    <section class="panel notice rise" style="animation-delay:.02s; border-color:var(--alert)">
        Driver instance <span class="mono">@DriverInstanceId</span> has an unknown <code>DriverType</code> value of
        <strong><span class="mono">@_existing.DriverType</span></strong>. No editor is registered for this type.
        Likely causes: the row was written by a newer build, or the type-string was corrupted in the database.
    </section>
}

@code {
    [Parameter] public string ClusterId { get; set; } = "";
    [Parameter] public string DriverInstanceId { get; set; } = "";

    private DriverInstance? _existing;
    private bool _loaded;

    private static readonly IReadOnlyDictionary<string, Type> _componentMap =
        new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
        {
            ["ModbusTcp"]            = typeof(ModbusDriverPage),
            ["AbCip"]                = typeof(AbCipDriverPage),
            ["AbLegacy"]             = typeof(AbLegacyDriverPage),
            ["S7"]                   = typeof(S7DriverPage),
            ["TwinCat"]              = typeof(TwinCATDriverPage),
            ["Focas"]                = typeof(FocasDriverPage),
            ["OpcUaClient"]          = typeof(OpcUaClientDriverPage),
            ["GalaxyMxGateway"]      = typeof(GalaxyDriverPage),
            ["Historian.Wonderware"] = typeof(HistorianWonderwareDriverPage),
        };

    protected override async Task OnInitializedAsync()
    {
        await using var db = await DbFactory.CreateDbContextAsync();
        _existing = await db.DriverInstances.AsNoTracking()
            .FirstOrDefaultAsync(d => d.ClusterId == ClusterId && d.DriverInstanceId == DriverInstanceId);
        _loaded = true;
    }

    private Type? ResolveComponentType()
        => _componentMap.TryGetValue(_existing!.DriverType, out var t) ? t : null;

    private IDictionary<string, object> BuildParameters()
        => new Dictionary<string, object>
        {
            ["ClusterId"] = ClusterId,
            ["DriverInstanceId"] = DriverInstanceId,
        };
}
