using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Driver.Sql;

namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;

/// <summary>
/// Maps a driver's <c>DriverType</c> string to its typed tag-config editor component. Drivers absent
/// from the map fall back to the generic raw-JSON textarea in the TagModal. Keys are the canonical
/// <see cref="DriverTypeNames"/> constants
/// (case-insensitive) so this map can never drift from the authoritative factory names.
/// </summary>
public static class TagConfigEditorMap
{
    private static readonly IReadOnlyDictionary<string, Type> Map =
        new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
        {
            [DriverTypeNames.Modbus]      = typeof(Components.Shared.Uns.TagEditors.ModbusTagConfigEditor),
            [DriverTypeNames.S7]          = typeof(Components.Shared.Uns.TagEditors.S7TagConfigEditor),
            [DriverTypeNames.AbCip]       = typeof(Components.Shared.Uns.TagEditors.AbCipTagConfigEditor),
            [DriverTypeNames.AbLegacy]    = typeof(Components.Shared.Uns.TagEditors.AbLegacyTagConfigEditor),
            [DriverTypeNames.TwinCAT]     = typeof(Components.Shared.Uns.TagEditors.TwinCATTagConfigEditor),
            [DriverTypeNames.FOCAS]       = typeof(Components.Shared.Uns.TagEditors.FocasTagConfigEditor),
            [DriverTypeNames.OpcUaClient] = typeof(Components.Shared.Uns.TagEditors.OpcUaClientTagConfigEditor),
            [DriverTypeNames.Calculation] = typeof(Components.Shared.Uns.TagEditors.CalculationTagConfigEditor),
            // Keyed off SqlDriver.DriverTypeName, which is value-identical to DriverTypeNames.Sql. The
            // note that used to sit here — "that shared constant is deliberately absent until Task 11 wires
            // the factory" — went stale when the constant landed; the key is correct either way.
            [SqlDriver.DriverTypeName]     = typeof(Components.Shared.Uns.TagEditors.SqlTagConfigEditor),
            [DriverTypeNames.Mqtt]        = typeof(Components.Shared.Uns.TagEditors.MqttTagConfigEditor),
            [DriverTypeNames.MTConnect]   = typeof(Components.Shared.Uns.TagEditors.MTConnectTagConfigEditor),
        };

    /// <summary>Returns the editor component type for a driver type, or null if none is registered.</summary>
    /// <param name="driverType">The driver type name to look up an editor component for.</param>
    /// <returns>The editor component <see cref="Type"/>, or null if no typed editor is registered.</returns>
    public static Type? Resolve(string? driverType)
        => driverType is not null && Map.TryGetValue(driverType, out var t) ? t : null;
}
