using CommonAI.Data;
using CommonAI.Zone.Formula;
using CommonAI.Zone.Helper;
using CommonAI.ZoneServer.JSGModule;
using CommonLang.Log;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XmdsCommon.JSGModule;
using XmdsCommon.JSGModule.Interface;
using XmdsCommon.Plugin;
using XmdsCommonServer.Plugin;
using XmdsCommonServer.Plugin.CardSkill;
using XmdsCommonServer.Plugin.CardSkill.PlayerCardSkill;
using XmdsCommonServer.XLS.Data;

namespace XmdsCommonSkill.Plugin.CardSkill
{
	/** 玩家卡牌技能模块 */
	public class JSGPlayerCardModule : JSGCardModuleBase
	{
		//protected static Logger log = LoggerFactory.GetLogger("JSGPlayerCardModule");

		//玩家卡牌技能信息
		private CardSkillData[] mPlayerCardSkill = new CardSkillData[(int)CardType.Max + 1];
		//卡牌权重模块
		private JSGCardRateModule mCardRateModule = new JSGCardRateModule();

		// 上次获得卡牌数据
		private GetCardData mLastCardInfo = new GetCardData();
		
		// 卡牌珠下一次强化效果
		private JSNextCardSkillStrengthenhModule mNextCardStrengthInfo = new JSNextCardSkillStrengthenhModule();

		//玩家数据
		private int mCardListTestIndex = 0;
		//是否开启
		private bool mIsFuncOpen;

		public JSGPlayerCardModule(XmdsVirtual owner)
		{
			//this.Init(owner);
		}

		protected override bool OnInit(XmdsVirtual owner, bool notifyClient)
		{
			mIsFuncOpen = false;
			if (mCardData == null)
			{
				mCardData = new JSGPlayerCardData();
			}

			XmdsUnitProperties prop = owner.mUnit.Properties as XmdsUnitProperties;
			if (prop == null || owner.SkillHelper == null || prop.ServerData.CardSkills == null)
			{
				log.Error("XmdsPlayerCardSkill null : " + owner.mUnit.Parent.GetSceneID() + ", " + owner.mUnit.PlayerUUID);
				return false;
			}
			else if(prop.ServerData.CardSkills.UnitSkills.Count != (int)CardType.Max + 1)
			{
				log.Error("XmdsPlayerCardSkill init 四象系统技能数量错误 : " + owner.mUnit.Parent.GetSceneID() + ", " + owner.mUnit.PlayerUUID + ", " + prop.ServerData.CardSkills.UnitSkills.Count);
				return false;
			}
			
			for (int i = 0; i <= (int)CardType.Max; i++)
			{
				GameSkill gs = prop.ServerData.CardSkills.UnitSkills[i];
				mPlayerCardSkill[i] = new CardSkillData(gs.SkillID, (CardType)i);
				if(!this.InitSkillData(mPlayerCardSkill[i], gs))
				{
					return false;
				}				
			}

			this.ReloadCardSkillWeight();
			this.ReSet(true, notifyClient);
			String uniqueInfo = mOwner.mUnit.IsPlayer ? mOwner.mUnit.PlayerUUID : (mOwner.mUnit.Parent.GetSceneID() + "_" + mOwner.mInfo.ID);
			mCardRateModule.initUniqueInfo(uniqueInfo);
			return true;
		}

		private bool InitSkillData(CardSkillData cardSkillData, GameSkill gs, IJSGCardSkill cardSkill = null)
		{
			cardSkillData.skill = cardSkill == null ? (this.mOwner.SkillHelper.GetPlayerSkillById(gs.SkillID) as IJSGCardSkill) : cardSkill;;
			if (cardSkillData.skill == null)
			{
				log.Error("初始化玩家卡牌技能异常1: " + this.mOwner.mUnit.PlayerUUID + ", " + gs.SkillID);
				//mPlayerCardSkill[i].skilLv = 0;
				//mPlayerCardSkill[i].weight = 1000;
				return false;
			}

			XmdsSkillData skillData = XmdsDataMgr.GetInstance().GetXmdsSkillData(gs.SkillID);
			if (skillData != null)
			{
				if (skillData.DamageType == 1)
				{
					cardSkillData.dmgType = DamageType.Damage;
				}
				else if (skillData.DamageType == 2)
				{
					cardSkillData.dmgType = DamageType.Heal;
				}
				else
				{
					cardSkillData.dmgType = DamageType.None;
				}
			}
			else
			{
				log.Error("初始化玩家卡牌技能异常2: " + this.mOwner.mUnit.PlayerUUID + ", " + gs.SkillID);
				return false;
			}

			cardSkillData.skilLv = (short)gs.SkillLevel;
			//if(cardSkillData.type < CardType.Max)
			//{
			//	cardSkillData.setWeight(this.mOwner);
			//}
			
			return true;
		}

		protected override void ReSet(bool IsInit, bool notifyClient)
		{
			base.ReSet(IsInit, notifyClient);
			if(IsInit)
			{
				this.mNextCardStrengthInfo.Init();
			}

			if(!IsInit)
			{
				this.mCardListTestIndex = 0;
				this.mNextGetCardTime = 0;

				this.mNextCardStrengthInfo.ReSet();
				this.mLastCardInfo.ReSet();
				this.mCardData.ReSet(this.mOwner);
			}
			else if(notifyClient)
			{
				this.mCardData.RefreshCardInfo(this.mOwner);
			}
		}

		protected override void OnUpdate(XmdsVirtual player, int interval, bool slowRefresh)
		{
			if (!this.mIsFuncOpen || !slowRefresh)
			{
				return;
			}

			this.mNextCardStrengthInfo.Update(player);
			this.mCardRateModule.Update();
		}

		//击中某一单位
		public override void OnHitOther(XmdsVirtual hitter, AttackSource source, int damage, DamageType damageType)
		{
			// 排除自己作用于自己的一切伤害
			if (!this.mIsFuncOpen || (damage <= 0) || this.mOwner == hitter)
			{
				return;
			}

			if (!base.mIsInitOK || this.mOwner == null || mPlayerCardSkill == null || mNextGetCardTime > CommonLang.CUtils.localTimeMS 
				|| source.FromSkillType == XmdsSkillType.cardSkill || !JSGModule.RandomPrecent(this.mCardCfg.rate))
			{
				return;
			}

			mNextGetCardTime = CommonLang.CUtils.localTimeMS + this.mCardCfg.interval;
			GenCardData cardData = mCardRateModule.GetRandomCardType(mPlayerCardSkill);
			if(cardData == null)
			{
				log.Warn("JSGPlayerCardModule OnHitOther 没有随机到卡牌:" + this.mOwner.mUnit.PlayerUUID);
				return;
			}
			this.DoPlayerAddCard(cardData, hitter, source, CreateCardBallSource.Normal);
		}

		//额外增加一个球:指定类型和属性
		public override void AddCard(CardType type, int nums)
		{
			this.DoPlayerAddCard(new GenCardData(type, nums), null, null, CreateCardBallSource.CardLogic);
		}

		//额外产生一个球:random(true: 使用权重来获取,false: 获得一个权重最高额)
		public override void AddCard(int nums, bool useWeight)
		{
			CardType cardType = mCardRateModule.GetCardByWeight(useWeight);
			if (cardType == CardType.Max)
			{
				log.Warn("JSGPlayerCardModule AddCard 没有随机到卡牌:" + this.mOwner.mUnit.PlayerUUID + ", " + nums);
				return;
			}

			this.DoPlayerAddCard(new GenCardData(cardType, nums), null, null, CreateCardBallSource.CardLogic);
		}


		//增加某一卡牌权重
		public override void ChangeCardWeight(CardType type, CardRateChgType chgType, int value,  int validTime, 
			bool isPrecent = true, int validTimes = -1, int uniqueID = 0)
		{
			CardRateChgData data = new CardRateChgData();
			data.uniqueID = uniqueID;
			data.cardType = type;
			data.chgType = chgType;
			data.isPrecent = isPrecent;
			data.value = (short)value;
			data.validTime = validTime  + CommonLang.CUtils.localTimeMS;
			data.validTimes = (short)validTimes;
			this.mCardRateModule.AddChanges(data);
		}

		public override void OnSkillDataChange(GameSkill info)
		{
			for(int i = 0; i < mPlayerCardSkill.Length; i++)
			{
				CardSkillData data = mPlayerCardSkill[i];
				if(data != null && data.skillId == info.SkillID)
				{
					data.skilLv = (short)info.SkillLevel;
					break;
				}
			}
		}

		public override void ReloadCardSkillWeight()
        {
			int totalWeight = 0;
			String extInfo = "";
			for (int i = 0; i < (int)CardType.Max; i++)
			{
				CardSkillData data = mPlayerCardSkill[i];
				if (data != null)
				{
					totalWeight += this.mOwner.MirrorProp.cardWeight[i];
					data.setWeight(this.mOwner);

					extInfo = extInfo + ", " + this.mOwner.MirrorProp.cardWeight[i];
				}
			}

			String uniqueInfo = mOwner.mUnit.IsPlayer ? mOwner.mUnit.PlayerUUID : (mOwner.mUnit.Parent.GetSceneID() + "_" + mOwner.mInfo.ID);
			log.Info("卡牌权重信息:" + uniqueInfo + ", 总权重:" + totalWeight + ", " + extInfo);
			this.mIsFuncOpen = totalWeight > 0;
		}


		public override void OnInitOver(GameSkill info, IJSGCardSkill cardSkill)
		{
			for (int i = 0; i < mPlayerCardSkill.Length; i++)
			{
				CardSkillData data = mPlayerCardSkill[i];
				if (data != null && data.skillId/100000 == info.SkillID/100000)
				{					
					this.InitSkillData(mPlayerCardSkill[i], info, cardSkill);
					//if(info.TalentSkillLevel1 > 0 && !this.mIsFuncOpen)
					//{
					//	this.mIsFuncOpen = true;
					//}
					break;
				}
			}
		}

		//玩家增加一个球
		private void DoPlayerAddCard(GenCardData cardData, XmdsVirtual hitter, AttackSource source, CreateCardBallSource type)
		{
			if (!this.mOwner.DispatchTryGetCardBallEvent(this.mOwner, type, cardData.type))
			{
				return;
			}

			if (XmdsConfig.Instance.CARD_OPEN_TEST && XmdsConfig.Instance.CARD_GET_LIST.Count > 0)
			{
				CardType testCardType = XmdsConfig.Instance.CARD_GET_LIST[this.mCardListTestIndex];
				log.Warn("出牌调试,使用索引Id: " + this.mCardListTestIndex + ", " + cardData.type + " -> " + testCardType + " 数量:" + cardData.nums);
				cardData.type = testCardType;
				if ((++this.mCardListTestIndex) >= XmdsConfig.Instance.CARD_GET_LIST.Count) { this.mCardListTestIndex = 0; }
			}

#if JSG_CARD_TEST
			if (XmdsConfig.Instance.CARD_OPEN_TEST && XmdsConfig.Instance.CARD_GET_LIST.Count > 0)
			{
				CardType testCardType = XmdsConfig.Instance.CARD_GET_LIST[this.mCardListTestIndex];
				log.Warn("出牌调试,使用索引Id: " + this.mCardListTestIndex + ", " + cardData.type + " -> " + testCardType + " 数量:" + cardData.nums);
				cardData.type = testCardType;
				if ((++this.mCardListTestIndex) >= XmdsConfig.Instance.CARD_GET_LIST.Count) { this.mCardListTestIndex = 0; }
			}
			else
			{
				log.Warn("----DoPlayerAddCard: 获得卡牌: " + cardData.type + ", 数量: " + cardData.nums);
			}			
#endif

			CardTriggerResult result = mCardData.AddCard(this.mOwner, cardData);
			if (result == null)
			{				
				return;
			}
			//result.type = CardType.BaiHu;
			//result.sameNums = 3;
			CardSkillData triggerSkill = mPlayerCardSkill[(int)result.type];
			mCardData.SendTriggerInfo(this.mOwner, result, triggerSkill.skillId, result.cardData);

#if JSG_CARD_TEST
			log.Warn("----DoPlayerAddCard: 触发卡牌技能: " + result.type + ", 技能ID:" + triggerSkill.skillId + ", 球数:" + result.sameNums);
#endif

			//改成延时触发
			//triggerSkill.skill.TriggerCardSkill(this.mOwner, hitter, source, triggerSkill, result.sameNums);
			//this.mOwner.DispatchTriggerCardSkillEvent(this.mOwner, hitter, result.type, result.sameNums);

			base.mTriggerSkillDelay.init(triggerSkill.skill, this.mOwner, hitter, source, triggerSkill, result.sameNums);			

			//技能释放完成,记录上一次释放的卡牌信息
			this.mLastCardInfo.cardType = result.type;
			this.mLastCardInfo.time = CommonLang.CUtils.localTimeMS;
		}

		//重置当前强化效果
		public override void TriggerSkillLoadStrength(CardSkillData skillData, int sameNums)
		{
			this.mNextCardStrengthInfo.TriggerSkillLoadStrength(skillData, sameNums);
		}


		// 获得特殊效果强化加成
		public override IntIntData GetStrengthInfo(CardStrengthenType type)
		{
			return this.mNextCardStrengthInfo.GetStrengthInfo(type);
		}

		// 添加下一次强化效果
		public override NextCardStrengthenInfo AddNextStrengthInfo(CardType type, CardStrengthenType strenghType, int value1, int value2, int validTime, int validTimes = -1,
			byte needSames = 0, DamageType dmgType = DamageType.None, CardLayerRule layerRules = null)
		{
			return this.mNextCardStrengthInfo.AddStrength(type, strenghType, value1, value2, validTime, validTimes, needSames, dmgType, layerRules);
		}

		//上一次释放技能信息
		public override GetCardData GetLastCardData()
		{
			return this.mLastCardInfo;
		}
	}
}