﻿using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace JLGames.RocketDriver.Games.PanelManager
{
    public class ButtonAction : MonoBehaviour
    {
        public class Actions
        {
            public UnityAction ActionOk;
            public UnityAction ActionCancel;
            public UnityAction ActionClose;
            public UnityAction ActionOutside;
            public UnityAction ActionOther;
        }

        [SerializeField] protected Button m_ButtonOk;
        [SerializeField] protected Button m_ButtonCancel;
        [SerializeField] protected Button m_ButtonClose;
        [SerializeField] protected Button m_ButtonOutside;
        [SerializeField] protected Button m_ButtonOther;

        public Button ButtonOk => m_ButtonOk;
        public Button ButtonCancel => m_ButtonCancel;
        public Button ButtonClose => m_ButtonClose;
        public Button ButtonOutside => m_ButtonOutside;
        public Button ButtonOther => m_ButtonOther;

        private Button.ButtonClickedEvent m_EventOk;
        private Button.ButtonClickedEvent m_EventCancel;
        private Button.ButtonClickedEvent m_EventClose;
        private Button.ButtonClickedEvent m_EventOutside;
        private Button.ButtonClickedEvent m_EventOther;

        public void AppendOkAction(UnityAction action)
        {
            if (null == action) return;
            if (null == m_EventOk) m_EventOk = new Button.ButtonClickedEvent();
            m_EventOk.AddListener(action);
        }

        public void SetOkAction(UnityAction action)
        {
            m_EventOk?.RemoveAllListeners();
            AppendOkAction(action);
        }

        public void AppendCancelAction(UnityAction action)
        {
            if (null == action) return;
            if (null == m_EventCancel) m_EventCancel = new Button.ButtonClickedEvent();
            m_EventCancel.AddListener(action);
        }

        public void SetCancelAction(UnityAction action)
        {
            m_EventCancel?.RemoveAllListeners();
            AppendCancelAction(action);
        }

        public void AppendCloseAction(UnityAction action)
        {
            if (null == action) return;
            if (null == m_EventClose) m_EventClose = new Button.ButtonClickedEvent();
            m_EventClose.AddListener(action);
        }

        public void SetCloseAction(UnityAction action)
        {
            m_EventClose?.RemoveAllListeners();
            AppendCloseAction(action);
        }

        public void AppendOutsideAction(UnityAction action)
        {
            if (null == action) return;
            if (null == m_EventOutside) m_EventOutside = new Button.ButtonClickedEvent();
            m_EventOutside.AddListener(action);
        }

        public void SetOutsideAction(UnityAction action)
        {
            m_EventOutside?.RemoveAllListeners();
            AppendOutsideAction(action);
        }

        public void AppendOtherAction(UnityAction action)
        {
            if (null == action) return;
            if (null == m_EventOther) m_EventOther = new Button.ButtonClickedEvent();
            m_EventOther.AddListener(action);
        }

        public void SetOtherAction(UnityAction action)
        {
            m_EventOther?.RemoveAllListeners();
            AppendOtherAction(action);
        }

        public void ClearActions()
        {
            m_EventOk?.RemoveAllListeners();
            m_EventCancel?.RemoveAllListeners();
            m_EventClose?.RemoveAllListeners();
            m_EventOutside?.RemoveAllListeners();
            m_EventOther?.RemoveAllListeners();
            m_EventOk = m_EventCancel = m_EventClose = m_EventOutside = m_EventOther = null;
        }

        private void OnEnable()
        {
            InitButtonActions();
        }

        private void OnDisable()
        {
            ReInitButtonActions();
        }

        void OnDestroy()
        {
            ReInitButtonActions();
            m_EventOk = m_EventCancel = m_EventClose = m_EventOutside = m_EventOther = null;
        }

        protected void InitButtonActions()
        {
            AddButtonAction(m_ButtonOk, OnClickOk);
            AddButtonAction(m_ButtonCancel, OnClickCancel);
            AddButtonAction(m_ButtonClose, OnClickClose);
            AddButtonAction(m_ButtonOutside, OnClickOutside);
            AddButtonAction(m_ButtonOther, OnClickOther);
        }

        protected void ReInitButtonActions()
        {
            RemoveButtonAction(m_ButtonOther, OnClickOther);
            RemoveButtonAction(m_ButtonOutside, OnClickOutside);
            RemoveButtonAction(m_ButtonClose, OnClickClose);
            RemoveButtonAction(m_ButtonCancel, OnClickCancel);
            RemoveButtonAction(m_ButtonOk, OnClickOk);
        }

        protected void AddButtonAction(Button button, UnityAction action)
        {
            if (null != button && null != action)
            {
                button.onClick.AddListener(action);
            }
        }

        protected void RemoveButtonAction(Button button, UnityAction action)
        {
            if (null != button && null != action)
            {
                button.onClick.RemoveListener(action);
            }
        }

        protected void Close()
        {
            PanelManagerShared.Manager.CloseInstacnePanel(gameObject);
        }

        protected void CloseAndInvoke(Button.ButtonClickedEvent evt)
        {
            Close();
            evt?.Invoke();
        }

        protected void OnClickOk()
        {
            CloseAndInvoke(m_EventOk);
        }

        protected void OnClickCancel()
        {
            CloseAndInvoke(m_EventCancel);
        }

        protected void OnClickClose()
        {
            CloseAndInvoke(m_EventClose);
        }

        protected void OnClickOutside()
        {
            CloseAndInvoke(m_EventOutside);
        }

        protected void OnClickOther()
        {
            m_EventOther?.Invoke();
        }
    }
}