MainHud/BlackjackEventRunner.cs
using Keyboard_Warriors_.Models;
using Keyboard_Warriors_.Systems;
using Sandbox;
using System;

namespace Keyboard_Warriors_.Managers;

public static class BlackjackEventRunner
{
	private static Player cachedPlayer;
	private static Player cachedAI;
	private static int secretAITotal;

	// =========================================================================
	// 🌐 MULTIPLAYER NETWORK HAND REGISTERS
	// =========================================================================
	private static int p1HandTotal = 0;
	private static int p2HandTotal = 0;
	private static bool isPlayerOneFinished = false;
	private static bool isPlayerTwoFinished = false;
	private static bool isMatchResolved = false;
	// =========================================================================

	private static int DrawCard() => Random.Shared.Next( 1, 12 );

	private static GameManager GetManager()
	{
		return Sandbox.Game.ActiveScene?.Get<GameManager>();
	}

	public static void StartEvent( Player player, Player ai )
	{
		var manager = GetManager();
		if ( manager == null ) return;

		bool isMultiplayer = manager.CurrentMode == GameManager.PlayMode.Multiplayer;

		cachedPlayer = player;
		cachedAI = ai;

		if ( isMultiplayer )
		{
			GameManager.AddLog( "** A symmetrical game of CYBER BLACKJACK begins! **" );

			// Reset and deal clean initial two-card packet totals for both humans
			p1HandTotal = DrawCard() + DrawCard();
			p2HandTotal = DrawCard() + DrawCard();

			isPlayerOneFinished = false;
			isPlayerTwoFinished = false;
			isMatchResolved = false;

			GameManager.AddLog( $"📡 [NET] Deal packets complete. {cachedPlayer.name} is up first to configure their array!" );

			// Player 1 (Host) starts the hit/stand cycle first
			RunMultiplayerLoop( true );
		}
		else
		{
			// 🤖 SINGLE PLAYER MODE: Your exact original un-edited career loop setup
			GameManager.AddLog( "** A game of BLACKJACK begins! **" );

			int currentScalePlayerTotal = DrawCard() + DrawCard();
			secretAITotal = DrawCard() + DrawCard();

			GameManager.AddLog( $"You are dealt cards totaling: {currentScalePlayerTotal}" );
			GameManager.AddLog( $"AI is showing: {secretAITotal / 2} (one card hidden)" );
			GameManager.AddLog( "⚠️ AWAITING HIT/STAND PROTOCOL CHOICE..." );

			RunBlackjackTurnLoop( currentScalePlayerTotal );
		}
	}

	// =========================================================================
	// 👥 MULTIPLAYER SEQUENTIAL HIT/STAND TURN MATRIX
	// =========================================================================
	private static void RunMultiplayerLoop( bool isPlayerOneActive )
	{
		var manager = GetManager();
		if ( manager == null ) return;

		int currentHandTotal = isPlayerOneActive ? p1HandTotal : p2HandTotal;
		string activeName = isPlayerOneActive ? cachedPlayer.name : cachedAI.name;

		// Immediate bust gating if an additional card packet overclocks the 21 threshold
		if ( currentHandTotal > 21 )
		{
			GameManager.AddLog( $"💥 {activeName} total: {currentHandTotal} - BUSTED!" );
			if ( isPlayerOneActive ) isPlayerOneFinished = true;
			else isPlayerTwoFinished = true;

			AdvanceMultiplayerTurnPhase( isPlayerOneActive );
			return;
		}

		// Immediate baseline lock if they hit an un-bustable natural 21 metric
		if ( currentHandTotal == 21 )
		{
			GameManager.AddLog( $"🃏 {activeName} hit a perfect 21 structural stack!" );
			if ( isPlayerOneActive ) isPlayerOneFinished = true;
			else isPlayerTwoFinished = true;

			AdvanceMultiplayerTurnPhase( isPlayerOneActive );
			return;
		}

		// Enforce local display screens correctly based on machine connection identity tokens
		bool shouldDrawPopup = (isPlayerOneActive && Networking.IsHost) || (!isPlayerOneActive && !Networking.IsHost);

		if ( shouldDrawPopup )
		{
			var blackjackEvent = new ChoiceEvent
			{
				Title = "🃏 CYBER BLACKJACK EMULATION",
				PromptText = $"Your current card array value sits at: {currentHandTotal}. Will you request an additional data card packet (HIT) or lock this calculation down (STAND)?",
			};

			blackjackEvent.Options.Add( new EventOption
			{
				ButtonText = "➕ REQUEST CARD (HIT)",
				ActionToExecute = async () =>
				{
					int freshCard = DrawCard();
					if ( isPlayerOneActive ) p1HandTotal += freshCard;
					else p2HandTotal += freshCard;

					GameManager.AddLog( $"🃏 {activeName} draws a {freshCard}. Total: {currentHandTotal + freshCard}" );
					await GameTask.Delay( 50 );

					RunMultiplayerLoop( isPlayerOneActive );
				}
			} );

			blackjackEvent.Options.Add( new EventOption
			{
				ButtonText = "🔒 STAND WITH TOTAL",
				ActionToExecute = () =>
				{
					GameManager.AddLog( $"🔒 {activeName} stands with a solid total of {currentHandTotal}." );
					if ( isPlayerOneActive ) isPlayerOneFinished = true;
					else isPlayerTwoFinished = true;

					AdvanceMultiplayerTurnPhase( isPlayerOneActive );
				}
			} );

			manager.TriggerChoicePopup( blackjackEvent );
		}
		else
		{
			// Clean text tracker overlay updates for the player currently waiting
			if ( manager.IsChoiceEventActive ) manager.IsChoiceEventActive = false;
			GameManager.AddLog( $"⏳ Waiting for {activeName} to finish executing their card configuration loop..." );
		}
	}

	private static void AdvanceMultiplayerTurnPhase( bool wasPlayerOneActive )
	{
		var manager = GetManager();
		if ( wasPlayerOneActive && !isPlayerTwoFinished )
		{
			// Player 1 finished their choices -> dynamically unlock Player 2's prompt screen
			RunMultiplayerLoop( false );
		}
		else if ( isPlayerOneFinished && isPlayerTwoFinished && !isMatchResolved )
		{
			isMatchResolved = true;

			GameManager.AddLog( $"\n📊 [BLACKJACK REVELATION MATRIX]" );
			GameManager.AddLog( $"➡️ {cachedPlayer.name} Final Total: {p1HandTotal} | {cachedAI.name} Final Total: {p2HandTotal}" );

			// Evaluate competitive baseline rules side-by-side
			if ( p1HandTotal > 21 && p2HandTotal > 21 )
			{
				GameManager.AddLog( "🤝 BOTH PLAYERS BUSTED! Symmetrical data wipe: -10 HP each." );
				CombatManager.applyDamage( ref cachedPlayer, 10 );
				CombatManager.applyDamage( ref cachedAI, 10 );
			}
			else if ( p1HandTotal > 21 )
			{
				GameManager.AddLog( $"🏆 {cachedAI.name} WINS! {cachedPlayer.name} busted. -25 HP to {cachedPlayer.name}!" );
				CombatManager.applyDamage( ref cachedPlayer, 25 );
			}
			else if ( p2HandTotal > 21 )
			{
				GameManager.AddLog( $"🏆 {cachedPlayer.name} WINS! {cachedAI.name} busted. -25 HP to {cachedAI.name}!" );
				CombatManager.applyDamage( ref cachedAI, 25 );
			}
			else if ( p1HandTotal > p2HandTotal )
			{
				int dmg = (p1HandTotal == 21) ? 40 : 25;
				string winMsg = (p1HandTotal == 21) ? $"🏆 {cachedPlayer.name} LANDS NATURAL BLACKJACK!" : $"🏆 {cachedPlayer.name} out-calculated the array!";
				GameManager.AddLog( $"{winMsg} {cachedAI.name} suffers -{dmg} HP!" );
				CombatManager.applyDamage( ref cachedAI, dmg );
			}
			else if ( p2HandTotal > p1HandTotal )
			{
				int dmg = (p2HandTotal == 21) ? 40 : 25;
				string winMsg = (p2HandTotal == 21) ? $"🏆 {cachedAI.name} LANDS NATURAL BLACKJACK!" : $"🏆 {cachedAI.name} out-calculated the array!";
				GameManager.AddLog( $"{winMsg} {cachedPlayer.name} suffers -{dmg} HP!" );
				CombatManager.applyDamage( ref cachedPlayer, dmg );
			}
			else
			{
				GameManager.AddLog( $"🤝 Absolute deadlock tie score! Both lose -10 HP." );
				CombatManager.applyDamage( ref cachedPlayer, 10 );
				CombatManager.applyDamage( ref cachedAI, 10 );
			}

			GameManager.AddLog( $"{cachedPlayer.name} | HP: {cachedPlayer.hp} | Armor: {cachedPlayer.defense}" );
			GameManager.AddLog( $"{cachedAI.name} | HP: {cachedAI.hp} | Armor: {cachedAI.defense}" );

			if ( manager != null ) manager.IsChoiceEventActive = false;
		}
	}
	// =========================================================================

	private static void RunBlackjackTurnLoop( int runningPlayerTotal )
	{
		var manager = Sandbox.Game.ActiveScene?.Get<GameManager>();
		int prestige = manager != null ? manager.CurrentPrestige : 0;
		int scaledWinDamage = 25 + (prestige * 3);

		if ( runningPlayerTotal > 21 )
		{
			GameManager.AddLog( $"** Total: {runningPlayerTotal} - You BUST! AI wins automatically. -{scaledWinDamage} HP. **" );
			CombatManager.applyDamage( ref cachedPlayer, scaledWinDamage );
			GameManager.AddLog( $"{cachedPlayer.name} | HP: {cachedPlayer.hp} | Armor: {cachedPlayer.defense}" );
			return;
		}

		var blackjackEvent = new ChoiceEvent
		{
			Title = "🃏 CYBER BLACKJACK EMULATION",
			PromptText = $"Your current hand value sits at: {runningPlayerTotal}. The AI is presenting a split risk window. Will you request an additional card packet or lock this calculation down?",
		};

		blackjackEvent.Options.Add( new EventOption
		{
			ButtonText = "➕ REQUEST CARD (HIT)",
			ActionToExecute = async () =>
			{
				int freshCard = DrawCard();
				int updatedTotal = runningPlayerTotal + freshCard;
				GameManager.AddLog( $"You draw a {freshCard}. Total: {updatedTotal}" );

				await GameTask.Delay( 50 );
				RunBlackjackTurnLoop( updatedTotal );
			}
		} );

		blackjackEvent.Options.Add( new EventOption
		{
			ButtonText = "🔒 STAND WITH TOTAL",
			ActionToExecute = () =>
			{
				ResolveDealerAndMatch( runningPlayerTotal );
			}
		} );

		GameManager.Instance.TriggerChoicePopup( blackjackEvent );
	}

	private static void ResolveDealerAndMatch( int finalPlayerTotal )
	{
		var manager = Sandbox.Game.ActiveScene?.Get<GameManager>();
		int prestige = manager != null ? manager.CurrentPrestige : 0;

		int scaledBlackjackDamage = 40 + (prestige * 5);
		int scaledWinDamage = 25 + (prestige * 3);
		int scaledTieDamage = 10 + (prestige * 2);

		if ( finalPlayerTotal == 21 )
		{
			GameManager.AddLog( $"** BLACKJACK!! AI loses -{scaledBlackjackDamage} HP! **" );
			CombatManager.applyDamage( ref cachedAI, scaledBlackjackDamage );
			return;
		}

		GameManager.AddLog( $"You stand with {finalPlayerTotal}." );
		GameManager.AddLog( $"AI reveals hidden total: {secretAITotal}" );

		int aiRunningTotal = secretAITotal;
		while ( aiRunningTotal < 17 )
		{
			int card = DrawCard();
			aiRunningTotal += card;
			GameManager.AddLog( $"AI draws a {card}. Total: {aiRunningTotal}" );
		}

		if ( aiRunningTotal == 21 )
		{
			GameManager.AddLog( $"** AI hits 21! You lose {scaledBlackjackDamage} HP! **" );
			CombatManager.applyDamage( ref cachedPlayer, scaledBlackjackDamage );
		}
		else if ( aiRunningTotal > 21 || finalPlayerTotal > aiRunningTotal )
		{
			GameManager.AddLog( $"** You win with {finalPlayerTotal} vs {aiRunningTotal}! AI loses {scaledWinDamage} HP! **" );
			CombatManager.applyDamage( ref cachedAI, scaledWinDamage );
		}
		else if ( aiRunningTotal > finalPlayerTotal )
		{
			GameManager.AddLog( $"** AI wins with {aiRunningTotal} vs {finalPlayerTotal}! You lose {scaledWinDamage} HP! **" );
			CombatManager.applyDamage( ref cachedPlayer, scaledWinDamage );
		}
		else
		{
			GameManager.AddLog( $"** Tie! Both lose {scaledTieDamage} HP. **" );
			CombatManager.applyDamage( ref cachedPlayer, scaledTieDamage );
			CombatManager.applyDamage( ref cachedAI, scaledTieDamage );
		}

		GameManager.AddLog( $"{cachedPlayer.name} | HP: {cachedPlayer.hp} | Armor: {cachedPlayer.defense}" );
		GameManager.AddLog( $"{cachedAI.name} | HP: {cachedAI.hp} | Armor: {cachedAI.defense}" );
	}
}