using FL.Battle.Components;
using System;
using UnityEngine;
using XGame.Database;
using XGame.Framework.Asyncs;
using XGame.Framework.Interfaces;
using XGame.Framework.Time;

namespace FL.Battle.Buffs
{
    public class Buff : IBuff, IReference, IDisposable
    {
        protected IBuffListener Listener { get; private set; }
        protected IBuffsContext Context { get; private set; }
        public BuffTable Table { get; private set; }

        public int TableId => Table.Id;

        public long EntityId { get; private set; }

        public long OwnerId => Context.Entity.EntityId;

        public int Duration => Table.EndureTime;

        private int _layers;
        /// <summary>
        /// 叠加层数
        /// </summary>
        public int Layers
        {
            get => _layers;
            set
            {
                //var last = _layers;
                _layers = Mathf.Clamp(value, 1, LayerLimit);
                (_dieTimer as IReset)?.Reset();
                //if (last != _layers)
                //    OnLayerChanged();
            }
        }
        /// <summary>
        /// 叠加层数上限
        /// </summary>
        public virtual int LayerLimit => Table.AddUp;

        public EBuffType BuffType => (EBuffType)Table.BuffType;

        /// <summary>
        /// buff结束定时器
        /// </summary>
        private ITimer _dieTimer;

        public EElementType ElementType => Table.Element;

        public string IconName => Table.Icon;

        private IAsync _vfxLoadAsync;
        private GameObject _vfxGo;

        public virtual bool IsShowIcon => true;

        public void Init(BuffTable table, long entityId, IBuffsContext context, IBuffListener listener)
        {
            Table = table;
            EntityId = entityId;
            Context = context;
            Listener = listener;
            _layers = 1;
            _dieTimer = context.Time.AddDelayTimer(Duration, () =>
            {
                Listener?.OnCompleted(TableId);
            });
            LoadBuffVfx();
            OnInited();
        }

        void IDisposable.Dispose()
        {
            InnerDispose();
        }

        void IReference.Clear()
        {
            InnerDispose();
        }
        private void InnerDispose()
        {
            OnDispose();
            _dieTimer?.Cancel();
            _dieTimer = null;
            UnloadBuffVfx();
            Table = null;
            Context = null;
            Listener = null;
        }
        protected virtual void OnInited()
        {

        }
        protected virtual void OnDispose()
        {

        }
        //protected virtual void OnLayerChanged()
        //{
        //}
        /// <summary>
        /// 加载buff配套特效
        /// </summary>
        private void LoadBuffVfx()
        {
            var vfxName = Table.BuffEffect;
            if (string.IsNullOrEmpty(vfxName))
                return;
            var loadAsync = Context.Asset.LoadAsync<GameObject>(vfxName);
            _vfxLoadAsync = loadAsync;
            loadAsync.On(_ =>
            {
                _vfxLoadAsync = null;
                var go = loadAsync.Result;
                if (go == null)
                    return;
                go.transform.SetParent(Context.OwnerTr, false);
                if (BuffType == EBuffType.Freeze)
                { // 冰冻特效根据模型大小缩放
                    go.transform.localScale = Vector3.one * Context.Entity.Attr.Radius * 2;
                }
                go.SetActive(true);
                _vfxGo = go;
            });
        }
        /// <summary>
        /// 释放特效
        /// </summary>
        private void UnloadBuffVfx()
        {
            _vfxLoadAsync?.RemoveAll();
            _vfxLoadAsync = null;
            if (_vfxGo != null)
            {
                Context.Asset.Recycle(_vfxGo);
                _vfxGo = null;
            }
        }
    }
}
