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

namespace Keyboard_Warriors_.Managers;

public static class UnoDuelEventRunner
{
	private static Player cachedPlayer;
	private static Player cachedAI;

	private static readonly string[] colors = { "Red", "Blue", "Green", "Yellow" };

	private static int topColor;
	private static int topNumber;
	private static int topType;

	private static int playerColor;
	private static int playerNumber;
	private static int playerType;

	private static int aiColor;
	private static int aiNumber;
	private static int aiType;

	private static bool playerCanPlay;

	// =========================================================================
	// 🌐 MULTIPLAYER NETWORK STATE MATRIX
	// =========================================================================
	private static bool isPlayerOneFinished = false;
	private static bool isPlayerTwoFinished = false;
	private static bool isUnoResolved = false;
	private static int p1SavedChoice = 0;
	private static int p2SavedChoice = 0;
	// =========================================================================

	private static int DrawCardType()
	{
		int roll = Random.Shared.Next( 0, 100 );
		if ( roll < 65 ) return 0;
		if ( roll < 77 ) return 1;
		if ( roll < 92 ) return 2;
		return 3;
	}

	private static string GetCardTypeName( int t )
	{
		if ( t == 0 ) return "Number";
		if ( t == 1 ) return "Reverse";
		if ( t == 2 ) return "Draw Two";
		return "Wild";
	}

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

	public static void StartEvent( Player player, Player ai )
	{
		var manager = GetManager();
		if ( manager == null )
		{
			Log.Error( "[UNO DUEL CRITICAL] Failed to resolve GameManager from active scene tree setup!" );
			return;
		}

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

		GameManager.AddSystemLog( "\n=== UNO DUEL MATCH PROTOCOL ===" );

		cachedPlayer = player;
		cachedAI = ai;

		// Symmetrically deal starting card packets across the frame arrays
		topColor = Random.Shared.Next( 0, 4 );
		topNumber = Random.Shared.Next( 0, 10 );
		topType = DrawCardType();

		playerColor = Random.Shared.Next( 0, 4 );
		playerNumber = Random.Shared.Next( 0, 10 );
		playerType = DrawCardType();

		aiColor = Random.Shared.Next( 0, 4 );
		aiNumber = Random.Shared.Next( 0, 10 );
		aiType = DrawCardType();

		if ( isMultiplayer )
		{
			isPlayerOneFinished = false;
			isPlayerTwoFinished = false;
			isUnoResolved = false;
			p1SavedChoice = 0;
			p2SavedChoice = 0;

			GameManager.AddSystemLog( $"\n[DECK STACK] Top Discard Pile: {colors[topColor]} {topNumber} ({GetCardTypeName( topType )})" );
			GameManager.AddPlayerLog( $"[{cachedPlayer.name}'s HAND] Dealt Profile: {colors[playerColor]} {playerNumber} ({GetCardTypeName( playerType )})" );
			GameManager.AddAILog( $"[{cachedAI.name}'s HAND] Dealt Profile: {colors[aiColor]} {aiNumber} ({GetCardTypeName( aiType )})" );
			GameManager.AddSystemLog( "⚠️ AWAITING SECURITY HANDSHAKE DISCARD PROTOCOLS..." );

			// Begin sequential phase matching loop with Player 1 (Host)
			RunMultiplayerUnoLoop( true );
		}
		else
		{
			// 🤖 SINGLE PLAYER MODE: Exact original career rules configuration
			GameManager.AddSystemLog( $"\n[DECK STACK] Top Discard Pile: {colors[topColor]} {topNumber} ({GetCardTypeName( topType )})" );
			GameManager.AddPlayerLog( $"[YOUR HAND] Dealt Profile: {colors[playerColor]} {playerNumber} ({GetCardTypeName( playerType )})" );
			GameManager.AddAILog( $"[AI BUFFER] Dealt Profile: {colors[aiColor]} {aiNumber} ({GetCardTypeName( aiType )})" );
			GameManager.AddSystemLog( "⚠️ AWAITING SECURITY HANDSHAKE DISCARD PROTOCOL..." );

			playerCanPlay =
				playerType == 3 ||
				playerType == topType ||
				playerColor == topColor ||
				playerNumber == topNumber;

			var unoEvent = new ChoiceEvent
			{
				Title = "🃏 PROTOCOL CARD DECK DUEL",
				PromptText = $"The system has dealt an encryption card profile. Top Card: {colors[topColor]} {topNumber} ({GetCardTypeName( topType )}). Your Card: {colors[playerColor]} {playerNumber} ({GetCardTypeName( playerType )}). Will you match the sector or pull from the core stack?",
			};

			unoEvent.Options.Add( new EventOption { ButtonText = "🃏 DISCARD / PLAY CARD", ActionToExecute = () => ResolveUnoDuel( 1 ) } );
			unoEvent.Options.Add( new EventOption { ButtonText = "➕ DRAW PACKET & SKIP", ActionToExecute = () => ResolveUnoDuel( 2 ) } );

			manager.TriggerChoicePopup( unoEvent );
		}
	}

	// =========================================================================
	// 👥 MULTIPLAYER SEQUENTIAL CARD DISCARD ROUTER
	// =========================================================================
	private static void RunMultiplayerUnoLoop( bool isPlayerOneTurn )
	{
		var manager = GetManager();
		if ( manager == null ) return;

		string activeName = isPlayerOneTurn ? cachedPlayer.name : cachedAI.name;
		int activeColor = isPlayerOneTurn ? playerColor : aiColor;
		int activeNumber = isPlayerOneTurn ? playerNumber : aiNumber;
		int activeType = isPlayerOneTurn ? playerType : aiType;

		bool canActivePlay =
			activeType == 3 ||
			activeType == topType ||
			activeColor == topColor ||
			activeNumber == topNumber;

		bool shouldDrawPopup = (isPlayerOneTurn && Networking.IsHost) || (!isPlayerOneTurn && !Networking.IsHost);

		if ( shouldDrawPopup )
		{
			var unoMpEvent = new ChoiceEvent
			{
				Title = "🃏 PROTOCOL CARD DECK DUEL",
				PromptText = $"Top Card: {colors[topColor]} {topNumber} ({GetCardTypeName( topType )}). Your Card: {colors[activeColor]} {activeNumber} ({GetCardTypeName( activeType )}). Execute discard vector sub-routine:",
			};

			unoMpEvent.Options.Add( new EventOption
			{
				ButtonText = canActivePlay ? "🃏 DISCARD / PLAY CARD (VALID MATCH)" : "❌ DISCARD / PLAY CARD (FORCES MISPLAY PENALTY)",
				ActionToExecute = () =>
				{
					if ( isPlayerOneTurn ) { p1SavedChoice = 1; isPlayerOneFinished = true; }
					else { p2SavedChoice = 1; isPlayerTwoFinished = true; }

					// Symmetrically pass the card properties forward into the stack top card pointer context
					topColor = activeColor;
					topNumber = activeNumber;
					topType = activeType;

					AdvanceMultiplayerUnoPhase( isPlayerOneTurn );
				}
			} );

			unoMpEvent.Options.Add( new EventOption
			{
				ButtonText = "➕ DRAW PACKET & SKIP",
				ActionToExecute = () =>
				{
					if ( isPlayerOneTurn ) { p1SavedChoice = 2; isPlayerOneFinished = true; }
					else { p2SavedChoice = 2; isPlayerTwoFinished = true; }

					AdvanceMultiplayerUnoPhase( isPlayerOneTurn );
				}
			} );

			manager.TriggerChoicePopup( unoMpEvent );
		}
		else
		{
			if ( manager.IsChoiceEventActive ) manager.IsChoiceEventActive = false;
			GameManager.AddSystemLog( $"⏳ Waiting for {activeName} to finalize their card discard handshake..." );
		}
	}

	private static void AdvanceMultiplayerUnoPhase( bool wasPlayerOneTurn )
	{
		var manager = GetManager();
		if ( wasPlayerOneTurn && !isPlayerTwoFinished )
		{
			// Player 1 logged their card -> dynamically pass prompt controls over to Player 2
			RunMultiplayerUnoLoop( false );
		}
		else if ( isPlayerOneFinished && isPlayerTwoFinished && !isUnoResolved )
		{
			isUnoResolved = true;

			GameManager.AddSystemLog( $"\n📊 [NET UNO DUEL EXECUTION]" );

			// Calculate flat competitive baseline damage metrics for multiplayer wires
			int pReverseDmg = 10;
			int pDrawTwoDmg = 20;
			int pPenaltyDmg = 15;

			// --- EVALUATE PLAYER 1 OUTCOME ---
			bool p1CanPlayInitial = playerType == 3 || playerType == topType || playerColor == topColor || playerNumber == topNumber;
			if ( p1SavedChoice == 1 )
			{
				if ( p1CanPlayInitial )
				{
					GameManager.AddPlayerLog( $"🟢 {cachedPlayer.name} played their {colors[playerColor]} {GetCardTypeName( playerType )}!" );
					if ( playerType == 1 )
					{
						GameManager.AddPlayerLog( $"🔄 REVERSE DIRECTION! {cachedAI.name} suffers -{pReverseDmg} HP | {cachedPlayer.name} heals +{pReverseDmg} HP!" );
						CombatManager.applyDamage( ref cachedAI, pReverseDmg );
						cachedPlayer.hp = Math.Min( cachedPlayer.maxHp, cachedPlayer.hp + pReverseDmg );
					}
					else if ( playerType == 2 )
					{
						GameManager.AddPlayerLog( $"➕ DRAW TWO! {cachedAI.name} takes -{pDrawTwoDmg} HP!" );
						CombatManager.applyDamage( ref cachedAI, pDrawTwoDmg );
					}
					else if ( playerType == 3 ) GameManager.AddPlayerLog( $"🌈 {cachedPlayer.name} triggered a Wild color shift vector!" );
				}
				else
				{
					GameManager.AddPlayerLog( $"❌ {cachedPlayer.name} forced an INVALID SEQUENCE! Penalty feedback hits for -{pPenaltyDmg} HP!" );
					CombatManager.applyDamage( ref cachedPlayer, pPenaltyDmg );
				}
			}
			else GameManager.AddPlayerLog( $"📥 {cachedPlayer.name} drew a packet and skipped their action." );

			// --- EVALUATE PLAYER 2 OUTCOME ---
			bool p2CanPlayInitial = aiType == 3 || aiType == topType || aiColor == topColor || aiNumber == topNumber;
			if ( p2SavedChoice == 1 )
			{
				if ( p2CanPlayInitial )
				{
					GameManager.AddAILog( $"🟢 {cachedAI.name} played their {colors[aiColor]} {GetCardTypeName( aiType )}!" );
					if ( aiType == 1 )
					{
						GameManager.AddAILog( $"🔄 REVERSE DIRECTION! {cachedPlayer.name} suffers -{pReverseDmg} HP | {cachedAI.name} heals +{pReverseDmg} HP!" );
						CombatManager.applyDamage( ref cachedPlayer, pReverseDmg );
						cachedAI.hp = Math.Min( cachedAI.maxHp, cachedAI.hp + pReverseDmg );
					}
					else if ( aiType == 2 )
					{
						GameManager.AddAILog( $"➕ DRAW TWO! {cachedPlayer.name} takes -{pDrawTwoDmg} HP!" );
						CombatManager.applyDamage( ref cachedPlayer, pDrawTwoDmg );
					}
					else if ( aiType == 3 ) GameManager.AddAILog( $"🌈 {cachedAI.name} triggered a Wild color shift vector!" );
				}
				else
				{
					GameManager.AddAILog( $"❌ {cachedAI.name} forced an INVALID SEQUENCE! Penalty feedback hits for -{pPenaltyDmg} HP!" );
					CombatManager.applyDamage( ref cachedAI, pPenaltyDmg );
				}
			}
			else GameManager.AddAILog( $"📥 {cachedAI.name} drew a packet and skipped their action." );

			// Hard clamp health values safely
			if ( cachedPlayer.hp < 0 ) cachedPlayer.hp = 0;
			if ( cachedAI.hp < 0 ) cachedAI.hp = 0;

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

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

	private static void ResolveUnoDuel( int playerChoice )
	{
		var manager = GetManager();
		int prestige = manager != null ? manager.CurrentPrestige : 0;

		int scaledReverseDamage = 10 + (prestige * 1);
		int scaledDrawTwoDamage = 20 + (prestige * 3);
		int scaledPenaltyDamage = 15 + (prestige * 2);

		if ( playerChoice == 1 )
		{
			if ( playerCanPlay )
			{
				GameManager.AddPlayerLog( $"🟢 CARD MATCHED! You successfully play your {colors[playerColor]} {GetCardTypeName( playerType )}!" );

				if ( playerType == 1 )
				{
					int finalHeal = scaledReverseDamage + cachedPlayer.eventHealingBuff;
					GameManager.AddPlayerLog( $"🔄 REVERSE DIRECTION! Data stream inverted! AI loses {scaledReverseDamage} HP | You heal +{finalHeal} HP!" );
					CombatManager.applyDamage( ref cachedAI, scaledReverseDamage );
					cachedPlayer.hp += finalHeal;
					cachedPlayer.eventHealingBuff = 0;
				}
				else if ( playerType == 2 )
				{
					GameManager.AddPlayerLog( $"➕ DRAW TWO! Forcing stack overflow on AI registers! AI loses {scaledDrawTwoDamage} HP!" );
					CombatManager.applyDamage( ref cachedAI, scaledDrawTwoDamage );
				}
				else if ( playerType == 3 )
				{
					topColor = Random.Shared.Next( 0, 4 );
					GameManager.AddPlayerLog( $"🌈 [WILD CARD ACTIVATE] Firewalls re-encrypted! Mainframe color shifted to {colors[topColor]}!" );
				}
				else
				{
					GameManager.AddPlayerLog( $"💾 Data segment discarded cleanly: {colors[playerColor]} {playerNumber} overrides the stack." );
				}

				topColor = playerColor;
				topNumber = playerNumber;
				topType = playerType;
			}
			else
			{
				GameManager.AddPlayerLog( $"❌ INVALID SEQUENCE! Your {colors[playerColor]} {GetCardTypeName( playerType )} does not match the pile color or number! Card rejected!" );
				GameManager.AddPlayerLog( $"🚨 UNO MISPLAY PENALTY! System feedback loop hits you for -{scaledPenaltyDamage} HP!" );
				CombatManager.applyDamage( ref cachedPlayer, scaledPenaltyDamage );
			}
		}
		else
		{
			GameManager.AddPlayerLog( "📥 Packet pulled. You draw from the core stack and skip your action." );
		}

		bool aiCanPlay = aiType == 3 || aiType == topType || aiColor == topColor || aiNumber == topNumber;
		GameManager.AddAILog( "\nAI's turn!" );

		if ( aiCanPlay && cachedAI.hp > 15 )
		{
			GameManager.AddAILog( $"🔴 AI MATCHED! AI plays its {colors[aiColor]} {GetCardTypeName( aiType )} onto the pile!" );

			if ( aiType == 1 )
			{
				int finalAIHeal = scaledReverseDamage + cachedAI.eventHealingBuff;
				GameManager.AddAILog( $"🔄 AI REVERSE! AI steals health! (You lose {scaledReverseDamage} HP | AI heals +{finalAIHeal} HP!)" );
				CombatManager.applyDamage( ref cachedPlayer, scaledReverseDamage );
				cachedAI.hp += finalAIHeal;
				cachedAI.eventHealingBuff = 0;
			}
			else if ( aiType == 2 )
			{
				GameManager.AddAILog( $"➕ AI DRAW TWO! You lose {scaledDrawTwoDamage} HP!" );
				CombatManager.applyDamage( ref cachedPlayer, scaledDrawTwoDamage );
			}
			else if ( aiType == 3 )
			{
				topColor = Random.Shared.Next( 0, 4 );
				GameManager.AddAILog( $"🌈 AI uses WILD! Mainframe color shifted to {colors[topColor]}" );
			}
			else
			{
				GameManager.AddAILog( $"💾 AI discards cleanly: {colors[aiColor]} {aiNumber} overrides the stack." );
			}

			topColor = aiColor;
			topNumber = aiNumber;
			topType = aiType;
		}
		else
		{
			GameManager.AddAILog( "AI draws a card from the core stack." );
			if ( !aiCanPlay )
			{
				GameManager.AddAILog( $"🚨 AI MISPLAY PENALTY! AI failed to match parameters!" );
			}
		}
	}
}