using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Wizard;

public class AIEmoteMng
{
	private EnemyAI AI;

	private float _allyAdvOnTurnStart;

	private float _opponentAdvOnTurnStart;

	private int _allyLegionNumOnTurnStart;

	private float _allyAdvOnFirstAttack;

	private float _advOnBeforeSetCard;

	private int _opponentLifeOnBeforeSetCard;

	private int _opponentLifeOnBeforeAttack;

	private bool _isLastOpr_CardPlay;

	private float _playedCardValue;

	private float _allyAdvOnCardPlay;

	private bool _isFirstAttacked;

	private bool _isOpponentTurnEmoteOccured;

	private bool _isAIGreeted;

	private bool _isAIThanked;

	private readonly Stopwatch _stopwatch;

	private bool _isThinkingEmoteOccured;

	public Dictionary<int, int> EmoteCategoryPlayedCounter { get; private set; }

	public bool IsOpponentTurnEmoteOccured => _isOpponentTurnEmoteOccured;

	public Stopwatch Stopwatch => _stopwatch;

	public int EmoteRandomSeed { get; private set; }

	public AIEmoteMng(EnemyAI ai)
	{
		AI = ai;
		EmoteRandomSeed = new Random().Next();
		_stopwatch = new Stopwatch();
		_isAIGreeted = false;
		_isAIThanked = false;
		EmoteCategoryPlayedCounter = new Dictionary<int, int>();
	}

	public float EvalDisplacement_PlayedValue()
	{
		if (!_isLastOpr_CardPlay)
		{
			return 0f;
		}
		return AI.CalcFieldAdvantage() - (_allyAdvOnCardPlay + _playedCardValue);
	}

	public void ResetLastOpr()
	{
		_isLastOpr_CardPlay = false;
	}

	public void SetUpOnAllyTurnStart()
	{
		_isFirstAttacked = false;
		ResetLastOpr();
		AI.EmoteQuery.UpdateCategoryInterval();
		_stopwatch.Reset();
		_stopwatch.Start();
		_isThinkingEmoteOccured = false;
	}

	public void EvalFieldOnTurnStart()
	{
		_allyAdvOnTurnStart = AI.CalcFieldAdvantage();
		_allyLegionNumOnTurnStart = AI.ALLY.InPlayCards.Count((BattleCardBase c) => c.IsTribe(CardBasePrm.TribeType.LEGION));
	}

	public void EvalFieldOnOpponentTurnStart()
	{
		_opponentAdvOnTurnStart = AI.CalcFieldAdvantage();
	}

	public void EvalFieldOnAttack()
	{
		if (!_isFirstAttacked)
		{
			_allyAdvOnFirstAttack = AI.CalcFieldAdvantage();
			_isFirstAttacked = true;
		}
	}

	public void EvalFieldOnBeforeSetCard()
	{
		_advOnBeforeSetCard = AI.CalcFieldAdvantage();
		_opponentLifeOnBeforeSetCard = AI.OPPONENT.Class.Life;
	}

	public void EvalFieldOnBeforeAttack()
	{
		_opponentLifeOnBeforeAttack = AI.OPPONENT.Class.Life;
	}

	public void EvalAllyOnCardPlay(AIVirtualCard playCard, AISinglePlayptnRecord playptnRecord)
	{
		if (playptnRecord != null && playptnRecord.PlayPtn != null && playptnRecord.PlayPtn.Count > 0)
		{
			_isLastOpr_CardPlay = true;
			_allyAdvOnCardPlay = AI.CalcFieldAdvantage();
			AIVirtualTargetSelectAction play = new AIVirtualTargetSelectAction(playCard, playCard, AIOperationType.PLAY);
			_playedCardValue = AI.EnemyAIPlay.EvaluateHandValue(playCard, playptnRecord.PlayPtn, play, isOnBattleSimulate: false, playptnRecord);
		}
	}

	public void OnOpponentTurnEmote()
	{
		_isOpponentTurnEmoteOccured = true;
	}

	public void ResetOpponentTurnEmoteFlag()
	{
		_isOpponentTurnEmoteOccured = false;
	}

	public AIEmoteCmd OnAllyCardDestroy()
	{
		return null;
	}

	public bool IsReverseDisAdv()
	{
		if (_allyAdvOnTurnStart >= 0f)
		{
			return false;
		}
		return AI.CalcFieldAdvantage() >= 0f;
	}

	public bool IsOpponentEarnGreatMerit()
	{
		float num = AI.CalcFieldAdvantage();
		int ppTotal = AI.OPPONENT.PpTotal;
		return _opponentAdvOnTurnStart - num > (float)ppTotal * 2f;
	}

	public bool IsFailedReverseDisAdv()
	{
		if (_allyAdvOnTurnStart >= 0f)
		{
			return false;
		}
		return AI.CalcFieldAdvantage() < 0f;
	}

	public bool IsOpponentFailedReverseDisAdv()
	{
		if (_opponentAdvOnTurnStart <= 0f)
		{
			return false;
		}
		return AI.CalcFieldAdvantage() > 0f;
	}

	public bool IsRemainTooPP()
	{
		return AI.ALLY.Pp >= 2;
	}

	public bool IsOpponentRemainTooPP()
	{
		return AI.OPPONENT.Pp > AI.OPPONENT.PpTotal / 2;
	}

	public bool IsGiantPlayed()
	{
		float num = 10f;
		return AI.FieldInplayValueDifference >= num;
	}

	public bool IsEnoughUnit()
	{
		return AI.ALLY.InPlayCards.Count() >= 3;
	}

	public bool IsEnoughGrave()
	{
		return AI.ALLY.CemeteryList.Count >= 6;
	}

	public bool IsCheckmated()
	{
		int num = 0;
		foreach (BattleCardBase inPlayCard in AI.OPPONENT.InPlayCards)
		{
			if (inPlayCard.IsUnit)
			{
				num += inPlayCard.Atk;
			}
		}
		if (AI.OPPONENT.IsEvolve && AI.OPPONENT.InPlayCards.Any((BattleCardBase card) => card.IsUnit && !card.IsEvolution))
		{
			num += AI.OPPONENT.InPlayCards.Max((BattleCardBase card) => (!card.IsEvolution) ? (card.BaseParameter.EvoAtk - card.BaseParameter.Atk) : 0);
		}
		int num2 = 0;
		List<AIVirtualCard> bothClassAndInplayCards = AI.CurrentVirtualField.CardListSet.BothClassAndInplayCards;
		for (int num3 = 0; num3 < bothClassAndInplayCards.Count; num3++)
		{
			AIVirtualCard aIVirtualCard = bothClassAndInplayCards[num3];
			if (aIVirtualCard.TagCollectionContainer.HasTag(AIPlayTagType.TurnEndDamage))
			{
				num2 += aIVirtualCard.TagCollectionContainer.TurnEndTags.GetTurnEndDamageToAllyLeader(aIVirtualCard);
			}
		}
		return num + num2 >= AI.ALLY.Class.Life;
	}

	public bool IsHuntDown()
	{
		if (AI.OPPONENT.InPlayCards.Any((BattleCardBase c) => c.SkillApplyInformation.IsGuard))
		{
			return false;
		}
		int num = 0;
		foreach (BattleCardBase inPlayCard in AI.ALLY.InPlayCards)
		{
			if (inPlayCard.IsUnit)
			{
				num += inPlayCard.Atk;
			}
		}
		if (AI.ALLY.CurrentEpCount > 0)
		{
			num += 2;
		}
		return num >= AI.OPPONENT.Class.Life;
	}

	public bool IsEliminatedAllyLegion(AIVirtualCard destroyingCard)
	{
		if (_allyLegionNumOnTurnStart < 2)
		{
			return false;
		}
		if (AI.CurrentVirtualField.AllyInplayCards.Count((AIVirtualCard c) => c.IsTribe(CardBasePrm.TribeType.LEGION) && c.IsSameCard(destroyingCard)) > 0)
		{
			return false;
		}
		return true;
	}

	public bool IsAwaking(int turnOffset)
	{
		if (AI.ALLY.Pp + turnOffset == 7)
		{
			return true;
		}
		return false;
	}

	public bool IsUnexpectedBattle()
	{
		if (!_isFirstAttacked)
		{
			return false;
		}
		return AI.CalcFieldAdvantage() < _allyAdvOnFirstAttack;
	}

	public bool IsBanishOverExpected(BattleCardBase actCard, AIVirtualField fieldAfterPlayed)
	{
		if (!actCard.IsSpell)
		{
			return false;
		}
		float num = (float)actCard.Cost * 2f + 4f;
		float num2 = AI.ParamQuery.EvaluateBattlePlayerPair(AI.CurrentVirtualField);
		if (AI.ParamQuery.EvaluateBattlePlayerPair(fieldAfterPlayed) - num2 >= num)
		{
			return true;
		}
		return false;
	}

	public bool IsOpponentBanishSplendid(AIVirtualCard actCard)
	{
		if (actCard.IsAlly)
		{
			return false;
		}
		float num = (float)actCard.Cost * 2f + 4f;
		float num2 = AI.CalcFieldAdvantage();
		if (_advOnBeforeSetCard - num2 >= num)
		{
			return true;
		}
		return false;
	}

	public bool IsOpponentBanishBad(AIVirtualCard actCard)
	{
		if (actCard.IsAlly)
		{
			return false;
		}
		float num = actCard.Cost;
		float num2 = AI.CalcFieldAdvantage();
		if (_advOnBeforeSetCard - num2 < num)
		{
			return true;
		}
		return false;
	}

	public bool IsOpponentHealClassLifeLargeOnCardPlay()
	{
		int num = 4;
		if (AI.OPPONENT.Class.Life - _opponentLifeOnBeforeSetCard >= num)
		{
			return true;
		}
		return false;
	}

	public bool IsOpponentHealClassLifeLargeOnAttack()
	{
		int num = 4;
		if (AI.OPPONENT.Class.Life - _opponentLifeOnBeforeAttack >= num)
		{
			return true;
		}
		return false;
	}

	public bool IsThinkingLong()
	{
		float num = 20000f;
		if (!_isThinkingEmoteOccured)
		{
			return (float)_stopwatch.ElapsedMilliseconds > num;
		}
		return false;
	}

	public void OnThinkingEmote()
	{
		_isThinkingEmoteOccured = true;
		_stopwatch.Reset();
	}

	public void OnOperationRequest()
	{
		if (!_isThinkingEmoteOccured)
		{
			_stopwatch.Reset();
			_stopwatch.Start();
		}
	}

	public bool IsReplyAllowed(ClassCharaPrm.EmotionType emoteType, ref ClassCharaPrm.EmotionType replyEmote)
	{
		switch (emoteType)
		{
		case ClassCharaPrm.EmotionType.GREET:
			if (_isAIGreeted)
			{
				return false;
			}
			replyEmote = ClassCharaPrm.EmotionType.GREET;
			_isAIGreeted = true;
			return true;
		case ClassCharaPrm.EmotionType.THANK:
			if (_isAIThanked)
			{
				return false;
			}
			replyEmote = ClassCharaPrm.EmotionType.THANK;
			_isAIThanked = true;
			return true;
		default:
			return false;
		}
	}

	public void AddPlayedCountOnEmotePlaying(int category)
	{
		if (EmoteCategoryPlayedCounter.ContainsKey(category))
		{
			EmoteCategoryPlayedCounter[category]++;
		}
		else
		{
			EmoteCategoryPlayedCounter.Add(category, 1);
		}
	}

	public int GetEmotePlayCount(int category)
	{
		if (EmoteCategoryPlayedCounter.ContainsKey(category))
		{
			return EmoteCategoryPlayedCounter[category];
		}
		return 0;
	}
}
