using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.SignalR.Client;
using RobotNet.MapShares.Dtos;
using RobotNet.RobotShares.Dtos;
using RobotNet.Shares;

namespace RobotNet.WebApp.Clients;

public class RobotHubClient: WebAssemblyHubClient
{
    public event Action<IEnumerable<RobotOnlineStateDto>>? IsOnlineChanged;
    private IDisposable? disIsOnlineChanged;

    public event Action? MapDeactive;
    private IDisposable? disMapDeactive;

    public event Action<IEnumerable<RobotInfomationDto>>? UpdateChanged;
    private IDisposable? disUpdateChanged;

    public event Action<IEnumerable<ElementDto>>? ElementsStateChanged;
    private IDisposable? disElementsStateChanged;

    public event Action<RobotVDA5050StateDto>? VDA5050InfoChanged;
    private IDisposable? disVDA5050InfoChanged;

    public event Action? RobotDetailDeactive;
    private IDisposable? disRobotDetailDeactive;

    public RobotHubClient(IAccessTokenProvider tokenProvider, Uri uri) : base(tokenProvider, uri)
    {
        disIsOnlineChanged = Connection.On<IEnumerable<RobotOnlineStateDto>>("IsOnlineChanged", nodes => IsOnlineChanged?.Invoke(nodes));
        disUpdateChanged = Connection.On<IEnumerable<RobotInfomationDto>>("UpdateChanged", state => UpdateChanged?.Invoke(state));
        disElementsStateChanged = Connection.On<IEnumerable<ElementDto>>("ElementsStateChanged", state => ElementsStateChanged?.Invoke(state));
        disVDA5050InfoChanged = Connection.On<RobotVDA5050StateDto>("VDA5050InfoChanged", vdastate => VDA5050InfoChanged?.Invoke(vdastate));
        disMapDeactive = Connection.On("MapDeactive", () => MapDeactive?.Invoke());
        disRobotDetailDeactive = Connection.On("RobotDetailDeactive", () => RobotDetailDeactive?.Invoke());
    }

    public override async Task StopAsync()
    {
        if (disIsOnlineChanged != null)
        {
            disIsOnlineChanged.Dispose();
            disIsOnlineChanged = null;
        }
        if (disUpdateChanged != null)
        {
            disUpdateChanged.Dispose();
            disUpdateChanged = null;
        }
        if (disElementsStateChanged != null)
        {
            disElementsStateChanged.Dispose();
            disElementsStateChanged = null;
        }
        if (disVDA5050InfoChanged != null)
        {
            disVDA5050InfoChanged.Dispose();
            disVDA5050InfoChanged = null;
        }
        if (disMapDeactive != null)
        {
            disMapDeactive.Dispose();
            disMapDeactive = null;
        }
        if (disRobotDetailDeactive != null)
        {
            disRobotDetailDeactive.Dispose();
            disRobotDetailDeactive = null;
        }
        await base.StopAsync();
    }

    public Task MapActive(Guid mapId) => IsConnected ? Connection.InvokeAsync("MapActive", mapId) : Task.CompletedTask;

    public Task RobotDetailActive(string robotId) => IsConnected ? Connection.InvokeAsync("RobotDetailActive", robotId) : Task.CompletedTask;

    public async Task<MessageResult> SetInitialPose(string robotId, double x, double y, double yaw)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(SetInitialPose), robotId, x, y, yaw) : new(false, "Kết nối thất bại");

    public async Task<MessageResult> MoveStraight(string robotId, double x, double y, double theta)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(MoveStraight), robotId, x, y, theta) : new(false, "Kết nối thất bại");

    public async Task<MessageResult> MoveToNode(string robotId, string nodename)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(MoveToNode), robotId, nodename) : new(false, "Kết nối thất bại");

    public async Task<MessageResult> MoveRandom(string robotId, List<string> nodes)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(MoveRandom), robotId, nodes) : new(false, "Kết nối thất bại");

    public async Task<MessageResult> CancelNavigation(string robotId)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(CancelNavigation), robotId) : new(false, "Kết nối thất bại");

    public async Task<MessageResult> SetMap(string robotId, Guid mapId)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(SetMap), robotId, mapId) : new(false, "Kết nối thất bại");

    public async Task<MessageResult> CancelAction(string robotId)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(CancelAction), robotId) : new(false, "Kết nối thất bại");

    public async Task<MessageResult> SendAction(string robotId, ActionDto action)
        => IsConnected ? await Connection.InvokeAsync<MessageResult>(nameof(SendAction), robotId, action) : new(false, "Kết nối thất bại");

}
