using System;
using System.Collections.Generic;

namespace XGame.Framework.Asyncs
{
    /// <summary>
    /// 异步的回调监听操作
    /// </summary>
    public struct AsyncListenerOperation
    {
        List<OnAsyncCompleted> completedActions;
        List<ListenerKV> completedList;
        bool bNeedSort;


        /// <summary>
        /// 是否有监听事件
        /// </summary>
        public bool HaveListener => (completedActions != null && completedActions.Count > 0) || (completedList != null && completedList.Count > 0);


        public void On(OnAsyncCompleted action)
        {
            if (completedActions == null)
                completedActions = new List<OnAsyncCompleted>();

            if (action != null)
            {
                completedActions.Add(action);
            }
        }

        public void On(IAsyncListener listener, int order = 0)
        {
            if (listener == null)
                return;

            if (completedList == null)
                completedList = new List<ListenerKV>(4);

            completedList.Add(new ListenerKV(listener, order));

            bNeedSort = order != 0;
        }

        public void RemoveOn(OnAsyncCompleted action)
        {
            if (action != null)
                completedActions.Remove(action);
        }

        public void RemoveOn(IAsyncListener listener)
        {
            if (completedList == null)
                return;

            for (int i = 0; i < completedList.Count; i++)
            {
                var cur = completedList[i];
                if (cur.Listener == listener)
                {
                    completedList.RemoveAt(i);
                    break;
                }
            }
        }


        public void OnCompleted(IAsync async)
        {
            int excutedIdx = -1;

            if (completedList != null && completedList.Count > 0)
            {
                if (bNeedSort && completedList.Count > 1)
                {
                    completedList.Sort();
                }

                //先执行completedList中order小于0的
                for (excutedIdx = 0; excutedIdx < completedList.Count;)
                {
                    var cur = completedList[excutedIdx];
                    var listener = cur.Listener;
                    if (cur.Order >= 0)
                        break;
                    listener.SaveInvoke(async);
                    excutedIdx++;
                }
            }

            //执行回调函数
            if (completedActions != null)
            {
                for (int i = 0, length = completedActions.Count; i < length; i++)
                {
                    var method = completedActions[i];
                    method.SaveInvoke(async);
                }
                completedActions.Clear();
            }


            //再执行completedList中大于0的部分
            if (excutedIdx >= 0)
            {
                for (; excutedIdx < completedList.Count; excutedIdx++)
                {
                    var listener = completedList[excutedIdx].Listener;
                    listener.SaveInvoke(async);
                }
                completedList.Clear();
            }
        }

        public void Clear()
        {
            completedActions?.Clear();
            completedList?.Clear();
        }


        struct ListenerKV : IComparable<ListenerKV>
        {
            public IAsyncListener Listener;
            public int Order;

            public ListenerKV(IAsyncListener l, int o)
            {
                Listener = l;
                Order = o;
            }

            public int CompareTo(ListenerKV other)
            {
                return Order - other.Order;
            }
        }
    }
}
