using CommonAI.Data;
using CommonAI.Zone;
using CommonAI.Zone.Formula;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonLang;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XmdsCommon.JSGModule.Interface;
using XmdsCommon.Plugin;
using XmdsCommonServer.Plugin;
using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills;
using XmdsCommonServer.XLS.Data;
using XmdsCommonSkill.Plugin.Buffs;
using XmdsCommonSkill.Plugin.Interface;
using XmdsCommonSkill.Plugin.Skills;

namespace XmdsCommonSkill.Plugin.CardSkill
{
	/** 卡牌技能基类 */
	public abstract class JSGCardSkillBase : XmdsSkillBase, IJSGCardSkill
	{
		//蓄势buff
		protected static readonly int BUFF_STOREENERGY = (int)XmdsBuffBase.XmdsBuffList.CARD_STORE_ENERGY;
		protected static readonly byte BUFF_STOREENERGY_TRIGGER_MIN = 3;                // 蓄势触发最少球数
		protected static readonly int BUFF_STOREENERGY_DMG = 500;                       // 每一层蓄势对应的

		//蓄势最高层, 时间
		protected static int BUFF_STOREENERGY_MAXLAYER = 0;
		protected static int BUFF_STOREENERGY_TIME = 10000;
		//青龙之力,XX之力最高层数
		protected static int BUFF_ABILITY_MAXLAYER = 10;

		private int mTriggerSameCards;

		//触发卡牌技能
		public virtual void TriggerCardSkill(XmdsVirtual player, XmdsVirtual hitter, AttackSource source, CardSkillData skillData, int sameNums)
		{
			// 基础数据初始化
			this.mTriggerSameCards = sameNums;
			player.CardModule.TriggerSkillLoadStrength(skillData, sameNums);
			this.OnTriggerCardSkill(player, hitter, source, skillData, sameNums);
		}

		protected override void OnSkillDamagePerEvent(BattleParams param)
		{
			this.OnGetCardSkillDamage(param);

			//玩家伤害不一样(治疗不受影响)
			if (param.Hitter.IsPlayerUnit() && param.UseDamageType != DamageType.Heal)
			{
				param.SkillDamagePer = CUtils.CastInt(param.SkillDamagePer * XmdsConfig.Instance.CARD_PLAYER_DMG_PER);
			}
		}

		protected override void OnSkillLogicAftercalDamage(BattleParams param)
		{
			//整体技能伤害加成(蓄势特殊伤害,走配置,定值)
			IntIntData dmgStrength = param.Attacker.CardModule.GetStrengthInfo(CardStrengthenType.Dmg);
			if (dmgStrength != null && dmgStrength.value1 > 0)
			{
				if(dmgStrength.value1 > 50000)
				{
					log.Warn("JSGCardSkillBase OnSkillLogicAftercalDamage notice: " + this.SkillID + ", " + dmgStrength.value1);
				}
				//param.SkillDamagePer += XmdsConfig.Instance.CARD_STOREENERGY_DMG * Math.Min(dmgStrength.value2, this.GetStoreMaxLayer());
				param.HitResult = CUtils.CastInt(param.HitResult * (1.0f + XmdsUnitProp.PER * dmgStrength.value1));
				//System.Console.WriteLine("伤害强化扩展:" + dmgStrength.value1);
			}

			//按层数叠加伤害
			//dmgStrength = param.Attacker.CardModule.GetStrengthInfo(CardStrengthenType.Dmg_SpecialLayer);
			//if (dmgStrength != null && dmgStrength.value1 > 0)
			//{
			//	float addPer = XmdsUnitProp.PER * dmgStrength.value1 * Math.Min(BUFF_ABILITY_MAXLAYER, dmgStrength.value2);
			//	param.HitResult = CUtils.CastInt(param.HitResult * (1.0f + addPer));
			//}			
		}

		//用于子类扩展继承的
		public virtual int GetEffectID(int skillLv, int sameNums) { return this.SkillID; }
		public virtual void OnTriggerCardSkill(XmdsVirtual player, XmdsVirtual hitter, AttackSource source, CardSkillData skillData, int sameNums) { }
		protected virtual void OnGetCardSkillDamage(BattleParams param) { }

		//技能数据变更
		protected override void OnSkillDataChange(GameSkill gs, XmdsVirtual unit)
		{
			unit.CardModule.OnSkillDataChange(gs);
		}

		protected override void OnInitOver(XmdsVirtual unit, GameSkill info)
		{
			unit.CardModule.OnInitOver(info, this);

			if(BUFF_STOREENERGY_MAXLAYER == 0)
			{
				this.LoadStaticData();
			}
		}

		//释放法术
		protected void unitLaunchSpell(XmdsVirtual launcher, XmdsVirtual hitter, int spellID, bool fromBody = true)
		{
			if(launcher == null)
			{
				string stackInfo = new StackTrace().ToString();
				log.Error("JSGCardSkillBase unitLaunchSpell launch_null 1: " + spellID + ", CardSkillID: " + this.SkillID);
				return;
			}
			else if(hitter == null)
			{
				//需要目标,但是没有,设定为最大仇恨目标
				//log.Info("card skill need target but null: " + spellID + ", CardSkillID: " + this.SkillID);
				InstanceUnit hateUnit = launcher.GetHateSystem().GetHated();
				if(hateUnit == null)
				{
					//log.Error("JSGCardSkillBase unitLaunchSpell launch_null 3: " + spellID + ", CardSkillID: " + this.SkillID);
					return;
				}
				hitter = hateUnit.Virtual as XmdsVirtual;
				if (hitter == null)
				{
					log.Error("JSGCardSkillBase unitLaunchSpell launch_null 2: " + spellID + ", CardSkillID: " + this.SkillID);
					return;
				}
			}

			LaunchSpell launchSpll = ComSpellTemplate.Instance().GetCardSpell(spellID);
			XmdsVirtual fromUnit = (fromBody || hitter == null) ? launcher : hitter;
			if (hitter == null)
			{
				launcher.mUnit.Parent.unitLaunchSpell(XmdsSkillType.cardSkill, launcher.mUnit, launchSpll, fromUnit.mUnit.X, fromUnit.mUnit.Y);
			}
			else
			{
				launcher.mUnit.Parent.unitLaunchSpell(XmdsSkillType.cardSkill, launcher.mUnit, launchSpll, fromUnit.mUnit.X, fromUnit.mUnit.Y, hitter.mUnit.ID);
			}			
		}

		public int GetTriggerSameCards()
		{
			return this.mTriggerSameCards;
		}

		// 卡牌相同数,获取表格数据读取下标
		public int GetIndex2(int index)
		{
			return this.mTriggerSameCards * 2 + index - 4;
		}

		// 卡牌相同数,获取表格数据读取下标
		public int GetIndex3(int index)
		{
			return this.mTriggerSameCards * 3 + index - 6;
		}

		// 卡牌相同数,获取表格数据读取下标
		public int GetIndex4(int index)
		{
			return this.mTriggerSameCards * 4 + index - 8;
		}

		// 获得蓄势最大层
		private void LoadStaticData()
		{
			var bt1 = XmdsBattleSkill.GetBuffTemplate(BUFF_STOREENERGY);
			if (bt1 != null)
			{
				BUFF_STOREENERGY_MAXLAYER = bt1.MaxOverlay;
				BUFF_STOREENERGY_TIME = bt1.LifeTimeMS;
			}
			else
			{
				BUFF_STOREENERGY_MAXLAYER = 1;
				BUFF_STOREENERGY_TIME = 10000;
			}

			// XX之力最高层数
			var bt2 = XmdsBattleSkill.GetBuffTemplate(CardSkill_QingLongBase.BuffID_TYPE_ABILITY);
			if (bt2 != null)
			{
				BUFF_ABILITY_MAXLAYER = bt2.MaxOverlay;
			}
			else
			{
				BUFF_ABILITY_MAXLAYER = 10;
			}
		}

		protected void AddXuShi(XmdsVirtual player, int addLayers)
		{
			CardLayerRule layerRule = new CardLayerRule(BUFF_STOREENERGY, CardLayerType.Layers, BUFF_STOREENERGY_MAXLAYER);
			NextCardStrengthenInfo data = player.CardModule.AddNextStrengthInfo(CommonAI.Data.CardType.Max, CardStrengthenType.Dmg, 
				XmdsConfig.Instance.CARD_STOREENERGY_DMG, addLayers, BUFF_STOREENERGY_TIME, 1, BUFF_STOREENERGY_TRIGGER_MIN, DamageType.Damage, layerRule);
			if(data != null)
			{
				data.bindBuffID = BUFF_STOREENERGY;
			}
		}
	}
}