using System;
using System.Collections.Generic;
using UnityEngine;
using Wizard.Battle;
using Wizard.Battle.Phase;
using Wizard.Battle.Recovery;
using Wizard.Battle.View.Vfx;
using Wizard.BattleMgr;

namespace Wizard;

public class AINetworkBattleManager : NetworkBattleManagerBase
{
	private AITurnControl _aiTurnControl;

	private Func<VfxBase> _turnTransitionFunc;

	private VfxBase _initiateGameEndFunc;

	private bool _sendFinshBattleTask;

	private bool _isWin;

	public AIBattleInfoReceiver BattleInfoReceiver { get; protected set; }

	public AINetworkBattleManager(IBattleMgrContentsCreator contentsCreator)
		: base(contentsCreator)
	{
		_turnTransitionFunc = null;
	}

	protected override void NetworkBattleManagerSetup()
	{
		DataMgr dataMgr = GameMgr.GetIns().GetDataMgr();
		dataMgr.SetDeckMaxCount(40, isSelf: true);
		dataMgr.SetDeckMaxCount(40, isSelf: false);
		IsShowDisconnectPanel = false;
		IsShowOpponentDisconnectPanel = false;
		NotReplaceCardList = new List<ReplaceReceivedCard.CardIdAndIndex>();
		base.validateSkillIndexList = new List<ValidateSkillData>();
		RegisterActionManager = new RegisterActionManager(this);
		base.RegisterUnapprovedList = new List<RegisterUnapproved>();
		base.registerSelectTypeSkillIndexList = new List<int>();
		sendKeyActionDataManager = new SendKeyActionDataManager();
		TouchControl = new NetworkTouchControl(this, _battleCamera, _backGround);
		networkTouchControl = TouchControl as NetworkTouchControl;
		JudgeResultReceiveCode = NetworkBattleReceiver.RESULT_CODE.NotFinish;
		if (base.IsRecovery || GameMgr.GetIns().IsReplayBattle)
		{
			networkTouchControl.SetDisableTouch();
			base.networkBattleData = new NetworkRecoveryBattleData(this);
			networkReceiver = new NetworkReplayBattleReceiver(this);
			OperateReceive = new RecoveryOperateReceive(this, RegisterActionManager, OperateMgr, base.networkBattleData);
			int selfIdxSeed = (base.IsRecovery ? _contentsCreator.RecoveryManager.IdxChangeSeed : Data.ReplayBattleInfo.IdxChangeSeed);
			int oppIdxSeed = (GameMgr.GetIns().IsReplayBattle ? Data.ReplayBattleInfo.OppoIdxChangeSeed : (-1));
			CreateXorShift(selfIdxSeed, oppIdxSeed);
			BattleEnemy.EnableEnemyAI = false;
		}
		else
		{
			base.networkBattleData = new NetworkBattleData(this);
			networkReceiver = new NetworkBattleReceiver(this);
			OperateReceive = new OperateReceive(this, RegisterActionManager, OperateMgr, base.networkBattleData);
		}
		OperateMgr.SetTouchControl(TouchControl);
		networkConsistency = new NetworkConsistency(this);
		_networkBattleSetupCardEventBase = new NetworkAIBattleSetupCardEvent(this, RegisterActionManager, base.networkBattleData);
		operateReceiveChecker = new OperateReceiveChecker(this, base.networkBattleData);
		_intervalCheckList = new List<NetworkBattleIntervalCheckerBase>();
		base.opponentRecoveryToDispChecker = new OpponentRecoveryToDispChecker();
		base.disconnectToDispChecker = new DisconnectToDispChecker();
		_intervalCheckList.Add(base.disconnectToDispChecker);
		base.disconnectToLoseChecker = new DisconnectToLoseChecker();
		base.disconnectToLoseChecker.OnDisconnectLose += delegate
		{
			DisconnectLose();
		};
		base.disconnectToLoseChecker.OnBeforeDisconnectLose += delegate
		{
			BeforeDisconnectLose();
		};
		_intervalCheckList.Add(base.disconnectToLoseChecker);
		base.notMulliganEndToJudgeChecker = new NullNotMulliganEndToJudgeChecker();
		base.notTurnEndToLoseChecker = new NullNotTurnEndToLoseChecker(this);
		base.receiveTurnEndToJudgeResult = new NullReceiveTurnEndToJudgeResult();
		_intervalCheckList.Add(base.notTurnEndToLoseChecker);
		base.notTurnStartToLoseChecker = new NullNotTurnStartToLoseChecker();
		_intervalCheckList.Add(base.notTurnStartToLoseChecker);
		SendIntervalTriggerMain = new AISendIntervalTrigger();
		base.NetworkSender = new NetworkBattleSender(this, RegisterActionManager, base.RegisterUnapprovedList, networkConsistency);
		_aiTurnControl = new AITurnControl();
		if (!base.IsRecovery)
		{
			SettingOpponentAliveEvent();
			IsStopIntervalCheck = false;
			ToolboxGame.RealTimeNetworkAgent.StartPreparedStartTimer(DateTime.Now);
			ToolboxGame.RealTimeNetworkAgent.StartRecoveryRecording();
		}
	}

	protected override void DisconnectLose()
	{
		JudgeErrorDialog(isError: false);
	}

	public override VfxBase ChangePhase(IPhase phase)
	{
		if (phase is NetworkMulliganPhase || (phase is MainPhase && base.IsRecovery))
		{
			base.notMulliganEndToJudgeChecker.StartChecker();
			base.disconnectToDispChecker.OnDisp += delegate
			{
				ControlDisconnectOffTouchAndView(flag: true);
			};
			base.disconnectToDispChecker.OnErase += delegate
			{
				ControlDisconnectOffTouchAndView(flag: false);
			};
		}
		if (phase is OpeningPhase)
		{
			ConnectionReportTrigger.ConnectionReport(this);
		}
		return base.ChangePhase(phase);
	}

	public override void Update(float dt)
	{
		base.Update(dt);
		if (_turnTransitionFunc != null && ToolboxGame.RealTimeNetworkAgent != null && ToolboxGame.RealTimeNetworkAgent.PlayerNetworkStatus.IsAlive)
		{
			base.VfxMgr.RegisterSequentialVfx(_turnTransitionFunc.GetAllFuncVfxResults());
			_turnTransitionFunc = null;
		}
		if (_initiateGameEndFunc != null && ToolboxGame.RealTimeNetworkAgent != null && ToolboxGame.RealTimeNetworkAgent.PlayerNetworkStatus.IsAlive)
		{
			base.VfxMgr.RegisterSequentialVfx(_initiateGameEndFunc);
			_initiateGameEndFunc = null;
		}
		if (ToolboxGame.RealTimeNetworkAgent != null && _turnTransitionFunc == null && !IsBattleEnd && BattleEnemy.IsSelfTurn)
		{
			_aiTurnControl.Update(EnemyAI);
		}
	}

	public override void SetupBattlePlayersEvent()
	{
		BattlePlayer.OnSetupCardEvent += SetupCardEvent;
		BattleEnemy.OnSetupCardEvent += SetupCardEvent;
		BattlePlayer.OnSetupClassEvent += SetupPlayerClassEvent;
		BattleEnemy.OnSetupClassEvent += SetupOpponentClassEvent;
		BattlePlayer.Setup(BattleEnemy);
		BattleEnemy.Setup(BattlePlayer);
		BattlePlayer.OnTurnEnd += delegate
		{
			base.VfxMgr.Cancel();
			return NullVfx.GetInstance();
		};
	}

	protected override void SetupNetworkEvent(bool isRecovery)
	{
		BattlePlayer.OnPlayerActive += delegate
		{
			if (turnEndTimeController != null)
			{
				turnEndTimeController.StartCountDown("AIOnPlayerActive");
			}
		};
		BattlePlayer battlePlayer = BattlePlayer;
		battlePlayer.OnPostTurnEndComplete = (Action)Delegate.Combine(battlePlayer.OnPostTurnEndComplete, (Action)delegate
		{
			if (turnEndTimeController != null)
			{
				turnEndTimeController.EndCountDown("AIOnTurnEndComplete");
			}
			SendTurnEndAction();
		});
		BattleEnemy.OnTurnStartBeforeDraw += delegate
		{
			if (!IsVirtualBattle)
			{
				_aiTurnControl.StartTurnTimer();
			}
			return NullVfx.GetInstance();
		};
		BattleEnemy battleEnemy = BattleEnemy;
		battleEnemy.OnPostTurnEndComplete = (Action)Delegate.Combine(battleEnemy.OnPostTurnEndComplete, (Action)delegate
		{
			if (!IsVirtualBattle)
			{
				_aiTurnControl.StopTurnTimer();
			}
		});
	}

	public override void InitiateGameEndSequence(bool hasWon)
	{
		if (ToolboxGame.RealTimeNetworkAgent != null && ToolboxGame.RealTimeNetworkAgent.PlayerNetworkStatus.IsAlive)
		{
			if (!_sendFinshBattleTask)
			{
				_sendFinshBattleTask = true;
				_isWin = hasWon;
				BattleFinishToEffectClear();
				BattleFinishToStopIntervalChecker();
				ToolboxGame.RealTimeNetworkAgent.FinishBattleTask(this);
			}
		}
		else
		{
			_initiateGameEndFunc = InstantVfx.Create(delegate
			{
				InitiateGameEndSequence(hasWon);
			});
		}
	}

	public override void FinishBattleEffect(bool classDead)
	{
		classDead = !_isWin;
		if (classDead)
		{
			BattleCardBase battleCardBase = GetBattlePlayer(classDead).Class;
			if (battleCardBase.Life >= 1 && !battleCardBase.IsDead)
			{
				battleCardBase.FlagCardAsDestroyedByKiller();
				FINISH_TYPE finishTypeByStatus = GetFinishTypeByStatus();
				base.VfxMgr.RegisterSequentialVfx(DeadClass(classDead, finishTypeByStatus));
			}
		}
		base.VfxMgr.RegisterSequentialVfx(InstantVfx.Create(delegate
		{
			base.InitiateGameEndSequence(!classDead);
		}));
	}

	public override VfxBase JudgeBattleResult()
	{
		if (BattlePlayer.Class.IsDead && BattleEnemy.Class.IsDead)
		{
			return InstantVfx.Create(delegate
			{
				InitiateGameEndSequence(!BattlePlayer.IsSelfTurn);
			});
		}
		if (BattlePlayer.Class.IsDead)
		{
			return InstantVfx.Create(delegate
			{
				InitiateGameEndSequence(hasWon: false);
			});
		}
		if (BattleEnemy.Class.IsDead)
		{
			return InstantVfx.Create(delegate
			{
				InitiateGameEndSequence(hasWon: true);
			});
		}
		return NullVfx.GetInstance();
	}

	protected override void SetupEvent()
	{
		base.SetupEvent();
		BattlePlayer.OnShortageDeck += () => OnShortageDeck(BattlePlayer);
		BattleEnemy.OnShortageDeck += () => OnShortageDeck(BattleEnemy);
		SetUpTurnTransitionEvent();
	}

	private void SetUpTurnTransitionEvent()
	{
		BattlePlayer.OnTurnEndFinish += delegate
		{
			if (IsVirtualBattle || base.IsRecovery)
			{
				return NullVfx.GetInstance();
			}
			_turnTransitionFunc = null;
			_turnTransitionFunc = (Func<VfxBase>)Delegate.Combine(_turnTransitionFunc, new Func<VfxBase>(base.ControlTurnStartOpponent));
			return NullVfx.GetInstance();
		};
		BattleEnemy.OnTurnEndFinish += delegate
		{
			if (IsVirtualBattle || base.IsRecovery)
			{
				return NullVfx.GetInstance();
			}
			_turnTransitionFunc = null;
			_turnTransitionFunc = (Func<VfxBase>)Delegate.Combine(_turnTransitionFunc, new Func<VfxBase>(base.ControlTurnStartPlayer));
			return NullVfx.GetInstance();
		};
	}

	protected override void SetupBattlePlayerRegisterEvents(BattlePlayerBase battlePlayer)
	{
	}

	protected override void SetupNetworkActionProcessorEvent(ActionProcessor processor, bool isPlayer)
	{
	}

	public override void SetupFieldAndHandAfterRecovery(Action onEndRecoveryCallback, RecoveryOperationInfo aiBattleRecoveryData = null)
	{
		if (aiBattleRecoveryData.SetupInfo.HasMulliganInfo)
		{
			BattlePlayer.PlayerBattleView.ClearPlayQueue();
			BattleEnemy.BattleEnemyView.ClearPlayQueue();
			RecreateCardViews(BattlePlayer.InPlayCards);
			RecreateCardViews(BattlePlayer.HandCardList);
			RecreateCardViews(BattlePlayer.DeckCardList);
			RecreateCardViews(BattlePlayer.ReservedCardList);
			RecreateCardViews(BattleEnemy.InPlayCards);
			RecreateCardViews(BattleEnemy.HandCardList);
			RecreateCardViews(BattleEnemy.DeckCardList);
			RecreateCardViews(BattleEnemy.ReservedCardList);
			RefreshHealthVfx refreshHealthVfx = new RefreshHealthVfx(BattlePlayer);
			RefreshHealthVfx refreshHealthVfx2 = new RefreshHealthVfx(BattleEnemy);
			ParallelVfxPlayer parallelVfxPlayer = ParallelVfxPlayer.Create(BattlePlayer.BattleView.Recovery(doseFirst: false), BattleEnemy.BattleView.Recovery(doseFirst: false), refreshHealthVfx, refreshHealthVfx2);
			VfxBase vfxBase = (BattleEnemy.IsSelfTurn ? BattleEnemy.CreateThinkingVfx(this) : NullVfx.GetInstance());
			SequentialVfxPlayer vfx = SequentialVfxPlayer.Create(RecoveryAfterMulliganPhase.RestoreUI(this), parallelVfxPlayer, HandViewBase.CreateHideCardMeshesVfx(BattleEnemy.HandCardList), vfxBase, InstantVfx.Create(delegate
			{
				ResetLeaderAnimation(BattlePlayer, BattleEnemy);
			}));
			base.VfxMgr.RegisterSequentialVfx(vfx);
		}
	}

	public override void RecoveryEnd()
	{
		base.IsRecovery = false;
		SettingOpponentAliveEvent();
		IsStopIntervalCheck = false;
		SetUpTurnTransitionEvent();
		networkTouchControl.SetEnableTouch();
		NetworkBattleData networkBattleData = base.networkBattleData;
		base.networkBattleData = new NetworkBattleData(this);
		base.networkBattleData.isPlayerMulliganEnd = networkBattleData.isPlayerMulliganEnd;
		base.networkBattleData.isOppoMulliganEnd = networkBattleData.isOppoMulliganEnd;
		base.networkBattleData.SetReceiveData(networkBattleData.GetReceiveData());
		base.networkBattleData.isEnemyFirstTurn = networkBattleData.isEnemyFirstTurn;
		_networkBattleSetupCardEventBase.OverwriteNetworkBattleData(base.networkBattleData);
		SetupCreateBattleCardFunc(createCardWithoutGameObject: false);
		OperateMgr operateMgr = OperateMgr;
		OperateMgr = CreateOperateMgr();
		OperateMgr.SetUpRecoveryEvent(operateMgr);
		StartRecoveryRecording();
		operateMgr = null;
		OperateReceive = new OperateReceive(this, RegisterActionManager, OperateMgr, base.networkBattleData);
		if (_phase is NetworkMulliganPhase)
		{
			(_phase as NetworkMulliganPhase).MulliganEventSetting();
		}
		operateReceiveChecker = new OperateReceiveChecker(this, base.networkBattleData);
		networkReceiver = new NetworkBattleReceiver(this);
		SetupNetworkEvent(isRecovery: true);
		if (_specialWinVfx == null)
		{
			ClearRegisterCardList();
		}
		BattleEnemy.EnableEnemyAI = true;
		BattlePlayer.Emotion.Enable = true;
		BattleEnemy.Emotion.Enable = true;
		if (BattleEnemy.IsSelfTurn)
		{
			EnemyAI.StopEnemyAI();
			EnemyAI.ExecuteEnemyAI(useWait: true);
		}
		ConnectionReportTrigger.ConnectionReport(this);
	}

	protected override void FirstRecoverySetting()
	{
		if (!base.IsRecovery)
		{
			StartRecoveryRecording();
		}
	}

	protected override int CreateBackgroundId()
	{
		if (_contentsCreator is RecoveryNetworkBattleMgrContentsCreator)
		{
			int backGroundId = ((RecoveryNetworkBattleMgrContentsCreator)_contentsCreator).RecoveryControllerInstance.AIBattleRecoveryData.SetupInfo.BackGroundId;
			if (backGroundId >= 0)
			{
				return backGroundId;
			}
		}
		return CalculationRandomStage();
	}

	public override void FinishBattle()
	{
		EnemyAI.StopEnemyAI();
	}

	public override void RecoveryTimeOutSetting(float extendTime, bool isMulliganEnd, long startTime = -1L)
	{
		if (!isMulliganEnd)
		{
			if (MulliganMgr != null)
			{
				MulliganMgr.GetMulliganInfo().SetExtendTime(extendTime);
			}
			return;
		}
		if (!BattlePlayer.IsSelfTurn)
		{
			if (startTime != -1)
			{
				_aiTurnControl.SetAndStartTurnTimer(DateTimeOffset.FromUnixTimeSeconds(startTime).LocalDateTime);
			}
			return;
		}
		if (turnEndTimeController == null)
		{
			TurnEndButtonUI component = SBattleLoad.m_TurnEndBtnUI.GetComponent<TurnEndButtonUI>();
			turnEndTimeController = new TurnEndTimeController(this, BattlePlayer, component);
		}
		if (!turnEndTimeController.IsCountdownRunning())
		{
			turnEndTimeController.StartCountDown("SetTimeoutSetting");
		}
		turnEndTimeController.SetExtendTime(extendTime);
	}

	public void SetupMulliganLaunchCompleteEvent()
	{
		_contentsCreator.RecoveryRecordManager.SetupMulliganStartTimeRecorderEvent(this);
	}

	public override VfxBase StartBattle()
	{
		SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create();
		LocalLog.SetLastTraceLogTurn(1);
		sequentialVfxPlayer.Register(ChangePhase(base.PhaseCreator.CreateMainPhase()));
		if (IsFirst)
		{
			sequentialVfxPlayer.Register(BattlePlayer.StartTurnControl("AIFirst"));
		}
		else
		{
			sequentialVfxPlayer.Register(BattleEnemy.StartTurnControl());
		}
		return sequentialVfxPlayer;
	}

	public override void SetupEnemyAI()
	{
		EnemyAI enemyAI = new RankMatchEnemyAI();
		enemyAI.LoadBufferedBattleState();
		EnemyAI = enemyAI;
		BattleInfoReceiver = new AIBattleInfoReceiver(EnemyAI);
		EnemyAI.InitOnGame(BattleEnemy, BattlePlayer);
		if (!base.IsRecovery)
		{
			BattleEnemy.EnableEnemyAI = true;
		}
	}

	public override BattleCardBase MetamorphoseCard(int cardId, bool isPlayer, int addIndex, SkillBase skill, bool isFusion = false)
	{
		return CreateBattleCardWithGameObject(new CardCreateInfo(cardId, isPlayer, skill.ApplyingTargetFilter is SkillTargetChosenCardsFilter, NetworkBattleDefine.NetworkCardPlaceState.None, isReferenceOpponentCard: false, skill), new IndexInfo(addIndex));
	}

	public override BattleCardBase CreateBattleCardWithGameObject(CardCreateInfo info, IndexInfo indexInfo, int repeatCount = -1, bool isVirtual = false, bool isActualCard = false)
	{
		CardParameter cardParameterFromId = CardMaster.GetInstanceForBattle().GetCardParameterFromId(info.Id);
		BattlePlayerBase battlePlayer = GetBattlePlayer(info.IsPlayer);
		int cardIndex = SetupCardIndex(battlePlayer, indexInfo.AddIndex);
		GameObject cardGameObject = null;
		if (!base.IsRecovery || !isVirtual)
		{
			cardGameObject = CreateBaseCardGameObject(cardParameterFromId, info.IsPlayer, cardIndex);
		}
		BattleCardBase battleCardBase = CreateBattleCard(info.Id, info.IsPlayer, cardGameObject, cardParameterFromId, battlePlayer, cardIndex);
		if (!base.IsRecovery || !isVirtual)
		{
			SetupCardObjectMaterials(cardGameObject, battleCardBase);
		}
		return battleCardBase;
	}

	protected override void ControlDisconnectOffTouchAndView(bool flag)
	{
		if (!_sendFinshBattleTask)
		{
			base.ControlDisconnectOffTouchAndView(flag);
		}
	}

	public override void PlayRetire()
	{
		if (RecoveryRecordManagerBase.IsExistsAINetworkRecoveryFile())
		{
			GameMgr.GetIns().GetDataMgr().SetRecoveryData(RecoveryOperationInfo.ReadRecoveryFile(OperationRecorderBase.RecordDirectoryPath + "recovery_ai_network.json"));
			RecoveryRecordManagerBase.DeleteRecoveryFile();
		}
		base.PlayRetire();
	}
}
