@implements IDisposable

@using RobotNet.WebApp.Maps.Components.Editor.Edge
@using RobotNet.WebApp.Maps.Components.Editor.Node

<MapEdge Models="@this.EdgeModels" />
<MapNode Models="@this.NodeModels" />

@code {
    public MapEdgeModel EdgeModels { get; set; } = [];
    public MapNodeModel NodeModels { get; set; } = [];
    public bool isMoving = false;

    private bool isShowing = false;
    private (Guid Id, double X, double Y) StartPosition = new();

    public void OnShow(bool isShow, List<EdgeModel> edgeModels)
    {
        isShowing = isShow;
        if (isShow && edgeModels.Count > 0)
        {
            isMoving = false;
            List<NodeDto> nodeDtos = [];
            foreach (var edge in edgeModels)
            {
                if (!nodeDtos.Any(n => n.Id == edge.StartNode.Id)) nodeDtos.Add(new()
                    {
                        Id = edge.StartNode.Id,
                        MapId = edge.StartNode.MapId,
                        Name = edge.StartNode.Name,
                        X = edge.StartNode.X,
                        Y = edge.StartNode.Y,
                        Theta = edge.StartNode.Theta,
                        AllowedDeviationXy = edge.StartNode.AllowedDeviationXy,
                        AllowedDeviationTheta = edge.StartNode.AllowedDeviationTheta,
                        Actions = edge.StartNode.Actions,
                    });
                if (!nodeDtos.Any(n => n.Id == edge.EndNode.Id)) nodeDtos.Add(new()
                    {
                        Id = edge.EndNode.Id,
                        MapId = edge.EndNode.MapId,
                        Name = edge.EndNode.Name,
                        X = edge.EndNode.X,
                        Y = edge.EndNode.Y,
                        Theta = edge.EndNode.Theta,
                        AllowedDeviationXy = edge.EndNode.AllowedDeviationXy,
                        AllowedDeviationTheta = edge.EndNode.AllowedDeviationTheta,
                        Actions = edge.EndNode.Actions,
                    });
            }

            NodeModels.ReplaceAll(nodeDtos);
            List<EdgeModel> edges = edgeModels.Select(edge => new EdgeModel(new()
                {
                    Id = edge.Id,
                    MapId = edge.MapId,
                    DirectionAllowed = edge.DirectionAllowed,
                    TrajectoryDegree = edge.TrajectoryDegree,
                    Actions = edge.Actions,
                    AllowedDeviationTheta = edge.AllowedDeviationTheta,
                    AllowedDeviationXy = edge.AllowedDeviationXy,
                    RotationAllowed = edge.RotationAllowed,
                    MaxHeight = edge.MaxHeight,
                    MinHeight = edge.MinHeight,
                    MaxRotationSpeed = edge.MaxRotationSpeed,
                    MaxSpeed = edge.MaxRotationSpeed,
                    ControlPoint1X = edge.ControlPoint1X,
                    ControlPoint1Y = edge.ControlPoint1Y,
                    ControlPoint2X = edge.ControlPoint2X,
                    ControlPoint2Y = edge.ControlPoint2Y,
                },
                NodeModels[edge.StartNode.Id],
                NodeModels[edge.EndNode.Id]
            )).ToList();

            EdgeModels.ReplaceAll(edges);
            EdgeModels.ActivedEdge(edges);
            if (NodeModels.Count() > 0)
            {
                StartPosition.Id = NodeModels[0].Id;
                StartPosition.X = NodeModels[0].X;
                StartPosition.Y = NodeModels[0].Y;
            }
        }
        else
        {
            isMoving = false;
            NodeModels.ReplaceAll([]);
            EdgeModels.ReplaceAll([]);
        }

        StateHasChanged();
    }

    public void UpdateMove(double x, double y)
    {
        if (!isShowing) return;
        if (NodeModels.Count() > 0)
        {
            var nodeChange = NodeModels[StartPosition.Id];
            if (nodeChange is not null)
            {
                var distance = Math.Sqrt(Math.Pow(StartPosition.X - nodeChange.X, 2) + Math.Pow(StartPosition.Y - nodeChange.Y, 2));
                if (distance > 0.25) isMoving = true;
                else isMoving = false;
            }

            EdgeModels.UpdateMoveEdge(x, y);
        }
    }

    public void SetStartMovePosition(double x, double y)
    {
        EdgeModels.SetStartMovePosition(x, y);
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}