using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using TMPro;
using Unity.VisualScripting;
using UnityEngine.InputSystem.Users;
//using UnityEngine.Device;
using UnityEngine.SceneManagement;
using System;
using UnityEngine.InputSystem.UI;
using UnityEngine.InputSystem.Utilities;
//using UnityEngine.Windows;

public class PlayerInfo
{
    public InputDevice Device { get; set; }
    public string ControlScheme { get; set; }
}

public class ModeSelection : MonoBehaviour
{
    public Button primaryButton;
    public Button confirmButton;
    public Button firstButtonAI;
    public Button confirmButtonAI;
    // Game mode selection buttons and graphics
    public GameObject graphic1v1;
    public GameObject graphic1v1ai;
    public GameObject graphic2v2;
    public GameObject graphic3v3;
    public CharacterSelection CharacterSelectionScript;
    public CashSystemCharacterSelection cashSystemCharacterSelection;
    //[SerializeField] JoinPlayer joinPlayer;
    public GameObject selectionScreen;
    public GameObject modeSelectionScreen;
    // Player selection buttons for each game mode
    public Button[] playerButtons1v1;
    public Button[] playerButtons1v1ai;
    public Button[] playerButtons2v2;
    public Button[] playerButtons3v3;
    public Sprite[] characterImages;
    // Character prefabs
    public GameObject[] characterPrefabs;
    // Maximum number of players for each game mode
    public int maxPlayers1v1 = 2;
    public int maxPlayers2v2 = 4;
    public int maxPlayers3v3 = 6;
    // Input devices for player selection
    public Image characterImage;
    private string previousCharacterName = "";
    public InputActionAsset existingInputAsset;
    public GameObject systemEvents;
    public GameObject systemEvents2;
    public Button[] playerButtons;
    public PlayerInput playerIncontrol;
    public InputAction.CallbackContext callbackContext;
    string controlScheme;
    public Dictionary<string,string> selectedPlayersAI = new Dictionary<string, string>();
    public Dictionary<string, PlayerInfo> selectedPlayerDevice = new Dictionary<string, PlayerInfo>();
    private int joinedPlayers = 0;
    private int maxPlayers = 2; // Set this to the maximum number of players you want to allow.
    private bool isMobile;
    public HomeSrceen homeScreen;
    public Button versusScreenBackButton;
#if ENABLE_INPUT_SYSTEM
    private IDisposable onAnyButtonPressSubscription;
#endif
    // Prevent duplicate scene loads
    private bool isLoadingGameScene = false;
    // Start is called before the first frame update
    void Start()
    {
        //initialize 1v1 graphic
        graphic1v1.SetActive(false);
        graphic1v1ai.SetActive(false);
        graphic2v2.SetActive(false);
        graphic3v3.SetActive(false);

        //graphic1v1.gameObject.transform.GetChild(1).GetChild(0).gameObject.SetActive(false);

        // This subscribes us to events that will fire if any button is pressed.  We'll most certainly want to throw this away 
        // when not in a selection screen (performance intensive)!
        
#if ENABLE_INPUT_SYSTEM
        EnableJoinListener();
#endif
    }
#if ENABLE_INPUT_SYSTEM
    private void EnableJoinListener()
    {
        if (!Application.isPlaying)
            return;

        if (onAnyButtonPressSubscription != null)
            return;

        Action<InputControl> handler = control =>
        {
            if (control == null)
                return;
            HandleDeviceJoin(control.device);
        };

        onAnyButtonPressSubscription = InputSystem.onAnyButtonPress.Call(handler);
    }

    private void DisableJoinListener()
    {
        if (!Application.isPlaying)
            return;

        if (onAnyButtonPressSubscription != null)
        {
            onAnyButtonPressSubscription.Dispose();
            onAnyButtonPressSubscription = null;
        }
    }

    private void HandleDeviceJoin(InputDevice device)
    {
        if (device == null)
            return;

        if (joinedPlayers >= maxPlayers)
        {
            DisableJoinListener();
            return;
        }

        if (!isActiveAndEnabled || modeSelectionScreen == null || !modeSelectionScreen.activeSelf)
            return;

        AddPlayer(device);

        if (joinedPlayers >= maxPlayers)
        {
            DisableJoinListener();
        }
    }
#endif

    private void OnEnable()
    {
#if ENABLE_INPUT_SYSTEM
        if (!Application.isPlaying)
            return;
        EnableJoinListener();
#endif
    }

    private void OnDisable()
    {
#if ENABLE_INPUT_SYSTEM
        if (!Application.isPlaying)
            return;
        DisableJoinListener();
#endif
    }


    public void SelectFirstButton()
    {
        primaryButton.Select();
    }
    public void SelectFirstAIButton()
    {
        firstButtonAI.Select();
    }
    void AddPlayer(InputDevice device)
    {
        //return if the gameobject is not modeselection screen
        if (!gameObject.activeSelf || !graphic1v1.gameObject.activeSelf || EventSystem.current.currentSelectedGameObject.name == "BackButton")
        {
            return;
        }
            
        if (graphic1v1.gameObject.activeSelf || graphic2v2.gameObject.activeSelf || graphic3v3.gameObject.activeSelf)
        {
            // Avoid running if the device is already paired to a player
            /*if (PlayerInput.all.Count > 0)
            {*/
            foreach (var player in PlayerInput.all)
            {
                //InputUser inputUser = player.user;
                foreach (var playerDevice in player.devices)
                {
                    if ((playerDevice.name.Contains("Keyboard") || playerDevice.name.Contains("Mouse")) && (device.name.Contains("Keyboard") || device.name.Contains("Mouse")))
                    {
                        /*print(device.name);
                        print("keyboard/mouse already added returned");*/
                        return;
                    }
                    if (device.name == playerDevice.name)
                    {
                        /*print(device.name);
                        print("device already added");*/
                        return;
                    }
                    /*else if ((device.name.Contains("Keyboard") || device.name.Contains("Mouse")) && (playerDevice.name.Contains("Keyboard") || playerDevice.name.Contains("Mouse")))
                        return;*/
                }
            }
            //}

            // Don't execute if not a gamepad or joystick or keyboard&mouse
            if (!device.name.Contains("Controller") && !device.name.Contains("Joystick") && !device.name.Contains("Gamepad") && !device.name.Contains("Keyboard") && !device.name.Contains("Mouse"))
            {
                print("if returned");
                return;
            }

            //print("Adding player");
            //var playerNumberToAdd = PlayerInput.all.Count + 1;

            if (device.name.Contains("Controller") || device.name.Contains("Gamepad"))
                controlScheme = "Gamepad";
            else if (device.name.Contains("Joystick"))
                controlScheme = "Joystick";
            else if (device.name.Contains("Keyboard") || device.name.Contains("Mouse"))
                controlScheme = "Keyboard&Mouse";

            foreach (var button in playerButtons1v1)
            {
                //print (button.name);
                if (button.gameObject.GetComponent<PlayerInput>() == null)
                {
                    PlayerInput buttonInput = button.gameObject.AddComponent<PlayerInput>();
                    buttonInput.actions = existingInputAsset;
                    buttonInput.defaultControlScheme = controlScheme;
                    buttonInput.neverAutoSwitchControlSchemes = true;
                    buttonInput.notificationBehavior = PlayerNotifications.InvokeUnityEvents;
                    
                    buttonInput.uiInputModule = systemEvents.GetComponent<InputSystemUIInputModule>();
                    buttonInput.uiInputModule.enabled = true;   
                    //buttonInput.uiInputModule.ActivateModule();
                    //buttonInput.uiInputModule.actionsAsset = existingInputAsset;
                    InputUser myUser = buttonInput.user;
                    //InputUser user = InputUser.PerformPairingWithDevice(device);
                    InputUser.PerformPairingWithDevice(device, myUser);
                    buttonInput.SwitchCurrentControlScheme(controlScheme, device);
                    buttonInput.defaultActionMap = "UI";
                    buttonInput.SwitchCurrentActionMap("UI");
                    buttonInput.currentActionMap["Submit"].performed += OnSubmit;
                    //buttonInput.gameObject.GetComponentInChildren<TextMeshProUGUI>().text = buttonInput.currentControlScheme.ToString();//this was about displaying the attached device to keyboard
                    buttonInput.camera = GameObject.Find("Main Camera").GetComponent<Camera>();
                    buttonInput.enabled = true;
                    buttonInput.ActivateInput();
                    joinedPlayers++;
                    return;
                }
            }
        }
    }
    public void On1v1aiClick()
    {
        foreach (var button in playerButtons1v1ai)
        {
            if (EventSystem.current.currentSelectedGameObject == button.gameObject)
            {
                //button.gameObject.GetComponent<ButtonClickSound>().PlayClickSound();
                PlayerPrefs.SetString("selectedbuttonpvp", button.name);
                //print("sent button" + PlayerPrefs.GetString("selectedbuttonpvp"));
                modeSelectionScreen.SetActive(false);
                CharacterSelectionScript.selectCharacterButton.onClick.AddListener(onSelectionScreenSelectClick);
                CharacterSelectionScript.backButton.onClick.AddListener(onSelectionScreenBackClick);
                selectionScreen.SetActive(true);
            }
        }
    }
    
    /// <summary>
    /// Called when the Confirm button is clicked in 3v3 mode (Cash System)
    /// Wire this to the Confirm button's OnClick in the 3v3 graphic
    /// </summary>
    public void OnConfirmButton3v3()
    {
        Debug.Log("[ModeSelection] OnConfirmButton3v3 clicked");
        
        // Check if we're in Cash System mode
        if (SelectionOptions.Instance != null && SelectionOptions.Instance.isCashSystemSelected)
        {
            // Delegate to CashSystemCharacterSelection
            if (cashSystemCharacterSelection != null)
            {
                cashSystemCharacterSelection.OnConfirmClicked();
            }
            else
            {
                // Fallback - get from graphic3v3
                CashSystemCharacterSelection cashSelection = graphic3v3.GetComponent<CashSystemCharacterSelection>();
                if (cashSelection != null)
                {
                    cashSelection.OnConfirmClicked();
                }
                else
                {
                    Debug.LogError("[ModeSelection] CashSystemCharacterSelection not found!");
                }
            }
        }
        else
        {
            // Not in Cash System mode - use the original AI confirm handler
            Debug.Log("[ModeSelection] Not in Cash System mode, calling OnconfirmButtonAIClick");
            OnconfirmButtonAIClick();
        }
    }
    
    public void OnconfirmButtonAIClick()
    {
        if (selectedPlayersAI.Count != 2 || SelectionOptions.Instance == null)
        {
            Debug.LogWarning("Not enough players selected or SelectionOptions not initialized");
            return;
        }

        // Guard against duplicate loads
        if (isLoadingGameScene || SceneLoader.IsLoading)
            return;

        // Disable input action and button to prevent double click
#if ENABLE_INPUT_SYSTEM
    DisableJoinListener();
#endif
        if (confirmButtonAI != null) confirmButtonAI.interactable = false;

        // Check platform
        isMobile = UnityEngine.Application.platform == RuntimePlatform.Android ||
                   UnityEngine.Application.platform == RuntimePlatform.IPhonePlayer;


        if (!isMobile)
        {
            bool isKeyboardInput = Keyboard.current != null && Keyboard.current.enterKey.isPressed;
            bool isMouseClick = Mouse.current != null && Mouse.current.leftButton.isPressed;

            if (isKeyboardInput || isMouseClick)
            {
                SetupAIGame("Keyboard&Mouse", InputSystem.GetDevice<Keyboard>());
            }
            else
            {
                SetupAIGame("Gamepad", InputSystem.GetDevice<Gamepad>());
            }
        }
        else
        {
            SetupAIGame("Gamepad", InputSystem.GetDevice<Gamepad>());
        }
    }

    private void SetupAIGame(string controlScheme, InputDevice device)
    {
        SelectionOptions.Instance.selectedPlayersAI = selectedPlayersAI;
        SelectionOptions.Instance.activeDeviceforAI = device;
        SelectionOptions.Instance.controlSchemeforAI = controlScheme;

        //GameManager.Instance.ShowLoadingUI();
        //GameManager.Instance.gameObject.GetComponent<LoadingScreen>()?.UI_to_show_AfterLoading(1, "Game");
        //GameManager.Instance.gameObject.GetComponent<LoadingScreen>()?.InitializeLoading();

        // Start the loading sequence
        StartCoroutine(LoadGameWithUI());
    }

    private IEnumerator LoadGameWithUI()
    {
        // Guard against multiple loads
        if (isLoadingGameScene || SceneLoader.IsLoading)
            yield break;
        isLoadingGameScene = true;

        // Show loading UI
        GameManager.Instance.ShowLoadingUI();
        
        // Load Game scene (Editor: built-in, Android: custom AssetBundle)
        // SceneLoader now handles everything automatically!
        var asyncLoad = SceneLoader.LoadSceneAsyncOnce("Game", LoadSceneMode.Single, allowSceneActivation: true);
        if (asyncLoad == null)
        {
            isLoadingGameScene = false;
            GameManager.Instance.HideLoadingUI();
            yield break;
        }
        
        // IMPORTANT: Run the wait loop on GameManager so it survives scene changes
        // This coroutine (running on ModeSelection) will be destroyed when MenuScene unloads!
        GameManager.Instance.StartCoroutine(WaitForGameSceneLoad(asyncLoad));
        
        // This coroutine will be destroyed here when the scene changes, which is fine
        // because WaitForGameSceneLoad is running on GameManager (DontDestroyOnLoad)
    }
    
    private static IEnumerator WaitForGameSceneLoad(SceneLoader.SceneLoadHandle asyncLoad)
    {
        // Wait until scene is fully loaded
        while (asyncLoad != null && !asyncLoad.isDone)
        {
            yield return null;
        }
        
        Debug.Log("[ModeSelection] Game scene loaded, hiding loading UI...");
        if (GameManager.Instance != null)
        {
            GameManager.Instance.HideLoadingUI();
        }
    }

    string GetKeyFromValue(Dictionary<string, string> dictionary, string value)
    {
        foreach (KeyValuePair<string, string> kvp in dictionary)
        {
            if (kvp.Value == value)
            {
                return kvp.Key;
            }
        }
        return null; // Return null if the value is not found
    }
    string GetNameFromValue(Dictionary<string, PlayerInfo> dictionary, InputDevice device)
    {
        foreach (KeyValuePair<string, PlayerInfo> kvp in dictionary)
        {
            if (kvp.Value.Device == device)
            {
                return kvp.Key;
            }
        }
        return null; // Return null if the value is not found
    }

    InputDevice GetDeviceFromValue(Dictionary<string, PlayerInfo> dictionary, InputDevice device)
    {
        foreach (KeyValuePair<string, PlayerInfo> kvp in dictionary)
        {
            if (kvp.Value.Device == device)
            {
                return kvp.Value.Device;
            }
        }
        return null; // Return null if the value is not found
    }

    //this will help selecting character while in ai mode
    public void onSelectionScreenSelectClick()
    {
        string selectedCharacterName = PlayerPrefs.GetString("selectedcharactername", "");
        if (selectedCharacterName != "")
        {
            // Check if in Cash System mode
            if (SelectionOptions.Instance != null && SelectionOptions.Instance.isCashSystemSelected)
            {
                HandleCashSystemCharacterSelection(selectedCharacterName);
                return;
            }
            
            string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");

            if (!string.IsNullOrEmpty(selectedbuttonpvp))
            {
                // Remove the previous character selection if it exists
                if (selectedbuttonpvp == "1.1ai" && selectedPlayersAI.ContainsValue("AI"))
                {
                    print("removed characters " + GetKeyFromValue(selectedPlayersAI, "AI"));
                    selectedPlayersAI.Remove(GetKeyFromValue(selectedPlayersAI, "AI"));
                }
                else if(selectedbuttonpvp == "1.2ai" && selectedPlayersAI.ContainsValue("PLAYER")){
                    print("removed characters " + GetKeyFromValue(selectedPlayersAI, "PLAYER"));
                    selectedPlayersAI.Remove(GetKeyFromValue(selectedPlayersAI, "PLAYER"));
                }
                
                // Add the new character selection
                if (selectedbuttonpvp == "1.1ai")
                {
                    selectedPlayersAI.Add(selectedCharacterName, "AI");
                }
                else if (selectedbuttonpvp == "1.2ai")
                {
                    selectedPlayersAI.Add(selectedCharacterName, "PLAYER");
                }

                UpdatePlayerSelectButtons(selectedCharacterName); // Pass the selected character name
                PlayerPrefs.SetString("selectedcharactername", "");

                // Deactivate the current screen
                selectionScreen.SetActive(false);
                // Activate the ModeScreen
                CharacterSelectionScript.modeScreen.SetActive(true);

                // Update the selected button
                foreach (var button in playerButtons1v1ai)
                {
                    if (button.name == selectedbuttonpvp)
                    {
                        GameObject buttonCurrent = button.gameObject;
                        print("button current" + buttonCurrent.name);
                        buttonCurrent.GetComponent<Button>().Select();
                        PlayerPrefs.SetString("selectedbuttonpvp", "");
                    }
                }
            }
        }
        CharacterSelectionScript.selectCharacterButton.onClick.RemoveListener(onSelectionScreenSelectClick);
        if (confirmButtonAI.onClick.GetPersistentEventCount() < 1)
        {
            confirmButtonAI.onClick.AddListener(OnconfirmButtonAIClick);
        }
    }
    
    /// <summary>
    /// Handle character selection for Cash System mode
    /// </summary>
    private void HandleCashSystemCharacterSelection(string selectedCharacterName)
    {
        Debug.Log($"[ModeSelection] Cash System character selected: {selectedCharacterName}");
        
        // Clear the saved character name
        PlayerPrefs.SetString("selectedcharactername", "");
        
        // Deactivate the selection screen
        selectionScreen.SetActive(false);
        
        // Call the CashSystemCharacterSelection to handle the selection
        if (cashSystemCharacterSelection != null)
        {
            cashSystemCharacterSelection.OnCharacterSelected(selectedCharacterName);
        }
        else
        {
            // Fallback - get it from the 3v3 graphic
            CashSystemCharacterSelection cashSelection = graphic3v3.GetComponent<CashSystemCharacterSelection>();
            if (cashSelection != null)
            {
                cashSelection.OnCharacterSelected(selectedCharacterName);
            }
            else
            {
                Debug.LogError("[ModeSelection] CashSystemCharacterSelection not found!");
            }
        }
        
        // Show mode selection screen again
        if (modeSelectionScreen != null)
        {
            modeSelectionScreen.SetActive(true);
        }
        
        // Activate the 3v3 graphic/mode screen
        graphic3v3.SetActive(true);
        
        // Remove listener
        CharacterSelectionScript.selectCharacterButton.onClick.RemoveListener(onSelectionScreenSelectClick);
    }

    public void onSelectionScreenBackClick()
    {
        
        PlayerPrefs.SetString("selectedcharactername", "");
        string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
        // Deactivate the current screen
        selectionScreen.SetActive(false);
        // Activate the ModeScreen
        modeSelectionScreen.SetActive(true);
        GameObject buttonCurrent = gameObject;        
        //primaryButton.Select();
        foreach (var button in playerButtons1v1)
        {
            if (button.name == selectedbuttonpvp)
            {
                //Destroy(button.GetComponent<PlayerInput>());
                buttonCurrent = button.gameObject;
                buttonCurrent.GetComponent<Button>().Select();
                PlayerPrefs.SetString("selectedbuttonpvp", "");
            }
        }
        CharacterSelectionScript.selectCharacterButton.onClick.RemoveListener(onSelectionScreenBackClick);
        if (SelectionOptions.Instance.isAISelected)
        {
            print("ai button selected");
            firstButtonAI.Select();
        }
        else
        {
            primaryButton.Select();
        }
        
        if (confirmButtonAI.onClick.GetPersistentEventCount() < 1)
            confirmButtonAI.onClick.AddListener(OnconfirmButtonAIClick);
    }
    public void ModeBackButton()
    {
#if ENABLE_INPUT_SYSTEM
        DisableJoinListener();
#endif
        modeSelectionScreen.SetActive(false);
        homeScreen.setModeScreen.SetActive(true);
    }
    public void OnSubmit(InputAction.CallbackContext context)
{
    // Early exit if core components are missing
    if (!this || !EventSystem.current || !EventSystem.current.currentSelectedGameObject || !GameManager.Instance?.gameObject)
    {
#if ENABLE_INPUT_SYSTEM
        DisableJoinListener();
#endif
        return;
    }

    GameObject currentButton = EventSystem.current.currentSelectedGameObject;
    if (currentButton == null) return;
    
    if (currentButton.name == "Confirm")
    {
        // Guard against duplicate loads
        if (isLoadingGameScene || SceneLoader.IsLoading)
            return;
        
        if (currentButton.GetComponent<PlayerInput>() == null)
        {
            foreach (var player in PlayerInput.all)
            {
                if (player != null && player.user != null && context.control != null)
                {
                    player.user.UnpairDevice(context.control.device);
                }
            }
            
            if (SelectionOptions.Instance != null)
            {
                SelectionOptions.Instance.selectedPlayerDevice = selectedPlayerDevice;
                if (confirmButton != null) confirmButton.interactable = false; // prevent double submit
                StartCoroutine(LoadGameWithUI());
            }

#if ENABLE_INPUT_SYSTEM
            DisableJoinListener();
#endif
        }
        return;
    }
    
    // ...existing code for other branches...
}


    private string DetermineControlScheme(InputDevice device)
    {
        if (device.name.Contains("Controller") || device.name.Contains("Gamepad"))
            return "Gamepad";
        if (device.name.Contains("Joystick"))
            return "Joystick";
        return "Keyboard&Mouse";
    }

    private void TransitionToModeScreen(InputAction.CallbackContext context, string controlScheme)
    {
        selectionScreen.SetActive(false);
        CharacterSelectionScript.modeScreen.SetActive(true);

        if (CharacterSelectionScript.selectCharacterButton != null)
        {
            var playerInput = CharacterSelectionScript.selectCharacterButton.gameObject.GetComponent<PlayerInput>();
            if (playerInput != null)
            {
                playerInput.uiInputModule.enabled = false;
                playerInput.DeactivateInput();
                Destroy(playerInput);
            }
        }

        foreach (var button1 in playerButtons1v1)
        {
            var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
            if (old != null)
            {
                old.enabled = true;
            }
        }

        UpdateButtonSelection(context);
    }

    private void HandleBackButton(InputAction.CallbackContext context)
    {
        PlayerPrefs.SetString("selectedcharactername", "");
        controlScheme = DetermineControlScheme(context.control.device);
        string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");

        selectionScreen.SetActive(false);
        modeSelectionScreen.SetActive(true);

        CleanupCharacterSelection();
        ResetUIInputModule();
        UpdateButtonSelectionForBack(selectedbuttonpvp);

#if ENABLE_INPUT_SYSTEM
    DisableJoinListener();
#endif
    }

    private void HandleModeSelectionBackButton()
    {
#if ENABLE_INPUT_SYSTEM
    DisableJoinListener();
#endif
        modeSelectionScreen.SetActive(false);
        homeScreen.setModeScreen.SetActive(true);

        CleanupPlayerInputs();
    }

    private void HandlePlayerButtonSelection(InputAction.CallbackContext context)
    {
        if (playerButtons1v1 == null) return;

        foreach (var button in playerButtons1v1)
        {
            if (button == null || !button.gameObject) continue;
            
            if (EventSystem.current?.currentSelectedGameObject == button.gameObject)
            {
                var playerInput = button.GetComponent<PlayerInput>();
                if (playerInput != null && playerInput.devices.Count > 0 && playerInput.devices[0] == context.control.device)
                {
                    ProcessButtonSelection(button, playerInput, context);
                    return;
                }
            }
        }
    }

    private void ProcessButtonSelection(Button button, PlayerInput playerInput, InputAction.CallbackContext context)
    {
        try
        {
            // Validate all required components exist
            if (!ValidateComponents(button, playerInput))
            {
                return;
            }

            // Store current player input
            playerIncontrol = playerInput;
            
            // Save button selection
            if (button != null)
            {
                PlayerPrefs.SetString("selectedbuttonpvp", button.name);
            }

            // Handle screen transitions
            if (modeSelectionScreen != null && selectionScreen != null)
            {
                modeSelectionScreen.SetActive(false);
                selectionScreen.SetActive(true);
            }

            // Setup input for character selection
            SetupCharacterSelectionInput(context);
        }
        catch (Exception e)
        {
            Debug.LogError($"Error in ProcessButtonSelection: {e.Message}\nStack Trace: {e.StackTrace}");
        }
    }

    private bool ValidateComponents(Button button, PlayerInput playerInput)
    {
        if (button == null || playerInput == null || !button.gameObject || !modeSelectionScreen || !selectionScreen)
        {
            Debug.LogWarning("One or more required components are missing");
            return false;
        }
        return true;
    }




    private void SetupCharacterSelectionInput(InputAction.CallbackContext context)
    {
        if (CharacterSelectionScript == null || CharacterSelectionScript.selectCharacterButton == null)
        {
            Debug.LogWarning("Character selection components not properly initialized");
            return;
        }

        var existingInput = CharacterSelectionScript.selectCharacterButton.gameObject.GetComponent<PlayerInput>();
        if (existingInput == null)
        {
            DisableExistingUIInputModules();
            CreateNewPlayerInput(context);
        }
    }


    private void CreateNewPlayerInput(InputAction.CallbackContext context)
    {
        var buttonInput = CharacterSelectionScript.selectCharacterButton.gameObject.AddComponent<PlayerInput>();
        if (buttonInput != null)
        {
            ConfigurePlayerInput(buttonInput, context);
        }
    }

    private void ConfigurePlayerInput(PlayerInput buttonInput, InputAction.CallbackContext context)
    {
        // Get the active device
        InputDevice device = GetActiveDevice();
        if (device == null) return;

        // Basic setup
        buttonInput.actions = existingInputAsset;
        buttonInput.defaultControlScheme = DetermineControlScheme(device);
        buttonInput.neverAutoSwitchControlSchemes = true;
        buttonInput.notificationBehavior = PlayerNotifications.InvokeUnityEvents;

        // UI Module setup
        if (systemEvents != null)
        {
            var uiModule = systemEvents.GetComponent<InputSystemUIInputModule>();
            if (uiModule != null)
            {
                buttonInput.uiInputModule = uiModule;
                uiModule.enabled = true;
            }
        }

        // Device pairing
        InputUser.PerformPairingWithDevice(device, buttonInput.user);
        buttonInput.SwitchCurrentControlScheme(buttonInput.defaultControlScheme, device);

        // Action map configuration
        buttonInput.defaultActionMap = "UI";
        buttonInput.SwitchCurrentActionMap("UI");

        var submitAction = buttonInput.actions.FindAction("UI/Submit");
        if (submitAction != null)
        {
            submitAction.performed += OnSubmit;
        }

        buttonInput.enabled = true;
    }

    private InputDevice GetActiveDevice()
    {
        if (Gamepad.current != null) return Gamepad.current;
        if (Keyboard.current != null) return Keyboard.current;
        if (Mouse.current != null) return Mouse.current;

        return null;
    }



    private void UpdateButtonSelection(InputAction.CallbackContext context)
    {
        string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
        foreach (var button in playerButtons1v1)
        {
            if (button.name == selectedbuttonpvp)
            {
                button.GetComponent<Button>().Select();
                PlayerPrefs.SetString("selectedbuttonpvp", "");
            }
        }
    }

    private void CleanupCharacterSelection()
    {
        if (CharacterSelectionScript.selectCharacterButton != null)
        {
            var playerInput = CharacterSelectionScript.selectCharacterButton.gameObject.GetComponent<PlayerInput>();
            if (playerInput != null)
            {
                playerInput.uiInputModule.enabled = false;
                playerInput.DeactivateInput();
                Destroy(playerInput);
            }
        }
    }

    private void ResetUIInputModule()
    {
        foreach (var button1 in playerButtons1v1)
        {
            var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
            if (old != null)
            {
                old.enabled = true;
            }
        }
    }

    private void UpdateButtonSelectionForBack(string selectedbuttonpvp)
    {
        foreach (var button in playerButtons1v1)
        {
            if (button.name == selectedbuttonpvp)
            {
                button.GetComponent<Button>().Select();
                PlayerPrefs.SetString("selectedbuttonpvp", "");
            }
        }
    }

    private void CleanupPlayerInputs()
    {
        foreach (var button1 in playerButtons1v1)
        {
            var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
            if (old != null)
            {
                old.enabled = false;
            }
            var playerInput = button1.GetComponent<PlayerInput>();
            if (playerInput != null)
            {
                Destroy(playerInput);
            }
        }
    }

    private void DisableExistingUIInputModules()
    {
        foreach (var button1 in playerButtons1v1)
        {
            var old = systemEvents?.GetComponent<InputSystemUIInputModule>();
            if (old != null)
            {
                old.enabled = false;
            }
        }
    }


    public IEnumerator LoadingNextLevel(int levelToLoad)
    {
        yield return new WaitForSeconds(0.5f);
        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(levelToLoad);

        // Wait until the asynchronous scene fully loads
        while (!asyncLoad.isDone)
        {
            yield return null;
        }
    }
    // Update is called once per frame
    // OPTIMIZATION: Cache PlayerPrefs value instead of reading every frame
    private bool wasScreenActive = false;
    
    void Update()
    {
        bool isScreenActive = modeSelectionScreen.gameObject.activeSelf;
        
        // Only check when screen first becomes active, not every frame
        if (isScreenActive && !wasScreenActive)
        {
            // Screen just became active, check for character update
            string storedCharacterName = PlayerPrefs.GetString("selectedcharactername");

            if (!string.IsNullOrEmpty(storedCharacterName) && storedCharacterName != previousCharacterName)
            {
                UpdatePlayerSelectButtons(storedCharacterName);
                previousCharacterName = storedCharacterName;
            }
        }
        
        wasScreenActive = isScreenActive;
    }
    
    public void ActivateGameMode(int mode)
    {
        // Activate the corresponding game mode graphic
        switch (mode)
        {
            case 1:

                graphic1v1.SetActive(true);
                graphic2v2.SetActive(false);
                graphic3v3.SetActive(false);
                /*button1v1.gameObject.transform.GetChild(1).gameObject.SetActive(true);
                button2v2.gameObject.transform.GetChild(1).gameObject.SetActive(false);
                button3v3.gameObject.transform.GetChild(1).gameObject.SetActive(false);*/

                break;
            case 2:
                graphic1v1.SetActive(false);
                graphic2v2.SetActive(true);
                graphic3v3.SetActive(false);
                /*button1v1.gameObject.transform.GetChild(1).gameObject.SetActive(false);
                button2v2.gameObject.transform.GetChild(1).gameObject.SetActive(true);
                button3v3.gameObject.transform.GetChild(1).gameObject.SetActive(false);*/

                break;
            case 3:
                graphic1v1.SetActive(false);
                graphic3v3.SetActive(true);
                graphic2v2.SetActive(false);
                /*button1v1.gameObject.transform.GetChild(1).gameObject.SetActive(false);
                button2v2.gameObject.transform.GetChild(1).gameObject.SetActive(false);
                button3v3.gameObject.transform.GetChild(1).gameObject.SetActive(true);*/

                break;
        }
    }
    public void UpdatePlayerSelectButtons(string characterName)
    {
        (Sprite characterSprite, Sprite characterSpriteBg) = GetCharacterSprite(characterName);
        // Update the player select buttons with the character sprite
        foreach (Button playerButton in playerButtons1v1)
        {
            string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
            if (selectedbuttonpvp == playerButton.name)
            {
                // Update the player select buttons with the character sprite
                Image buttonImageBg = playerButton.GetComponent<Image>();
                //1.2 is the left button, 1.1 is the right button
                if (buttonImageBg != null && playerButton.name == "1.2")
                {
                    buttonImageBg.sprite = characterSprite;
                }
                if (buttonImageBg != null && playerButton.name == "1.1")
                {
                    buttonImageBg.sprite = characterSpriteBg;
                }
            }
        }
        foreach (Button playerButton in playerButtons1v1ai)
        {
            string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
            if (selectedbuttonpvp == playerButton.name)
            {
                // Update the player select buttons with the character sprite
                Image buttonImageBg = playerButton.GetComponent<Image>();
                //1.ai is left button, 1.1ai is the right button
                if (buttonImageBg != null && playerButton.name == "1.2ai")
                {
                    buttonImageBg.sprite = characterSprite;
                }
                if (buttonImageBg != null && playerButton.name == "1.1ai")
                {
                    buttonImageBg.sprite = characterSpriteBg;
                }
            }
        }

        foreach (Button playerButton in playerButtons2v2)
        {
            string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
            if (selectedbuttonpvp == playerButton.name)
            {
                // Update the player select buttons with the character sprite
                PlayerPrefs.SetString("selectedbuttonpvp", "");

                Image buttonImage = playerButton.transform.GetChild(0).GetComponent<Image>();
                Image buttonImageBg = playerButton.GetComponent<Image>();
                if (buttonImage != null)
                {
                    buttonImage.sprite = characterSprite;
                    buttonImageBg.sprite = characterSpriteBg;
                    graphic2v2.gameObject.transform.GetChild(1).GetChild(0).gameObject.SetActive(true);
                    graphic2v2.gameObject.transform.GetChild(1).Find("add").gameObject.SetActive(false);
                }

            }
        }

        foreach (Button playerButton in playerButtons3v3)
        {
            string selectedbuttonpvp = PlayerPrefs.GetString("selectedbuttonpvp");
            if (selectedbuttonpvp == playerButton.name)
            {

                // Update the player select buttons with the character sprite
                PlayerPrefs.SetString("selectedbuttonpvp", "");

                Image buttonImage = playerButton.transform.GetChild(0).GetComponent<Image>();
                Image buttonImageBg = playerButton.GetComponent<Image>();
                if (buttonImage != null)
                {
                    buttonImage.sprite = characterSprite;
                    buttonImageBg.sprite = characterSpriteBg;
                    graphic3v3.gameObject.transform.GetChild(1).GetChild(0).gameObject.SetActive(true);
                    graphic3v3.gameObject.transform.GetChild(1).Find("add").gameObject.SetActive(false);
                }

            }
        }
    }
    public (Sprite, Sprite) GetCharacterSprite(string characterName)
    {
        // Assuming you have a dictionary or some logic to retrieve the corresponding sprite based on the character name
        // Implement the logic to return the sprite based on the character name
        string[] characterNames = CharacterSelectionScript.characterNames;
        foreach (string cName in characterNames)
        {
            if (cName == characterName)
            {
                Sprite characterSprite = CharacterSelectionScript.characterVsCardsLeft[System.Array.IndexOf(characterNames, characterName)];
                Sprite characterSpriteBg = CharacterSelectionScript.characterVsCardsRight[System.Array.IndexOf(characterNames, characterName)];
                return (characterSprite, characterSpriteBg);
            }
        }
        return (null, null);
        // Replace the return statement with your own code   
    }
}

