#nullable enable

namespace TagFighter.Effects.Steps
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    [Serializable]
    public class SinglePort<PortType> : IPort
    {
        public OutputStep<PortType>? Node;


        public PortCapacity Capacity => PortCapacity.Single;

        public string? DisplayName { get; set; }

        public IEnumerable<EffectStepNode> Connections() {
            if (Node != null) {
                yield return Node;
            }
        }

        public void DisconnectAll() {
            Node = null;
        }

        public bool FromData(PortData portData, Dictionary<string, EffectStepNode> guidToNode) {
            DisplayName = portData.DisplayName;
            var connectedNodeGuid = portData.ConnectedNodesGuid.FirstOrDefault();
            if (connectedNodeGuid != null) {
                TryConnect(guidToNode.GetValueOrDefault(connectedNodeGuid));
            }

            return true;
        }

        public bool IsAllowedConnect(EffectStepNode node) {
            // UnityEngine.Debug.Log($"{node.GetType()} {typeof(PortType)} {node as PortType}");
            return node is OutputStep<PortType>;
        }

        public PortData ToData() {
            return new() {
                Type = new(typeof(SinglePort<PortType>)),
                DisplayName = DisplayName,
                ConnectedNodesGuid = Node != null ? new() { $"{Node.Guid}" } : new(),
            };
        }

        public bool TryConnect(EffectStepNode node) {
            var success = false;
            if (IsAllowedConnect(node)) {
                Node = node as OutputStep<PortType>;
                success = true;
            }

            return success;
        }

        public bool TryDisconnect(EffectStepNode value) {
            var success = false;
            if (ReferenceEquals(Node, value)) {
                Node = null;
                success = true;
            }

            return success;
        }
    }
}