using Microsoft.AspNetCore.Http.Features;

namespace EEMSServerCore.Hubs;

internal partial class ClientsMainHub(DeviceManager deviceManager, IEEMSBaseServerProvider provider, IUIProvider uiCaller) : Hub, IClientCaller
{
    public override Task OnConnectedAsync()
    {
        if (Context.Features.Get<IHttpConnectionFeature>() is IHttpConnectionFeature feature)
            provider?.OnConnected(feature.RemoteIpAddress!.ToString(), (ushort)feature.RemotePort, ServiceHub.ClientHub);

        if (deviceManager.TryGetDevice(Context.ConnectionId, out DeviceInfo? device) && device is not null && device.Guid is not null)
        {
            device.IsConnected = true;
            uiCaller.UpdateDevice(device);
        }

        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception? exception)
    {
        deviceManager.TryGetDevice(Context.ConnectionId, out DeviceInfo? device);

        if (device is not null && device.Guid.HasValue)
        {
            ClientManager.DeviceClients.TryRemove(device.Guid.Value, out _);
            device.IsConnected = false;
            uiCaller.UpdateDevice(device);
            //uiCaller.OnlineStatusNotify(device.Guid.Value, false);
        }

        if (Context.Features.Get<IHttpConnectionFeature>() is IHttpConnectionFeature feature)
            provider?.OnDisConnected(feature.RemoteIpAddress!.ToString(), (ushort)feature.RemotePort, ServiceHub.ClientHub);

        return base.OnDisconnectedAsync(exception);
    }

    public Task<Guid> RegisterDevice(DeviceInfo deviceInfo)
    {
        deviceInfo.IP ??= string.Empty;
        deviceInfo.Guid ??= Guid.NewGuid();

        if (!deviceManager.LoginDevice(Context.ConnectionId, deviceInfo, Clients.Caller, out bool newDevice))
            return Task.FromResult(Guid.Empty);

        deviceInfo.IsConnected = true;
        if (newDevice)
            uiCaller.InsertNewDevice(deviceInfo);
        else
            uiCaller.UpdateDevice(deviceInfo);

        return Task.FromResult(deviceInfo.Guid.Value);
    }

    public Task<bool> UpdateRealTimeData(Dictionary<string, object> realtimeData)
    {
        if (!deviceManager.TryGetDevice(Context.ConnectionId, out DeviceInfo? device) || device is null || device.Guid is null)
            return Task.FromResult(false);

        return uiCaller.UpdateRealtimeData(device.Guid.Value, realtimeData);
    }

    public Task<bool> UpdateAlarm(IEnumerable<Alarm> alarms)
    {
        if (!deviceManager.TryGetDevice(Context.ConnectionId, out DeviceInfo? device) || device is null || device.Guid is null)
            return Task.FromResult(false);

        return uiCaller.UpdateAlarm(alarms);
    }

    public Task<bool> UpdateRecipeInfo(Recipe recipeInfo)
    {
        if (!deviceManager.TryGetDevice(Context.ConnectionId, out DeviceInfo? device) || device is null || device.Guid is null)
            return Task.FromResult(false);
        return uiCaller.UpdateRecipeInfo(recipeInfo);
    }
}
