using System;
using System.Collections.Generic;
using FairyGUI;
using UnityEngine;

namespace NBC
{
    public abstract class UIPanel : IUIPanel
    {
        public static Func<string, string> GetUIPackNameFunc = s => $"{s}/{s}";

        /// <summary>
        /// 是否显示在最顶层
        /// </summary>
        public bool IsTop => _ui.IsTop(this);

        /// <summary>
        /// 是否显示黑色背景蒙版
        /// </summary>
        public bool IsModal { get; protected set; }

        public virtual bool IsShowing => ContentPane != null && ContentPane.parent != null;

        public virtual bool IsCanVisible => ContentPane != null && ContentPane.parent != null && ContentPane.visible;

        public bool IsDotDel { get; protected set; }
        public virtual string UIPackRootUrl => string.Empty;

        public virtual string UIPackName { get; set; }
        public virtual string UIResName { get; set; }

        /// <summary>
        /// 模块id，(可用于对模块编号实现一些特定功能，如新手引导)
        /// </summary>
        public virtual int Id { get; protected set; }

        /// <summary>
        /// 是否显示光标，屏蔽游戏内输入
        /// </summary>
        public virtual bool IsShowCursor { get; protected set; } = true;

        /// <summary>
        /// 面板打开动画
        /// </summary>
        public UIAnimTask ShowAnim = null;

        /// <summary>
        /// 面板关闭动画
        /// </summary>
        public UIAnimTask HideAnim = null;

        private object _paramData;
        private bool _isInited;

        public GComponent ContentPane { get; protected set; }
        protected UIManager _ui;

        public void SetUIManager(UIManager manager)
        {
            _ui = manager;
        }

        public void SetData(object args)
        {
            _paramData = args;
        }

        public object GetData()
        {
            return _paramData;
        }

        public virtual string[] GetDependPackages()
        {
            return new string[] { };
        }


        public void Init()
        {
            try
            {
                var uiPackRootUrl = string.IsNullOrEmpty(UIPackRootUrl) ? UIConst.UIPackRootUrl : UIPackRootUrl;
                //实例化预设
                if (!_isInited)
                {
                    var dependPackages = GetDependPackages();
                    if (dependPackages != null && dependPackages.Length > 0)
                    {
                        foreach (var package in dependPackages)
                        {
                            if (package != UIPackName)
                            {
                                _ui.AddPackage(uiPackRootUrl, GetUIPackNameFunc(package));
                            }
                        }
                    }

                    _ui.AddPackage(uiPackRootUrl, GetUIPackNameFunc(UIPackName));

                    GObject panelObj = UIPackage.CreateObject(UIPackName, UIResName);
                    if (panelObj == null)
                    {
                        throw new Exception("不存在包名：" + UIPackName + "/ResName=" + UIResName);
                    }

                    // panelObj.name = UIResName;
                    panelObj.SetSize(GRoot.inst.width, GRoot.inst.height);
                    panelObj.position = Vector3.zero;
                    panelObj.ToSafeArea();
                    panelObj.scale = Vector2.one;
                    panelObj.pivotX = 0.5f;
                    panelObj.pivotY = 0.5f;
                    ContentPane = panelObj.asCom;
                    ContentPane.name = UIResName;
                    this.AutoFindAllField();
                    OnInit();

                    // FairyBatching
                    GComponent panelObjCom = panelObj.asCom;
                    if (panelObjCom != null)
                    {
                        panelObjCom.fairyBatching = true;
                    }

                    _isInited = true;
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
                throw;
            }
        }

        public void Show()
        {
            try
            {
                if (!IsShowing)
                {
                    GRoot.inst.AddChild(ContentPane);
                    ContentPane.visible = true;
                    _ui.AdjustModalLayer();
                }
                else
                {
                    if (!IsTop) _ui.BringToFront(this);
                    if (IsModal)
                    {
                        _ui.AdjustModalLayer();
                    }
                }

                _ui.TryPlayPanelTween(ContentPane);
                OpenAnimBegin();
                if (ShowAnim != null)
                {
                    ShowAnim.SetDefaultInfo();
                    ShowAnim.OnCompleted(OpenAnimFinished, true);
                    ShowAnim.Run(UIRunner.Def);
                }
                else
                {
                    OpenAnimFinished(null);
                }
            }
            catch (Exception e)
            {
                Log.Error($"UIPackName={UIPackName} UIResName={UIResName} e={e}");
                throw;
            }
        }

        public void Hide()
        {
            if (!IsShowing) return;
            if (HideAnim != null)
            {
                HideAnim.SetDefaultInfo();
                HideAnim.OnCompleted(HideAnimFinished);
                HideAnim.Run(UIRunner.Def);
            }
            else
            {
                HideAnimFinished(null);
            }
        }

        public void Update()
        {
            OnUpdate();
        }

        public void Refresh()
        {
            Show();
        }


        /// <summary>
        /// 设置刷新多语言
        /// </summary>
        public void SetLanguage()
        {
            _ui.TrySetPanelLanguage(ContentPane);
            OnSetLanguage();
        }

        public void HideImmediately()
        {
            // ContentPane.visible = false;
            if (ContentPane.parent != null)
            {
                // UIKit.
                GRoot.inst.RemoveChild(ContentPane);
                _ui.AdjustModalLayer();

                _ui?.DispatchEventWith(UIEvents.UIHide, this);
                // UIKit.LayerManager.RemoveChild(this);
            }

            OnHide();
        }

        public void Dispose()
        {
            if (!IsDotDel)
            {
                HideImmediately();
                ContentPane.Dispose();
                OnDestroy();
            }
            else
            {
                Log.Error("当前panel标记为不可删除，name=" + UIResName);
            }
        }

        private void OpenAnimBegin()
        {
            OnShow();
            SetLanguage();
            _ui?.DispatchEventWith(UIEvents.UIShow, this);
        }

        /// <summary>
        /// 打开动画播放完成
        /// </summary>
        /// <param name="task"></param>
        private void OpenAnimFinished(ITask task)
        {
            OnShowed();
        }

        /// <summary>
        /// 关闭动画播放完成
        /// </summary>
        /// <param name="task"></param>
        private void HideAnimFinished(ITask task)
        {
            HideImmediately();
        }

        #region 接口

        /// <summary>
        /// 界面初始化的时候
        /// </summary>
        protected virtual void OnInit()
        {
        }

        /// <summary>
        /// 代码设置多语言，OnShow后和语言变化时会调用
        /// </summary>
        protected virtual void OnSetLanguage()
        {
        }

        /// <summary>
        /// 显示界面显示
        /// </summary>
        /// <param name="param"></param>
        protected virtual void OnShow()
        {
        }

        /// <summary>
        /// 显示界面完成（动画后）
        /// </summary>
        protected virtual void OnShowed()
        {
        }

        protected virtual void OnUpdate()
        {
        }

        /// <summary>
        /// 界面隐藏的时候
        /// </summary>
        protected virtual void OnHide()
        {
        }

        /// <summary>
        /// 界面销毁的时候
        /// </summary>
        protected virtual void OnDestroy()
        {
        }

        #endregion
    }
}