using System.Collections;
using System.Collections.Generic;
using Animancer;
using Common.Utility.CombatEvent;
using Core.Utility;
using Fort23.Common;
using Fort23.Core;
using Fort23.UTool;
using GameLogic.Combat.Buff;
using GameLogic.Combat.CombatTool;
using GameLogic.Combat.CombatTool.CombatReport;
using GameLogic.Combat.Hero;
using GameLogic.Combat.Hero.HeroGPU;
using GameLogic.Player;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;
using UTool.CustomizeTimeLogic.FxLogic.TimeLineEventinterface;
public class CombatHeroEntity : ShowBaiscEntity, ITimeLineAnimtion, ITimeLineGetAttSpeed,
    IHero
{
    /// 
    /// 死亡时的节点ID
    /// 
    public int heroDieNodeId;
    public bool isPlayer;
    public bool isCreateHeroHp;
    public string guidName
    {
        get { return CurrCombatHeroInfo.modelName; }
    }
    public bool isFollowState;
    private float _lasetShowHarmTime;
    private float _injuriedShowTime;
    private bool _isAddinjuriedShow;
    private float _addInjuiedValue = (1.0f / 0.2f) * 0.3f;
    private bool _isDis;
    public float DisTime;
    public MagicWeaponControl heroMagicWeaponControl;
    public float HpBl
    {
        get { return CurrCombatHeroInfo.hp.Value * 100f / MaxCombatHeroInfo.hp.Value; }
    }
    public Vector3 dotPos
    {
        get { return combatHeroGameObject.position; }
    }
    public T GetThis() where T : IHero
    {
        return (T)(object)this;
    }
    public GameObject GameObject
    {
        get { return combatHeroGameObject.transform.gameObject; }
    }
    public Vector3 faceDir
    {
        get { return combatHeroGameObject.transform.forward; }
    }
    public async CTask InitForObject(GameObjectPool poolInterface, CombatAIBasic combatAIBasic,
        CombatHeroInfo combatHeroInfo,
        Vector3 pos,
        System.Action callBack = null, bool isPlayer = false)
    {
        //后面记到检查战斗里面不要出现异步加载,也不要出现同步IO加载
        this.isPlayer = isPlayer;
        string modelName = combatHeroInfo.modelName;
        if (combatHeroInfo.isGpu)
        {
            modelName += "_gpu";
        }
        CurrCombatHeroInfo = combatHeroInfo.Copy();
        MaxCombatHeroInfo = combatHeroInfo.Copy();
        poolInterface.own.transform.position = pos;
        // if (!IsEnemy)
        // {
        //     GameObjectPool fx_hero_quan =
        //         await GObjectPool.Instance.FetchAsync("fx_hero_quan.prefab", null);
        //     fx_hero_quan.own.transform.SetParent(poolInterface.own.transform);
        //     fx_hero_quan.own.transform.localPosition = Vector3.zero;
        // }
        // poolInterface.own.SetActive(false);
        heroMagicWeaponControl = new MagicWeaponControl();
        combatHeroTimeLineControl = new CombatHeroTimeLineControl();
        combatHeroTimeLineControl.Init(this);
        AssetHandle assetHandle =
            await AssetBundleLoadManager.Instance.LoadAssetAsyncTask(combatHeroInfo.modelName + "_TD.txt");
        if (assetHandle != null)
        {
            TextAsset textAsset = assetHandle.AssetObject();
            TimeLienData timeLienData = JsonManager.FromJson(textAsset.text);
            timeLienData.DeserializeData();
            assetHandle.Release();
            combatHeroTimeLineControl.AddTimeLienData(timeLienData);
        }
        combatHeroGameObject = new CombatHeroGameObject();
        combatHeroGameObject.Init(this, poolInterface);
        BuffControl = new BuffControl();
        BuffControl.Init(this);
        NavMeshAgent navMeshAgent = poolInterface.own.GetComponent();
        if (combatAIBasic == null)
        {
            combatAIBasic = new CombatAIBasic();
        }
        HeroEntityMono heroEntityMono = poolInterface.own.GetComponent();
        if (heroEntityMono == null)
        {
            CombatHeroColliderRoot combatHeroColliderRoot=  poolInterface.own.GetComponent();
            if (combatHeroColliderRoot != null)
            {
                heroEntityMono = combatHeroColliderRoot.root.GetOrAddComponent();
            }
            else
            {
                heroEntityMono =  poolInterface.own.GetOrAddComponent();
            }
        }
        heroEntityMono.combatHeroEntity = this;
        CombatAIBasic = combatAIBasic;
        CombatAIBasic.Init(this);
        CombatHeroSkillControl = new CombatHeroSkillControl();
        await CombatHeroSkillControl.Init(this);
        await InitShieldsFx();
        AnimancerComponent animancerComponent = poolInterface.own.GetComponent();
        combatHeroAnimtion = new CombatHeroAnimtion();
        // if (animancerComponent != null)
        {
        }
        // else
        // {
        //     combatHeroAnimtion = new CombatHeroGPUAnimtion();
        // }
        poolInterface.own.SetActive(true);
        combatHeroAnimtion.Init(this);
        CombatAIBasic.ChangeState(CombatHeroStateType.XiuMian);
        if (isCreateHeroHp)
        {
            CreateHeroHpEventData createHeroHpEventData = CreateHeroHpEventData.Create();
            createHeroHpEventData.combatHeroEntity = this;
            EventManager.Instance.Dispatch(CustomEventType.CreateHeroHp, createHeroHpEventData);
        }
        await heroMagicWeaponControl.InitMagicWeapon(this, isPlayer);
        CombatReportManager.Instance.AddCombatReportInfo(this);
        callBack?.Invoke(this);
        return this;
    }
    public virtual async CTask Init(CombatAIBasic combatAIBasic, CombatHeroInfo combatHeroInfo,
        Vector3 pos,
        System.Action callBack = null, bool isPlayer = false)
    {
        //后面记到检查战斗里面不要出现异步加载,也不要出现同步IO加载
        this.isPlayer = isPlayer;
        string modelName = combatHeroInfo.modelName;
        if (combatHeroInfo.isGpu)
        {
            modelName += "_gpu";
        }
        CurrCombatHeroInfo = combatHeroInfo.Copy();
        MaxCombatHeroInfo = combatHeroInfo.Copy();
        // GameTimeLineParticleFactory
        CombatHeroGameObjectPool poolInterface =
            await GObjectPool.Instance.FetchAsync(modelName + ".prefab", null);
        if (poolInterface == null || poolInterface.own == null)
        {
            return null;
        }
        return await InitForObject(poolInterface, combatAIBasic, combatHeroInfo, pos, callBack, isPlayer);
    }
    public virtual void Update(float t)
    {
        CombatAIBasic.Update(t);
        CombatHeroSkillControl.Update(t);
        combatHeroTimeLineControl.Update(t);
        combatHeroAnimtion.Update(t);
        combatHeroGameObject.Update(t);
        BuffControl.Update(t);
        heroMagicWeaponControl?.Update(t);
        if (combatHeroGameObject.HeroGPUMono != null)
        {
            if (_injuriedShowTime > 0)
            {
                _injuriedShowTime -= t;
                if (_isAddinjuriedShow)
                {
                    combatHeroGameObject.HeroGPUMono.injuriedStrength += t * (_addInjuiedValue);
                    if (combatHeroGameObject.HeroGPUMono.injuriedStrength >= 0.3f)
                    {
                        _isAddinjuriedShow = false;
                    }
                }
                else
                {
                    combatHeroGameObject.HeroGPUMono.injuriedStrength -= t * (_addInjuiedValue);
                    if (combatHeroGameObject.HeroGPUMono.injuriedStrength < 0)
                    {
                        combatHeroGameObject.HeroGPUMono.injuriedStrength = 0;
                    }
                }
            }
            else
            {
                combatHeroGameObject.HeroGPUMono.injuriedStrength = 0;
            }
        }
    }
    public T This()
    {
        return (T)(object)this;
    }
    public override T GetILifetCycleHitPoint(string hitPoinName, bool isStandType, bool isIgnoreHind)
    {
        return combatHeroGameObject.GetILifetCycleHitPoint(hitPoinName, isStandType, isIgnoreHind);
    }
    public override T GetMainHotPoin(bool isIgnoreHind = false)
    {
        return combatHeroGameObject.GetMainHotPoin(isIgnoreHind);
    }
    public void PlayAnim(string animName, bool isLoop, int layerId, bool repeat, float speed)
    {
        combatHeroAnimtion.Play(animName, speed);
    }
    public SpecialDotInfo GetSpecialDotInfo(string specialDotName)
    {
        return combatHeroGameObject.GetMainHotPoin(true).GetSpecialDotInfo(specialDotName);
    }
    public virtual float GetAttSpeed()
    {
        // CombatHeroSkillControl combatHeroSkillControl = CombatHeroSkillControl as CombatHeroSkillControl;
        // if (combatHeroSkillControl != null)
        // {
        //     if (combatHeroSkillControl.useSkillCount > 1)
        //     {
        //         return 4;
        //     }
        //
        //     return CurrCombatHeroInfo.GetAnimationSpeed;
        // }
        return 1;
    }
    public void HeroResurrection()
    {
        isDie = false;
        CombatAIBasic.ChangeState(CombatHeroStateType.idle, isQiangZhi: true);
        HeroHpUpdateEventData heroHpUpdateEventData = HeroHpUpdateEventData.Create();
        heroHpUpdateEventData.combatHeroEntity = this;
        CombatEventManager.Instance.Dispatch(CombatEventType.HeroHpUpdate, heroHpUpdateEventData);
        HeroResurrectionEventData heroResurrectionEventData = HeroResurrectionEventData.Create();
        heroResurrectionEventData.combatHeroEntity = this;
        CombatEventManager.Instance.Dispatch(CombatEventType.HeroResurrection, heroResurrectionEventData);
    }
    public void HeroDie(HarmReturnInfo harmReturnInfo)
    {
        heroDieNodeId = CombatController.currActiveCombat.CombatTypeBasic.allWinNodeCount;
        isDie = true;
        HeroDieEventData heroDieEventData = HeroDieEventData.Create();
        heroDieEventData.combatHeroEntity = this;
        heroDieEventData.HarmReturnInfo = harmReturnInfo;
        CombatEventManager.Instance.Dispatch(CombatEventType.HeroDie, heroDieEventData);
        combatHeroGameObject.HeroDie();
        CombatAIBasic.ChangeState(CombatHeroStateType.dile);
        CombatEventManager.Instance.Dispatch(CombatEventType.HeroDieFinish, heroDieEventData);
    }
    /// 
    /// 是否被控制
    /// 
    /// 
    public bool IsControl()
    {
        BuffBasic basic = BuffControl.GetBuffBasicForIdGroup(1006);
        if (basic != null)
        {
            return true;
        }
        b_1025 b1025 = BuffControl.GetBuffBasicForType();
        if (b1025 != null)
        {
            return true;
        }
        return false;
    }
    /// 
    /// 是否不能添加功法
    /// 
    /// 
    public bool IsCantAddGongFa()
    {
        BuffBasic basic = BuffControl.GetBuffBasicForIdGroup(1006);
        if (basic != null)
        {
            return false;
        }
        return true;
    }
    public void HeroHurt(HarmReturnInfo harmReturnInfo)
    {
        if (isDie)
        {
            return;
        }
        b_1015 b1015 = BuffControl.GetBuffBasicForType();
        if (b1015 != null)
        {
            return;
        }
        long att = harmReturnInfo.att;
        IBarrier shieldsBarrier = harmReturnInfo.triggerData.IBarrier as IBarrier;
        if (shieldsBarrier != null)
        {
            att = shieldsBarrier.Harm(harmReturnInfo);
            harmReturnInfo.harmType |= HarmType.Shields;
        }
        else
        {
            harmReturnInfo.isHitHero = true;
        }
        if (att > 0)
        {
            CurrCombatHeroInfo.hp -= att;
        }
        if (isZhanZhuang)
        {
            CurrCombatHeroInfo.hp = MaxCombatHeroInfo.hp;
        }
        UpdateHarmText(harmReturnInfo);
        if (combatHeroGameObject.HeroGPUMono != null)
        {
            _injuriedShowTime = 0.4f;
            combatHeroGameObject.HeroGPUMono.injuriedStrength = 0;
            _isAddinjuriedShow = true;
        }
        HeroInjuredEventData heroInjured = HeroInjuredEventData.Create();
        heroInjured.HarmReturnInfo = harmReturnInfo;
        CombatEventManager.Instance.Dispatch(CombatEventType.HeroInjured, heroInjured);
        HeroHpUpdateEventData heroHpUpdateEventData = HeroHpUpdateEventData.Create();
        heroHpUpdateEventData.combatHeroEntity = this;
        CombatEventManager.Instance.Dispatch(CombatEventType.HeroHpUpdate, heroHpUpdateEventData);
        if (CurrCombatHeroInfo.hp <= 0)
        {
            HeroDie(harmReturnInfo);
        }
    }
    private void UpdateHarmText(HarmReturnInfo harmReturnInfo)
    {
        float currTime = Time.time;
        if (currTime - _lasetShowHarmTime < 0.1f)
        {
            return;
        }
        _lasetShowHarmTime = currTime;
        HarmUpdateEventData harmUpdateEventData = HarmUpdateEventData.Create();
        harmUpdateEventData.HarmReturnInfo = harmReturnInfo;
        CombatEventManager.Instance.Dispatch(CombatEventType.HarmUpdate, harmUpdateEventData);
    }
    public void Recover(HarmReturnInfo harmReturnInfo)
    {
        CurrCombatHeroInfo.hp += harmReturnInfo.att;
        if (CurrCombatHeroInfo.hp > MaxCombatHeroInfo.hp)
        {
            CurrCombatHeroInfo.hp = MaxCombatHeroInfo.hp;
        }
        HarmUpdateEventData harmUpdateEventData = HarmUpdateEventData.Create();
        harmUpdateEventData.HarmReturnInfo = harmReturnInfo;
        CombatEventManager.Instance.Dispatch(CombatEventType.RecoverUpdate, harmUpdateEventData);
        HeroHpUpdateEventData heroHpUpdateEventData = HeroHpUpdateEventData.Create();
        heroHpUpdateEventData.combatHeroEntity = this;
        CombatEventManager.Instance.Dispatch(CombatEventType.HeroHpUpdate, heroHpUpdateEventData);
    }
    public void CloseLoopFx()
    {
        for (int i = 0; i < heroLoopParticle.Count; i++)
        {
            GObjectPool.Instance.Recycle(heroLoopParticle[i]);
        }
        heroLoopParticle.Clear();
    }
    public void DisposeForOnetCombat()
    {
        if (_isDis)
        {
            return;
        }
        _isDis = true;
        BuffControl.Dispose();
        _isDis = true;
        CombatHeroSkillControl.Dispose();
        CombatAIBasic.Dispose();
        combatHeroTimeLineControl.Dispose();
        combatHeroAnimtion.Dispose();
        CloseLoopFx();
        ShieldsBarrier?.Dispose();
        ShieldsBarrier = null;
    }
    public void Dispose()
    {
        if (_isDis)
        {
            return;
        }
        _isDis = true;
        BuffControl.Dispose();
        combatHeroGameObject.Dispose();
        isDie = true;
        CombatHeroSkillControl.Dispose();
        CombatAIBasic.Dispose();
        combatHeroTimeLineControl.Dispose();
        combatHeroAnimtion.Dispose();
        CloseLoopFx();
        ShieldsBarrier?.Dispose();
        ShieldsBarrier = null;
    }
    private void ProDormancyObj()
    {
        CombatHeroSkillControl.ProDormancyObj();
    }
    public override void ActiveObj()
    {
        isDie = false;
        _isDis = false;
    }
    public override void DormancyObj()
    {
        Dispose();
        ProDormancyObj();
        _isDis = false;
        CombatAIBasic = null;
        combatHeroGameObject = null;
        CurrCombatHeroInfo = null;
        MaxCombatHeroInfo = null;
        combatHeroTimeLineControl = null;
        combatHeroAnimtion = null;
        CombatHeroSkillControl = null;
        isFollowState = false;
        heroLoopParticle.Clear();
        isDie = true;
    }
}