// 本脚本只在不存在时会生成一次。已存在不会再次生成覆盖

using System.Collections.Generic;
using FairyGUI;
using UnityEngine;
using NBC;
using UIPanel = NBC.UIPanel;

namespace NBF
{
    public partial class Notices : UIPanel
    {
        public enum NoticeType
        {
            Info = 0,
            Success,
            Error,
            Warning,
        }

        class NoticeData
        {
            public NoticeType Type;
            public string Text;
        }
        
        private static bool _isOpen;
        private static readonly Queue<NoticeData> _msgArr = new();

        private GObjectPool _noticePool;
        private string _itemUrl;
        private float _startY;
        private float _startX;
        private const int LimitCount = 6; //显示条数上限

        private const int Gap = 8;
        private const int ItemWidth = 330;
        private const int ItemHeight = 76;

        public static void Info(string msg, NoticeType noticeType = NoticeType.Info)
        {
            if (string.IsNullOrEmpty(msg)) return;
            Log.Info($"显示一个notice={msg}");
            if (!_isOpen)
            {
                Notices.Show();
            }

            _msgArr.Enqueue(new NoticeData { Type = noticeType, Text = msg });
        }

        public static void Success(string msg)
        {
            Info(msg, NoticeType.Success);
        }

        public static void Warning(string msg)
        {
            Info(msg, NoticeType.Warning);
        }

        public static void Error(string msg)
        {
            Info(msg, NoticeType.Error);
        }


        protected override void OnInit()
        {
            ContentPane.sortingOrder = UIDef.UIOrder.Notices;
            _startY = GRoot.inst.height - ItemHeight - Gap - 110;
            _startX = GRoot.inst.width - ItemWidth - Gap;
            _itemUrl = UIPackage.GetItemURL(UIDef.Pack.Common, "NoticeItem");
            _noticePool = new GObjectPool(ContentPane.container.cachedTransform);
        }

        protected override void OnShow()
        {
            _isOpen = true;
        }

        protected override void OnUpdate()
        {
            if (_msgArr.Count > 0)
            {
                var msg = _msgArr.Dequeue();
                ShowOnceNotice(msg);
                //旧的向上移动
                var count = ContentPane.numChildren - 1;
                for (int i = 0; i < count; i++)
                {
                    GObject obj = ContentPane.GetChildAt(i);
                    if (obj != null)
                    {
                        SetObjRise(obj);
                    }
                }

                RemoveLimitMsg();
            }
        }

        //region notice
        private void ShowOnceNotice(NoticeData notice)
        {
            var item = GetFromPool(_itemUrl) as NoticeItem;
            if (item == null) return;
            item.SetData(notice.Text, notice.Type);
            item.x = _startX;
            item.y = _startY;

            item.alpha = 1;
            // item.TweenFade(0, 0.5f).SetDelay(2);
            // item.TweenMoveY(0, 3).SetEase(EaseType.QuintInOut).OnComplete(() => { ReturnToPool(item); });
            //显示在固定区域 两秒后消失
            item.TweenFade(0, 0.5f).SetDelay(3).OnComplete(() => { ReturnToPool(item); });
        }

        private void SetObjRise(GObject item)
        {
            item.TweenMoveY(item.y - item.height - 10, 0.2f).SetEase(EaseType.QuintInOut);
        }

        private void RemoveLimitMsg()
        {
            var count = ContentPane.numChildren;
            if (count > LimitCount)
            {
                for (int i = 0; i < count - LimitCount; i++)
                {
                    GObject obj = ContentPane.GetChildAt(i);
                    if (obj != null)
                    {
                        if (GTween.IsTweening(obj))
                        {
                            GTween.Kill(obj, true);
                        }
                        else
                        {
                            ReturnToPool(obj);
                        }
                    }
                }
            }
        }

        private GObject GetFromPool(string url)
        {
            var ret = _noticePool.GetObject(url);
            if (ret == null) return null;
            ret.visible = true;
            ContentPane.AddChild(ret);
            GTween.GetTween(ret, TweenPropType.Y)?.Kill();
            return ret;
        }

        private void ReturnToPool(GObject obj)
        {
            ContentPane.RemoveChild(obj);
            _noticePool.ReturnObject(obj);
        }

        protected override void OnHide()
        {
            _isOpen = false;
        }

        protected override void OnDestroy()
        {
            _noticePool.Clear();
        }
    }
}