#nullable enable


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

    [StepType(StepTypeAttribute.OperatorStep)]
    public class Operate : OutputStep<double>
    {
        [UnityEngine.SerializeField]
        MultiPort<double> _in = new();

        [UnityEngine.SerializeReference, CareBoo.Serially.ShowSerializeReference]
        public IResourceOperator? Operator;

        [UnityEngine.SerializeField]
        List<double> _const = new();

        public override IEnumerable<IPort> Inputs {
            get {
                yield return _in;
            }
        }

        public override string ToString() {
            var operatorName = Operator == null ? "*" : Operator.GetType().Name;
            var constName = _const.Count == 0 ? "" : $"({string.Join(",", _const)})";

            return $"{operatorName}{constName}";
        }

        public override bool IsValid => Operator != null;

        public override double Run(EffectInput blackBoard) {
            if (!IsValid || Operator == null) {
                UnityEngine.Debug.LogError($"{this} Inner types are null");
                return default;
            }

            var result = Operator.OperateEnum(_in.Nodes.Select(getter => getter.Run(blackBoard)).Concat(_const));

            return result;
        }
        public override EffectStepNodeData ToData() {
            var effectStepNodeData = base.ToData();
            effectStepNodeData.Const = _const;
            effectStepNodeData.Operator = Operator;
            return effectStepNodeData;
        }

        public override bool FromData(EffectStepNodeData effectStepNodeData, Dictionary<string, EffectStepNode> guidToNode) {
            base.FromData(effectStepNodeData, guidToNode);
            _const = effectStepNodeData.Const ?? new();
            Operator = effectStepNodeData.Operator;

            return true;
        }
    }
}