using System;
using System.Collections.Generic;
using Fort23.UTool;
using UnityEngine;
using UTool.CustomizeTimeLogic.FxLogic.TimeLineEventinterface;
using UTool.CustomizeTimeLogic.FxLogic.TimeLineEventLogic;

namespace CombatLibrary.CombatLibrary.CombatCore.CustomizeTimeLogic.FxLogic
{
    /// <summary>
    /// 把一些列clip进行管理起来（动画、声音、特效），组成一个技能所需的所有资源。
    /// 一般来说，就是一个track group下面的所有track里的所有clip
    /// </summary>
    public class TimeLineEventLogicGroupBasic : IDisposable
    {
        public object extraData;

        /// <summary>
        /// 关联的组
        /// </summary>
        private List<TimeLineEventLogicGroupBasic> _AssociationGroupBasics = new List<TimeLineEventLogicGroupBasic>();

        /// <summary>
        /// Timeline的逻辑组 
        /// </summary>
        [System.NonSerialized] public List<TimeLineEventLogicBasic> timeLineLogic = new List<TimeLineEventLogicBasic>();

        public System.Action<ParticleSystemPool> OnInitParticleSystemPoolCallBack;
        public long InitGuid;

        /// <summary>
        /// 当前时间线的执行时间
        /// </summary>
        public float timeLineTime;

        protected float maxTime;


        public float MAXTime => maxTime;

        public bool updateEnd;

        protected bool skillTimelineEnd;

        /// <summary>
        /// 时间线最大时间
        /// </summary>
        public float TimeLineMaxTime;

        public string groupName;
        protected ITimeLineTriggerEntity targetEntity;

        protected ILifeCycle castEntity;

        /// <summary>
        /// timeLine更新结束
        /// </summary>
        public System.Action TimeLineUpdateEnd;

        /// <summary>
        /// 是否有结束标志，如果没有，时间完成的时候就是结束的时候
        /// </summary>
        protected bool isEndSing;

        public float attSpeed;
        // public float updateSpeed;

        public float SkillPreparationTime;

        public void AddAssociationGroupBasics(TimeLineEventLogicGroupBasic timeLineEventLogicGroupBasic)
        {
            _AssociationGroupBasics.Add(timeLineEventLogicGroupBasic);
        }

        public bool IsExist(TimeLineEventLogicGroupBasic timeLineEventLogicGroupBasic)
        {
            if (this == timeLineEventLogicGroupBasic)
            {
                return true;
            }

            for (int i = 0; i < _AssociationGroupBasics.Count; i++)
            {
                if (_AssociationGroupBasics.Contains(timeLineEventLogicGroupBasic))
                {
                    return true;
                }
            }

            return false;
        }

        public virtual Vector3 SceneWorldPos()
        {
            return Vector3.one;
        }

        public void Init(List<TimeLineAssetSerialization> timeLineAssetSerializations)
        {
            for (int i = 0; i < timeLineAssetSerializations.Count; i++)
            {
                TimeLineAssetSerialization timeLineAssetSerialization = timeLineAssetSerializations[i];
                if (timeLineAssetSerialization is TimeLineMaxTimeSerializtion)
                {
                    maxTime = (float)timeLineAssetSerialization.endTime;
                }

                if (timeLineAssetSerialization is TimeLineSkillPreparationSerializtion)
                {
                    SkillPreparationTime = (float)timeLineAssetSerialization.endTime;
                }

                if (TimeLineMaxTime < timeLineAssetSerialization.endTime)
                {
                    TimeLineMaxTime = (float)timeLineAssetSerialization.endTime;
                }

                if (timeLineAssetSerialization is TimeLineEndSingSerializtion)
                {
                    isEndSing = true;
                }

                TimeLineEventLogicBasic timeLineEventLogicBasic = timeLineAssetSerialization.CreateLogic();
                timeLineEventLogicBasic.InitEventLogic(this, timeLineAssetSerialization);
                timeLineLogic.Add(timeLineEventLogicBasic);
            }

            if (maxTime == 0)
            {
                maxTime = TimeLineMaxTime;
            }

            ProInit();
        }

        protected virtual void ProInit()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="castEntity">施放者</param>
        /// <param name="targetEntity">触发者</param>
        /// <param name="currTarget">当前作用目标</param>
        /// <param name="extraData">事件的额外数据，在事件触发回调时带回回调的方法，更具具体逻辑赋值</param>
        /// <param name="customizePos">自定的点，对于特殊表现的需要，更具具体逻辑赋值</param>
        public void SetCombatInfo(ILifeCycle castEntity, ITimeLineTriggerEntity targetEntity,
            BetterList<ILifetCycleHitPoint> currTarget,
            TriggerData extraData,
            Vector3[] customizePos)
        {
            updateEnd = false;
            this.castEntity = castEntity;
            this.targetEntity = targetEntity;
            timeLineTime = (float)0;
            for (int i = 0; i < timeLineLogic.Count; i++)
            {
                timeLineLogic[i].SetCombatInfo(castEntity, targetEntity, currTarget, extraData, customizePos);
            }


            attSpeed = (float)1;
            if (groupName.Contains("att"))
            {
                ITimeLineGetAttSpeed timeLineGetAttSpeed = castEntity as ITimeLineGetAttSpeed;
                if (timeLineGetAttSpeed != null)
                {
                    attSpeed = timeLineGetAttSpeed.GetAttSpeed();
                }
            }

            if (attSpeed <= 0)
            {
                attSpeed = (float)1;
            }
        }

        public bool Update(float time)
        {
            if (updateEnd)
            {
                return true;
            }


            float updateSpeed = 1;
            ITimeLineParticlePlaySpeed timeLineParticlePlaySpeed = this.castEntity as ITimeLineParticlePlaySpeed;
            if (timeLineParticlePlaySpeed != null)
            {
                updateSpeed = timeLineParticlePlaySpeed.GetCurrPlaySpeed(null);
            }

            timeLineTime += time * attSpeed * updateSpeed;
            for (int i = 0; i < timeLineLogic.Count; i++)
            {
                timeLineLogic[i].TimeUpdate(timeLineTime);
            }

            if (timeLineTime > TimeLineMaxTime)
            {
                updateEnd = true;
            }

            if (!skillTimelineEnd && (timeLineTime > maxTime || updateEnd)) //完了
            {
                skillTimelineEnd = true;
                TimeLineUpdateEnd?.Invoke();
                if (!isEndSing)
                {
                    ITimeLineEndSing timeLineEndSing =
                        targetEntity as ITimeLineEndSing;
                    if (timeLineEndSing != null)
                    {
                        // LogTool.Log("技能结束");
                        timeLineEndSing.TimeLineEndSing(groupName);
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 打断TimeLine
        /// </summary>
        public void BreakTimeLine()
        {
            updateEnd = true;
            if (timeLineLogic != null)
            {
                for (int i = 0; i < timeLineLogic.Count; i++)
                {
                    timeLineLogic[i].BreakTimeLine();
                }

                timeLineLogic.Clear();
            }

            Dispose();
        }

        public void CloseLoopFx()
        {
            if (timeLineLogic != null)
            {
                for (int i = 0; i < timeLineLogic.Count; i++)
                {
                    TimeLineEventParticleLogicBasic timeLineEventParticleLogicBasic =
                        timeLineLogic[i] as TimeLineEventParticleLogicBasic;
                    if (timeLineEventParticleLogicBasic != null)
                    {
                        timeLineEventParticleLogicBasic.CloseLoopFx();
                    }
                }

                timeLineLogic.Clear();
            }
        }

        public void Dispose()
        {
            _AssociationGroupBasics.Clear();
            timeLineLogic.Clear();
        }
    }
}