using FairyGUI;
using UnityEngine;

namespace NBC
{
    /// <summary>
    /// ui界面默认动画
    /// </summary>
    public class PanelAnimationDef : UIAnimTask
    {
        public enum AnimType
        {
            CenterScaleBig = 0,

            /// <summary>上往中滑动--</summary>
            UpToSlide = 1,

            /// <summary>//下往中滑动</summary>
            DownToSlide = 2,

            /// <summary>左往中--</summary>
            LeftToSlide = 3,

            /// <summary>右往中--</summary>
            RightToSlide = 4,

            /// <summary>透明度</summary>
            Fade = 5,

            // 
            CenterPopScaleFade = 6,
            UpToSlideFade = 7,
            DownToSlideFade = 8,
            LeftToSlideFade = 9,
            RightToSlideFade = 10,
            BounceVertical = 11,
            Rotate = 12,
            Shake = 13,
        }

        private bool _isClose;
        private GComponent _node;
        private AnimType _animType;
        private float _animTime;


        public PanelAnimationDef(GComponent node, AnimType animType = AnimType.CenterScaleBig, bool close = false,
            float animTime = 0.5F)
        {
            _node = node;
            _isClose = close;
            _animType = animType;
            _animTime = animTime;
        }

        protected override void OnStart()
        {
            if (_node == null)
            {
                Finish();
                return;
            }

            // 直接使用 UITweenDynamic 扩展方法处理新增复合效果
            switch (_animType)
            {
                case AnimType.CenterPopScaleFade:
                    if (!_isClose)
                        _node.TweenPopShow(callback: Finish);
                    else
                        _node.TweenPopHide(callback: Finish);
                    return;
                case AnimType.UpToSlideFade:
                    if (!_isClose)
                        _node.TweenSlideInTop(callback: Finish);
                    else
                        _node.TweenSlideOutTop(callback: Finish);
                    return;
                case AnimType.DownToSlideFade:
                    if (!_isClose)
                        _node.TweenSlideInBottom(callback: Finish);
                    else
                        _node.TweenSlideOutBottom(callback: Finish);
                    return;
                case AnimType.LeftToSlideFade:
                    if (!_isClose)
                        _node.TweenSlideInLeft(callback: Finish);
                    else
                        _node.TweenSlideOutLeft(callback: Finish);
                    return;
                case AnimType.RightToSlideFade:
                    if (!_isClose)
                        _node.TweenSlideInRight(callback: Finish);
                    else
                        _node.TweenSlideOutRight(callback: Finish);
                    return;
                case AnimType.BounceVertical:
                    if (!_isClose)
                        _node.TweenBounceShow(callback: Finish); // 向上偏移进入
                    else
                        _node.TweenBounceHide(callback: Finish);
                    return;
                case AnimType.Rotate:
                    if (!_isClose)
                        _node.TweenRotateShow(callback: Finish);
                    else
                        _node.TweenRotateHide(callback: Finish);
                    return;
                case AnimType.Shake:
                    // shake 只在打开时使用，关闭直接结束
                    if (_isClose)
                    {
                        Finish();
                        return;
                    }

                    _node.TweenShakeShow(callback: Finish);
                    return;
            }


            if (_animType == AnimType.CenterScaleBig)
            {
                var strat = _isClose ? Vector3.one : Vector3.zero;
                var end = _isClose ? Vector3.zero : Vector3.one;
                var easeType = _isClose ? EaseType.BackIn : EaseType.BackOut;
                GTween.To(strat, end, _animTime)
                    .SetEase(easeType)
                    .SetTarget(_node, TweenPropType.Scale)
                    .OnComplete(Finish);
            }
            else if (_animType == AnimType.UpToSlide || _animType == AnimType.DownToSlide)
            {
                var safeAreaY = UI.Inst.GetSafeArea().y;
                var hight = GRoot.inst.viewHeight;
                var y = _animType == AnimType.UpToSlide ? -hight : hight;
                var strat = _isClose ? 0 : y;
                var end = _isClose ? y : safeAreaY;
                GTween.To(strat, end, _animTime)
                    .SetEase(EaseType.CubicOut)
                    .SetTarget(_node, TweenPropType.Y)
                    .OnComplete(Finish);
            }
            else if (_animType == AnimType.LeftToSlide || _animType == AnimType.RightToSlide)
            {
                var width = GRoot.inst.viewWidth;
                var x = _animType == AnimType.LeftToSlide ? -width : width;
                var strat = _isClose ? 0 : x;
                var end = _isClose ? x : 0;
                GTween.To(strat, end, _animTime)
                    .SetEase(EaseType.CubicOut)
                    .SetTarget(_node, TweenPropType.X)
                    .OnComplete(Finish);
            }
            else if (_animType == AnimType.Fade)
            {
                var s = _isClose ? 1 : 0;
                var end = _isClose ? 0 : 1;
                _node.alpha = s;
                GTween.To(s, end, _animTime)
                    .SetEase(EaseType.Linear)
                    .SetTarget(_node, TweenPropType.Alpha)
                    .OnComplete(Finish);
            }
        }

        /// <summary>
        /// 设置默认的状态
        /// </summary>
        public override void SetDefaultInfo()
        {
            switch (_animType)
            {
                case AnimType.CenterScaleBig:
                    _node.scale = _isClose ? Vector2.one : Vector2.zero;
                    break;
                case AnimType.UpToSlide:
                case AnimType.DownToSlide:
                    var hight = GRoot.inst.viewHeight;
                    var y = _animType == AnimType.UpToSlide ? -hight : hight;
                    _node.y = _isClose ? 0 : y;
                    break;
                case AnimType.LeftToSlide:
                case AnimType.RightToSlide:
                    var width = GRoot.inst.viewWidth;
                    var x = _animType == AnimType.LeftToSlide ? -width : width;
                    _node.x = _isClose ? 0 : x;
                    break;
                case AnimType.Fade:
                    _node.alpha = _isClose ? 1 : 0;
                    break;
                case AnimType.CenterPopScaleFade:
                    _node.scale = _isClose ? Vector2.one : new Vector2(0.8f, 0.8f);
                    _node.alpha = _isClose ? 1 : 0;
                    break;
                case AnimType.UpToSlideFade:

                    break;
                case AnimType.DownToSlideFade:

                    break;
                case AnimType.LeftToSlideFade:

                    break;
                case AnimType.RightToSlideFade:

                    break;
                case AnimType.BounceVertical:

                    break;
                case AnimType.Rotate:

                    break;
                case AnimType.Shake:

                    break;
            }
        }
    }

    public static class UIPanelAnimation
    {
        public static UIAnimTask GetCenterScaleBig(IUIPanel panel, bool close = false, float animTime = 0.5F)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.CenterScaleBig, close, animTime);

        public static UIAnimTask GetUpToSlide(IUIPanel panel, bool close = false, float animTime = 0.5F)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.UpToSlide, close, animTime);

        public static UIAnimTask GetDownToSlide(IUIPanel panel, bool close = false, float animTime = 0.5F)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.DownToSlide, close, animTime);

        public static UIAnimTask GetLeftToSlide(IUIPanel panel, bool close = false, float animTime = 0.5F)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.LeftToSlide, close, animTime);

        public static UIAnimTask GetRightToSlide(IUIPanel panel, bool close = false, float animTime = 0.5F)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.RightToSlide, close, animTime);

        public static UIAnimTask GetFade(IUIPanel panel, bool close = false, float animTime = 0.5F)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.Fade, close, animTime);

        // 新增复合动效获取方法
        public static UIAnimTask GetCenterPopScaleFade(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.CenterPopScaleFade, close);

        public static UIAnimTask GetUpToSlideFade(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.UpToSlideFade, close);

        public static UIAnimTask GetDownToSlideFade(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.DownToSlideFade, close);

        public static UIAnimTask GetLeftToSlideFade(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.LeftToSlideFade, close);

        public static UIAnimTask GetRightToSlideFade(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.RightToSlideFade, close);

        public static UIAnimTask GetBounceVertical(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.BounceVertical, close);

        public static UIAnimTask GetRotate(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.Rotate, close);

        public static UIAnimTask GetShake(IUIPanel panel, bool close = false)
            => new PanelAnimationDef(panel.ContentPane, PanelAnimationDef.AnimType.Shake, close);
    }
}