using System;
using Unity.VisualScripting;

namespace BansheeGz.BGDatabase
{
    [UnitShortTitle("Field changed Event")]
    [UnitTitle("Field changed Event")]
    [UnitSubtitle("Fires when field value is changed")]
    [UnitCategory("Events/BansheeGz")]
    public class BGBoltFieldChangedEvent: GameObjectEventUnit<BGBoltFieldChangedEventArgs>
    {
        protected override string hookName => nameof(BGBoltFieldChangedEvent);

        private EventHandler<BGEventArgsField> eventHandler;

        public override Type MessageListenerType => null;

        [DoNotSerialize]
        public ValueInput metaName { get; private set; }
        [DoNotSerialize]
        public ValueInput fieldName { get; private set; }


        [DoNotSerialize]
        public ValueOutput entityId { get; private set; }

        [DoNotSerialize]
        public ValueOutput entityIndex { get; private set; }


        protected override void Definition()
        {
            base.Definition();
            metaName = ValueInput("metaName", "");
            fieldName = ValueInput("fieldName", "");

            entityId = ValueOutput<string>("entityId");
            entityIndex = ValueOutput<int>("entityIndex");
        }

        public override void StartListening(GraphStack stack)
        {
            var data = stack.GetElementData<Data>(this);
            if (data.isListening) return;
            var reference = stack.ToReference();
            var tableName = Flow.FetchValue<string>(metaName, reference);
            var fName = Flow.FetchValue<string>(fieldName, reference);

            var table = BGRepo.I[tableName];
            var field = table.GetField(fName);
            eventHandler = (sender, args) =>
            {
                Trigger(reference, new BGBoltFieldChangedEventArgs(args.Entity.Id.ToString(), args.Entity.Index));
            };
            BGRepo.I.Events.AddFieldListener(field.Id, eventHandler);

            base.StartListening(stack);
        }

        public override void StopListening(GraphStack stack)
        {
            if (eventHandler != null)
            {
                var reference = stack.ToReference();
                var tableName = Flow.FetchValue<string>(metaName, reference);
                var fName = Flow.FetchValue<string>(fieldName, reference);
                var table = BGRepo.I[tableName];
                var field = table.GetField(fName);
                BGRepo.I.Events.RemoveFieldListener(field.Id, eventHandler);
            }
            base.StopListening(stack);
        }


        protected override void AssignArguments(Flow flow, BGBoltFieldChangedEventArgs data)
        {
            flow.SetValue(this.entityId, data.entityId);
            flow.SetValue(this.entityIndex, data.entityIndex);
        }

    }
}