using Azure.Core.Serialization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using RobotNet.MapShares.Dtos;
using RobotNet.RobotManager.Data;
using RobotNet.RobotManager.Services;
using RobotNet.RobotShares.VDA5050.InstantAction;
using RobotNet.Shares;
using System.Text.Json;

namespace RobotNet.RobotManager.Hubs;

[Authorize]
public class RobotHub(RobotPublisher RobotPublisher, Services.RobotManager RobotManager, RobotEditorDbContext RobotDb, LoggerController<RobotHub> Logger) : Hub
{
    public async Task MapActive(Guid mapId)
    {
        var keysToRemove = RobotPublisher.MapActive.Where(kvp => kvp.Value == Context.ConnectionId)
                            .Select(kvp => kvp.Key)
                            .ToList();
        foreach (var key in keysToRemove)
        {
            RobotPublisher.MapActive.Remove(key);
        }

        RobotPublisher.MapActive[mapId] = Context.ConnectionId;
        await Clients.AllExcept([.. RobotPublisher.MapActive.Values]).SendAsync("MapDeactive");
    }

    public async Task RobotDetailActive(string robotId)
    {
        var keysToRemove = RobotPublisher.RobotDetailActive.Where(kvp => kvp.Value == Context.ConnectionId)
                            .Select(kvp => kvp.Key)
                            .ToList();

        foreach (var key in keysToRemove)
        {
            RobotPublisher.RobotDetailActive.Remove(key);
        }

        RobotPublisher.RobotDetailActive[robotId] = Context.ConnectionId;
        await Clients.AllExcept([.. RobotPublisher.RobotDetailActive.Values]).SendAsync("RobotDetailDeactive");
    }

    public MessageResult SetInitialPose(string robotId, double x, double y, double yaw)
    {
        try
        {
            var robot = RobotManager[robotId];
            if (robot is not null)
            {
                robot.Initialize(x, y, yaw * 180 / Math.PI);
                return new(true);
            }
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"SetInitialPose: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }
    public MessageResult MoveStraight(string robotId, double x, double y, double theta)
    {
        try
        {
            var robot = RobotManager[robotId];
            if (robot is not null) return robot.MoveStraight(x, y);
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"MoveStraight: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }

    public async Task<MessageResult> MoveToNode(string robotId, string nodename)
    {
        try
        {
            var robot = RobotManager[robotId];
            if (robot is not null) return await robot.MoveToNode(nodename);
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"MoveToNode: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }

    public async Task<MessageResult> MoveRandom(string robotId, List<string> nodes)
    {
        try
        {
            var robot = RobotManager[robotId];
            if (robot is not null) return await robot.MoveRandom(nodes);
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"MoveToNode: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }

    public async Task<MessageResult> CancelNavigation(string robotId)
    {
        try
        {
            var robot = RobotManager[robotId];
            if (robot is not null) return await robot.CancelOrder();
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"CancelNavigation: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }

    public async Task<MessageResult> SetMap(string robotId, Guid mapId)
    {
        try
        {
            var robot = RobotDb.Robots.FirstOrDefault(x => x.RobotId == robotId);
            if (robot is not null)
            {
                robot.MapId = mapId;
                await RobotDb.SaveChangesAsync();
                return new(true);
            }
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"SetMap: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }

    public async Task<MessageResult> SendAction(string robotId, ActionDto action)
    {
        try
        {
            var robot = RobotManager[robotId];
            var actionVDA = JsonSerializer.Deserialize<RobotShares.VDA5050.InstantAction.Action>(action.Content, JsonOptionExtends.Read);
            if (robot is not null)
            {
                if (actionVDA is null) return new(false, "Action không hợp lệ"); 
                var send = await robot.InstantAction(actionVDA, false);
                return new(send.IsSuccess, send.Message);
            }
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"MoveToNode: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }

    public async Task<MessageResult> CancelAction(string robotId)
    {
        try
        {
            var robot = RobotManager[robotId];
            if (robot is not null) return await robot.CancelAction();
            return new(false, "Robot không tồn tại");
        }
        catch (Exception ex)
        {
            Logger.Warning($"CancelAction: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, "Hệ thống có lỗi xảy ra");
        }
    }
}
