namespace EEMSServerCore;

public class EEMSBaseServer : IDisposable
{

    public WebApplication? WebApplication { get; private set; }

    public bool Initialize(IEEMSBaseServerProvider provider, out IClientProvider? clientProvider, long messageSize = 26144)//26144:256kb
    {
        clientProvider = null;
        if (WebApplication is not null)
            return false;

        WebApplicationBuilder builder = WebApplication.CreateBuilder();
        builder.Services.AddSignalR(
            options =>
            {
                options.EnableDetailedErrors = true;
                options.MaximumReceiveMessageSize = messageSize;
            });

        clientProvider = new ClientCaller();
        builder.Services.AddHostedService<HostLifeTime>();
        builder.Services.AddSingleton<DeviceManager>();
        builder.Services.AddSingleton<ClientManager>();
        builder.Services.AddSingleton<IUIProvider, UICaller>();
        builder.Services.AddSingleton<IClientProvider>(clientProvider);
        builder.Services.AddSingleton<IEEMSBaseServerProvider>(provider);

        WebApplication = builder.Build();
        WebApplication.MapHub<UIHub>("/UIHub");
        WebApplication.MapHub<ClientsMainHub>("/ClientHub");
        return true;
    }

    public async Task<bool> StartServiceAsync(string ip, ushort port)
    {
        if (WebApplication is null)
            return false;

        if (string.IsNullOrEmpty(ip) || port < 1000)
            return false;

        try
        {
            await WebApplication.RunAsync($"http://{ip}:{port}");
        }
        catch
        {
            return false;
        }

        return true;
    }

    #region Dispose
    private bool disposedValue;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                // TODO: dispose managed state (managed objects)
                this.WebApplication?.DisposeAsync().AsTask().Wait();
                this.WebApplication = null;
            }

            // TODO: free unmanaged resources (unmanaged objects) and override finalizer
            // TODO: set large fields to null
            disposedValue = true;
        }
    }

    // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
    // ~EEMS_Server()
    // {
    //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
    //     Dispose(disposing: false);
    // }

    public void Dispose()
    {
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }
    #endregion
}


public interface IEEMSBaseServerProvider
{
    void Started();
    void OnConnected(string ip, ushort port, ServiceHub serviceHub);
    void OnDisConnected(string ip, ushort port, ServiceHub serviceHub);
}

public enum ServiceHub
{
    Undefined,
    ClinetHub,
    UIHub
}