using FL.Battle.Buffs;
using System.Collections.Generic;
using UnityEngine;
using XGame.Database;

namespace FL.Battle.Components
{
    /// <summary>
    /// 该脚本主要处理属性类Buff
    /// </summary>
    public partial class BuffsComponent
    {
        /// <summary>
        /// 加速buff
        /// </summary>
        private List<Buff> _speedUpBuffs;
        /// <summary>
        /// 减速buff
        /// </summary>
        private List<Buff> _speedCutBuffs;
        /// <summary>
        /// key:buffId
        /// value:buff增加/减少的属性值
        /// </summary>
        private Dictionary<int, int> _buffAttributeMap;
        private EAttributeType GetAttributeType(Buff buff)
        {
            return (EAttributeType)buff.Table.BuffTypeNum[0];
        }
        private int GetAttributeValue(Buff buff)
        {
            return buff.Table.BuffTypeNum[1] * buff.Layers;
        }
        /// <summary>
        /// 增加属性buff
        /// </summary>
        /// <param name="buff"></param>
        private void AddAttributeBuff(Buff buff)
        {
            //if (buff.BuffType != EBuffType.Attribute)
            //    return;
            var attrType = GetAttributeType(buff);
            if (attrType == EAttributeType.SpeedAdd)
            { // 加/减速的buff同时只能各有一个生效
                AddSpeedBuff(buff);
                return;
            }
            SaveAttributeValue(buff);
        }
        /// <summary>
        /// 移除属性buff
        /// </summary>
        /// <param name="buff"></param>
        private void RemoveAttributeBuff(Buff buff)
        {
            //if (buff.BuffType != EBuffType.Attribute)
            //    return;
            var attrType = GetAttributeType(buff);
            if (attrType == EAttributeType.SpeedAdd)
            { // 加/减速的buff同时只能各有一个生效
                RemoveSpeedBuff(buff);
                return;
            }
            RemoveAttributeValue(buff);
        }
        private void SaveAttributeValue(Buff buff)
        {
            var buffId = buff.TableId;
            var addVal = GetAttributeValue(buff);
            var result = addVal;
            if (_buffAttributeMap == null)
                _buffAttributeMap = new Dictionary<int, int>();
            else if (_buffAttributeMap.TryGetValue(buffId, out var lastVal))
            {
                result -= lastVal;
            }
            _buffAttributeMap[buffId] = addVal;
            var attrType = GetAttributeType(buff);
            Context.Entity.Attr.Dynamic.AddValue(attrType, result);
        }
        private void RemoveAttributeValue(Buff buff)
        {
            if (_buffAttributeMap?.TryGetValue(buff.TableId, out var value) ?? false)
            {
                _buffAttributeMap.Remove(buff.TableId);
                Context.Entity.Attr.Dynamic.AddValue(GetAttributeType(buff), -value);
            }
        }
        private void AddSpeedBuff(Buff buff)
        {
            var buffId = buff.TableId;
            var addVal = GetAttributeValue(buff);
            var speedBuffs = GetSpeedBuffs(addVal > 0);
            if (speedBuffs.Count > 0)
            { // 已有buff
                var firstLast = speedBuffs[0];
                var buffIdx = speedBuffs.FindIndex((a) => a.TableId == buffId);
                if (buffIdx != -1)
                {
                    speedBuffs.RemoveAt(buffIdx);
                }
                buffIdx = -1;
                for (int i = 0; i < speedBuffs.Count; i++)
                {
                    var tempBuff = speedBuffs[i];
                    var tempVal = GetAttributeValue(tempBuff);
                    if (Mathf.Abs(tempVal) < Mathf.Abs(addVal))
                    { // 找到第一个数值比当前小的，数值一样的，新的在后面
                        speedBuffs.Insert(i, buff);
                        buffIdx = i;
                        break;
                    }
                }
                if (buffIdx == -1)
                {
                    speedBuffs.Add(buff);
                    buffIdx = speedBuffs.Count - 1;
                }
                var firstNext = speedBuffs[0];
                if (firstNext.TableId == firstLast.TableId)
                { // 第一位的buff没变化，是同一个buff则需要刷新数值，否则不刷新
                    if (buffIdx > 0)
                    {
                        return;
                    }
                }
                else
                { // 先删除旧buff的数值
                    RemoveAttributeValue(firstLast);
                    SaveAttributeValue(firstNext);
                    RefreshMoveTimeScale();
                    return;
                }
            }
            else
            {
                speedBuffs.Add(buff);
            }
            SaveAttributeValue(buff);
            RefreshMoveTimeScale();
        }
        private void RemoveSpeedBuff(Buff buff)
        {
            var buffId = buff.TableId;
            var addVal = GetAttributeValue(buff);
            var speedBuffs = GetSpeedBuffs(addVal > 0);
            var buffIdx = speedBuffs.FindIndex((a) => a.TableId == buffId);
            if (buffIdx < 0)
            {
                return;
            }
            speedBuffs.RemoveAt(buffIdx);
            if (buffIdx > 0)
            { // 删除的不是第一个
                return;
            }
            //删除的是第一个buff
            RemoveAttributeValue(buff);
            if (speedBuffs.Count > 0)
            { // 还有加/减速buff
                SaveAttributeValue(speedBuffs[0]);
            }
            RefreshMoveTimeScale();
        }
        private List<Buff> GetSpeedBuffs(bool isSpeedUp)
        {
            if (isSpeedUp)
                return _speedUpBuffs ??= new List<Buff>();
            return _speedCutBuffs ??= new List<Buff>();
        }
        private void ClearAttributes()
        {
            _buffAttributeMap?.Clear();
            _speedUpBuffs?.Clear();
            _speedCutBuffs?.Clear();
        }
        private void RefreshMoveTimeScale()
        {
            Context.Move.TimeScale = Context.Entity.Attr.MoveSpeedScale;
        }
    }
}
