using CommonAI.Zone.Helper;
using CommonAI.ZoneClient;
using CommonLang;
using System;
using System.Collections;
using UnityEngine;
using CommonLang.Concurrent;
using CommonAI.Zone;
using System.Collections.Generic;
using System.IO;
using CommonAIClient.Unity.Utils;

namespace CommonAIClient.Unity.Battle
{
    public partial class ComAIUnit
    {
        HashMap<ZoneUnit.BuffState, Buff> mBuffs = new HashMap<ZoneUnit.BuffState, Buff>();


        private void UpdateBuff(float deltaTime)
        {
            foreach (var elem in mBuffs)
            {
                elem.Value.Update(deltaTime);
            }
        }

        protected virtual void ZUnit_OnBuffAdded(ZoneUnit unit, ZoneUnit.BuffState state)
        {
            Buff buff = new Buff(this, state);
            mBuffs.Add(state, buff);
        }

        protected virtual void ZUnit_OnBuffChanged(ZoneUnit unit, ZoneUnit.BuffState state)
        {
            Buff buff = null;
            if (mBuffs.TryGetValue(state, out buff))
            {
                buff.OnChange(state);
            }
        }

        protected virtual void ZUnit_OnBuffRemoved(ZoneUnit unit, ZoneUnit.BuffState state)
        {
            Buff buff = mBuffs.RemoveByKey(state);
            if (buff != null)
            {
                buff.Dispose();
            }
        }

        public class Buff
        {
            #region RefCount

            private static AtomicInteger s_alloc_count = new AtomicInteger(0);
            private static AtomicInteger s_active_count = new AtomicInteger(0);

            /// <summary>
            /// 分配实例数量
            /// </summary>
            public static int AllocCount { get { return s_alloc_count.Value; } }
            /// <summary>
            /// 未释放实例数量
            /// </summary>
            public static int ActiveCount { get { return s_active_count.Value; } }

            #endregion

            private bool mDisposed = false;
            private List<AssetObjectExt> mModels = new List<AssetObjectExt>();
            private List<Audio> mAudios = new List<Audio>();
            private AssetObjectExt mOverlayModel;
            private Audio mOverlayAudio;
            private Avatar mAvatar;
            internal readonly ComAIUnit mOwner;
            internal readonly ZoneUnit.BuffState mState;


            public bool IsDisposed { get { return mDisposed; } }
            protected ComAIUnit Owner { get { return mOwner; } }
            protected ZoneUnit.BuffState State { get { return State; } }


            internal Buff(ComAIUnit owner, ZoneUnit.BuffState state)
            {
                s_alloc_count++;
                s_active_count++;

                this.mOwner = owner;
                this.mState = state;

                if (state.Data.MakeAvatar
                    && !string.IsNullOrEmpty(state.Data.UnitFileName))
                {
                    mAvatar = owner.AddAvatar(state.Data.UnitFileName
                        , Path.GetFileNameWithoutExtension(state.Data.UnitFileName));
                }

                if (state.Data.BindingEffect != null)
                {
                    InitBindingEffect(state.Data.BindingEffect);
                }
                if (state.Data.BindingEffectList != null
                    && state.Data.BindingEffectList.Count > 0)
                {
                    foreach (var elem in state.Data.BindingEffectList)
                    {
                        InitBindingEffect(elem);
                    }
                }
                OnChange(state);
            }

            //只在初始化阶段调用
            private void InitBindingEffect(LaunchEffect eff)
            {
                if (!string.IsNullOrEmpty(eff.Name))
                {
                    BattleFactroy.Instance.GameObjectAdapter.Load(eff.Name
                        , System.IO.Path.GetFileNameWithoutExtension(eff.Name)
                        , (succ, aoe) =>
                        {
                            if (IsDisposed)
                            {
                                BattleFactroy.Instance.GameObjectAdapter.Unload(aoe);
                                return;
                            }

                            aoe.gameObject.ParentRoot(Owner.EffectRoot);
                            mModels.Add(aoe);
                        });
                }
                if (!string.IsNullOrEmpty(eff.SoundName))
                {
                    if (eff.IsLoop)
                    {
                        Audio audio = BattleFactroy.Instance.SoundAdapter.PlaySoundLoop(eff.SoundName, mOwner.ObjectRoot);
                        mAudios.Add(audio);

                    }
                    else
                    {
                        BattleFactroy.Instance.SoundAdapter.PlaySound(eff.SoundName, mOwner.ObjectRoot.Position());
                    }
                }
            }

            ~Buff()
            {
                s_alloc_count--;
            }

            //多层叠加
            internal void OnChange(ZoneUnit.BuffState state)
            {
                if (state.OverlayLevel < state.Data.OverlayBindingEffect.Count)
                {
                    var eff = state.Data.OverlayBindingEffect[state.OverlayLevel - 1];

                    BattleFactroy.Instance.GameObjectAdapter.Load(eff.Name
                        , System.IO.Path.GetFileNameWithoutExtension(eff.Name)
                        , (succ, aoe) =>
                        {
                            if (IsDisposed)
                            {
                                BattleFactroy.Instance.GameObjectAdapter.Unload(aoe);
                                return;
                            }

                            if (mOverlayModel != null)
                            {
                                BattleFactroy.Instance.GameObjectAdapter.Unload(mOverlayModel);
                            }

                            mOverlayModel = aoe;
                            mOverlayModel.gameObject.ParentRoot(Owner.EffectRoot);
                        });


                    if (!string.IsNullOrEmpty(eff.SoundName))
                    {
                        if (eff.IsLoop)
                        {
                            mOverlayAudio = BattleFactroy.Instance.SoundAdapter.PlaySoundLoop(eff.SoundName, mOwner.ObjectRoot);
                        }

                        else
                        {
                            BattleFactroy.Instance.SoundAdapter.PlaySound(eff.SoundName, mOwner.ObjectRoot.Position());
                        }
                    }
                }
            }

            internal void Dispose()
            {
                if (!mDisposed)
                {
                    OnDispose();
                    mDisposed = true;
                    s_active_count--;
                }
            }

            protected virtual void OnDispose()
            {
                if (mAvatar != null)
                {
                    mOwner.RemoveAvatar(mAvatar);
                }

                foreach (var elem in mModels)
                {
                    BattleFactroy.Instance.GameObjectAdapter.Unload(elem);
                }
                foreach (var elem in mAudios)
                {
                    BattleFactroy.Instance.SoundAdapter.StopSoundLoop(elem);
                }

                if (mOverlayModel != null)
                {
                    BattleFactroy.Instance.GameObjectAdapter.Unload(mOverlayModel);
                }
                if (mOverlayAudio != null)
                {
                    BattleFactroy.Instance.SoundAdapter.StopSoundLoop(mOverlayAudio);
                }
            }

            internal protected virtual void Update(float deltaTime)
            {

            }
        }
    }
}