using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using ZB.MOM.WW.OtOpcUa.AdminUI.Hubs;
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns;
using ZB.MOM.WW.OtOpcUa.Commons.Browsing;
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser;
using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser;

namespace ZB.MOM.WW.OtOpcUa.AdminUI;

public static class EndpointRouteBuilderExtensions
{
    /// <summary>
    /// Mounts the AdminUI Razor components and the AdminUI static asset pipeline at the root.
    /// Call from the fused Host's Program.cs alongside <c>app.MapOtOpcUaAuth()</c>.
    /// </summary>
    /// <typeparam name="TApp">The root component type for Razor pages.</typeparam>
    /// <param name="app">The endpoint route builder.</param>
    public static IEndpointRouteBuilder MapAdminUI<TApp>(this IEndpointRouteBuilder app)
        where TApp : IComponent
    {
        // Razor class library static assets (_content/ZB.MOM.WW.OtOpcUa.AdminUI/**) are
        // served via the Host's app.UseStaticFiles() middleware which must run BEFORE
        // UseAuthentication() — see Program.cs.
        app.MapRazorComponents<TApp>()
            .AddInteractiveServerRenderMode();
        return app;
    }

    /// <summary>
    /// Adds AdminUI services to the dependency injection container.
    /// </summary>
    /// <param name="services">The service collection.</param>
    public static IServiceCollection AddAdminUI(this IServiceCollection services)
    {
        services.AddRazorComponents().AddInteractiveServerComponents();
        services.AddOtOpcUaDriverStatusServices();

        // Browse pipeline — see docs/plans/2026-05-28-driver-browsers-design.md
        services.AddSingleton<Browsing.BrowseSessionRegistry>();
        services.AddHostedService<Browsing.BrowseSessionReaper>();
        services.AddScoped<Browsing.IBrowserSessionService, Browsing.BrowserSessionService>();
        services.AddScoped<IUnsTreeService, UnsTreeService>();
        services.AddSingleton<IDriverBrowser, OpcUaClientDriverBrowser>();
        services.AddSingleton<IDriverBrowser, GalaxyDriverBrowser>();

        // Roslyn-backed Monaco script-editor analysis (diagnostics/completions/hover/...).
        services.AddScoped<ScriptAnalysis.ScriptAnalysisService>();
        services.AddScoped<ScriptAnalysis.IScriptTagCatalog, ScriptAnalysis.ScriptTagCatalog>();

        return services;
    }
}
