﻿using System;
using Bolt;
using Ludiq;
using UnityEngine;

namespace InfinityCode.OnlineMapsBolt
{
    [UnitCategory("Online Maps")]
    public abstract class OnlineMapsBoltEventBase : Unit
    {
        [DoNotSerialize]
        [PortLabelHidden]
        public ControlInput enter { get; private set; }

        [DoNotSerialize]
        [PortLabelHidden]
        public ControlOutput exit { get; private set; }

        [DoNotSerialize]
        [PortLabelHidden]
        [NullMeansSelf]
        public ValueInput target { get; private set; }

        protected override void Definition()
        {
            enter = ControlInput("enter", Enter);
            exit = ControlOutput("exit");
            target = ValueInput("target", (GameObject) null).NullMeansSelf();

            Succession(enter, exit);

            OnDefinition();
        }

        protected abstract void OnDefinition();

        protected ControlOutput Enter(Flow flow)
        {
            OnEnter(flow);
            return exit;
        }

        protected abstract void OnEnter(Flow flow);

        protected void SubscribeToEvent(Flow flow, ref Action action, ValueInput eventName)
        {
            string name = flow.GetValue<string>(eventName);
            if (string.IsNullOrEmpty(name)) return;

            GameObject targetGO = flow.GetValue<GameObject>(target);
            action += () => CustomEvent.Trigger(targetGO, name);
        }

        protected void SubscribeToEvent<T>(Flow flow, ref Action<T> action, ValueInput eventName)
        {
            string name = flow.GetValue<string>(eventName);
            if (string.IsNullOrEmpty(name)) return;

            GameObject targetGO = flow.GetValue<GameObject>(target);
            action += v => CustomEvent.Trigger(targetGO, name, v);
        }

        public void ResetEvent(ref Action action)
        {
            action = null;
        }
    }
}