using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

using UnityEngine.Networking;
using System.Linq;

public class CurrentPlayerPicker : MonoBehaviour
{

    public GameObject serverManager;
    public int numberOfPlayers;

    public Text textfield;

    public GameObject sorryTaken;

    public GameObject selectionPanel;

    public GameObject errorPanel;
    public GameObject connectingPanel;

     public GameObject nextPanel;

    private string currentPlayer;

    private float elapsed = 0.0f;
    private float period = 1.0f;

    private bool selectionComplete;

    private string finalPlayerNumber;

    // CARD STUFF CARD STUFF CARD STUFF CARD STUFF
    public RawImage goalCard;
    public RawImage personCard;

    public RawImage goalCardView;
    public RawImage personaCardView;

    public List<Texture> goalCardImages;
    public List<Texture> personCardImages;


    //for action card selection during game running
    public Button actionButton;
    public RawImage actionCard;

    public GameObject actionCardView;
    
    public List<Texture> actionCardImages;


    //dictionary to map card images and unique IDs
    private Dictionary<string, int> personCardIDs;
    private Dictionary<string, int> goalCardIDs;
    private Dictionary<string, int> actionCardIDs;

    //mapping character cards and goal cards
    private Dictionary<int, List<int>> personToGoalCardMap;



    // Start is called before the first frame update
    void Start()
    {
        selectionComplete = false;
        finalPlayerNumber = "0";

        // Initialize dictionaries and assign unique IDs
        personCardIDs = new Dictionary<string, int>();
        goalCardIDs = new Dictionary<string, int>();
        actionCardIDs = new Dictionary<string, int>();

        // Assign IDs to character cards
        for (int i = 0; i < personCardImages.Count; i++)
        {
            personCardIDs[personCardImages[i].name] = i + 1; // ID starts from 1
        }

        // Assign IDs to goal cards
        for (int i = 0; i < goalCardImages.Count; i++)
        {
            goalCardIDs[goalCardImages[i].name] = i + 1; // ID starts from 1
        }

        // Assign IDs to action cards
        for (int i = 0; i < actionCardImages.Count; i++)
        {
            actionCardIDs[actionCardImages[i].name] = i + 1; // ID starts from 1
        }

        InitializePersonToGoalCardMap();  //initialize the character to goal cards

        //click actionButton to get the action card
        actionButton.onClick.AddListener(SelectActionCard);

    }

    // Update is called once per frame
    void Update()
    {
        if(selectionComplete)
            return;

        elapsed += Time.deltaTime;
        
        if (elapsed >= period) {
            elapsed = 0.0f;
            //Debug.Log("Inside");
            string currentGame = serverManager.GetComponent<CurrentGameConnect>().GetGameNumber();

            // GET ALL ALREADY SELECTED PLAYERS FROM SERVER
            // SET BUTTONS TO NOT ACTIVE OF THOSE PLAYERS
            string serverUrl_check = "https://smarthubs.media.tuwien.ac.at/api/is_player_available/"+ currentGame+ "/";
            for(int i = 1; i <= numberOfPlayers; i++)
            {
                //Debug.Log(i);
                StartCoroutine(AvaliablePlayers(serverUrl_check + i.ToString(), i.ToString()));
            }
        }
    }


    public void UpdatePlayerTexture(string clr)
    {
        this.gameObject.GetComponent<Image>().color = GameObject.Find("PlayerBtn" + clr).GetComponent<Button>().colors.normalColor;
    }

    public void SelectCards(string playerNumber, string gameNumber)
    {
        int randomPerson = Random.Range(0, personCardImages.Count);

        personCard.texture = personCardImages[randomPerson];
        personaCardView.texture = personCardImages[randomPerson];

        int personCardID = personCardIDs[personCard.texture.name];
        Debug.Log("person card ID: " + personCardID);
        
        //int range = 0;
        //int min = 0;
        
        /* if(finalPlayerNumber == "1")
        {
            range = 6;
        }
        if(finalPlayerNumber == "2")
        {
            min = 6;
            range = 12;
        }
        if(finalPlayerNumber == "3")
        {
            min = 12;
            range = 18;
        }
        if(finalPlayerNumber == "4")
        {
            min = 18;
            range = 24;
        }
        if(finalPlayerNumber == "5")
        {
            min = 24;
            range = 30;
        }
        if(finalPlayerNumber == "6")
        {
            min = 30;
            range = 36;
        }
        int randomGoal = Random.Range(min, range); */
        
        List<int> feasibleGoalCardIDs = personToGoalCardMap[personCardID]; //feasible goal card id for the selected character card

        // randomly select the goal cards from whole list
        int randomGoalIndex = Random.Range(0, feasibleGoalCardIDs.Count);
        int randomGoalID = feasibleGoalCardIDs[randomGoalIndex];

        Debug.Log("current feasible goal cards: " + randomGoalID);
        //Debug.Log("current feasible goal cards list: " + feasibleGoalCardIDs);
        Debug.Log("Current feasible goal cards list: " + string.Join(", ", feasibleGoalCardIDs));

        //get the texture of the seleccted goal cards
        string selectedGoalCardName = goalCardIDs.FirstOrDefault(x => x.Value == randomGoalID).Key;
        Texture selectedGoalCardTexture = goalCardImages.FirstOrDefault(x => x.name == selectedGoalCardName);
        
        // TELL THE SERVER THAT THE CARD IS TAKEN

        //goalCard.texture = goalCardImages[randomGoal];
        //goalCardView.texture = goalCardImages[randomGoal];

        goalCard.texture = selectedGoalCardTexture;
        goalCardView.texture = selectedGoalCardTexture;

        int goalCardID = goalCardIDs[goalCard.texture.name];
        Debug.Log("goal card ID: " + goalCardID);

        // Send the selected cards to the server
        StartCoroutine(UploadCharacterCard(gameNumber, personCardID));
        StartCoroutine(UploadGoalCard(gameNumber, goalCardID));

        nextPanel.SetActive(true);

    }
    
    // mapping character cards to goal cards
    private void InitializePersonToGoalCardMap()
    {
        personToGoalCardMap = new Dictionary<int, List<int>>
        {
            { 1, new List<int> { 1, 4, 6, 10, 12, 14, 15, 16, 17, 19, 20, 22, 23, 24, 26, 27, 29, 30, 31, 33, 34, 36, 37, 39, 40 } },
            { 2, new List<int> { 3, 6, 10, 22, 24, 29, 39, 40 } },
            { 3, new List<int> { 1, 4, 6, 10, 11, 12, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 36, 37, 39, 40 } },
            { 4, new List<int> { 1, 3, 4, 6, 10, 11, 12, 14, 15, 16, 17, 19, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 33, 39, 40 } },
            { 5, new List<int> { 1, 3, 6, 10, 12, 14, 15, 16, 17, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 36, 37, 39, 40 } },
            { 6, new List<int> { 1, 4, 6, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 33, 34, 36, 37, 39, 40 } },
            { 7, new List<int> { 3, 10, 11, 12, 14, 15, 16, 17, 18, 20, 21, 23, 28, 30, 31, 36, 37, 39, 40 } },
            { 8, new List<int> { 1, 3, 4, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 36, 37, 39, 40 } },
            { 9, new List<int> { 4, 6, 10, 11, 14, 15, 16, 17, 19, 20, 21, 23, 26, 27, 28, 29, 31, 33, 34, 36, 37, 39, 40 } },
            { 10, new List<int> { 4, 6, 10, 11, 15, 16, 20, 23, 24, 26, 27, 29, 30, 31, 33, 36, 37, 39, 40 } },
            { 11, new List<int> { 3, 10, 11, 16, 23, 24, 27, 29, 30, 31, 36, 37, 40 } }
        };

        Debug.Log("constrains between character and goal");
    }

   

    public IEnumerator AvaliablePlayers(string serverUrl, string player)
    {
        UnityWebRequest www = UnityWebRequest.Get(serverUrl);

        yield return www.SendWebRequest();

        if (www.result != UnityWebRequest.Result.Success)
        {
            //Debug.Log(www.error);
        }
        else
        {
            if(www.downloadHandler.text == "False")
            {
                GameObject[] playaz = GameObject.FindGameObjectsWithTag("pl");
                foreach(GameObject playa in playaz)
                {
                    if(playa.name.Contains(player))
                    {
                        playa.SetActive(false);
                    }
                }
            }
        }
    }


    public void choosePlayer(string playerNumber)
    {
        StartCoroutine(ChoosePlayer1(playerNumber));
    }

    public IEnumerator ChoosePlayer1(string playerNumber)
    {
        string currentGame = serverManager.GetComponent<CurrentGameConnect>().GetGameNumber();

        string serverUrl_check = "https://smarthubs.media.tuwien.ac.at/api/is_player_available/"+ currentGame+ "/" + playerNumber;

        UnityWebRequest www = UnityWebRequest.Get(serverUrl_check);

        yield return www.SendWebRequest();

        if (www.result != UnityWebRequest.Result.Success)
        {
            Debug.Log(www.error);
            errorPanel.SetActive(true);
            Debug.Log("choose player1 EPanel.");
        }
        else
        {
            if(www.downloadHandler.text == "False")
            {
                Debug.Log(www.error);
                sorryTaken.SetActive(true);
            }
            else 
            {
                StartCoroutine(ChoosePlayer2(playerNumber, currentGame));
            }
        }
    }

    public IEnumerator ChoosePlayer2(string playerNumber, string gameNumber)
    {
        string serverUrl = "https://smarthubs.media.tuwien.ac.at/api/select_player"; 

        WWWForm form = new WWWForm();
        
        form.AddField("game", gameNumber);
        form.AddField("player", playerNumber);

        using (UnityWebRequest www = UnityWebRequest.Post(serverUrl, form))
        {
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.Log(www.error);
                // PROMPT ERROR
                errorPanel.SetActive(true);
                Debug.Log("choose player2 EPanel.");
            }
            else
            {
                Debug.Log("Form upload complete!");
                
                // CLOSE THE PANEL
                selectionComplete = true;
                this.finalPlayerNumber = playerNumber;

                this.textfield.text = "Player " + playerNumber;
                UpdatePlayerTexture(playerNumber);

                // SUCCESS YOU CHOSE YOUR PLAYER
                SelectCards(playerNumber, gameNumber);

                // DIACTIVATE THE PANEL
                this.selectionPanel.SetActive(false);
            }
        }

        
    }

    public string GetPlayerNumber()
    {
        return this.finalPlayerNumber;
    }


    //transfer the charatcer card and goal cards to server
    private IEnumerator UploadCharacterCard(string gameNumber, int personCardID)  //upload the character cards
    {
        string serverUrl = "https://smarthubs.media.tuwien.ac.at/api/add_char_card_to_player";
        WWWForm form = new WWWForm();

        Debug.Log("charCard gameNumber: " + gameNumber);
        Debug.Log("charCard playerNumber: " + finalPlayerNumber);
        Debug.Log("charCard ID: " + personCardID);

        form.AddField("game", gameNumber);

        form.AddField("player", finalPlayerNumber);
        form.AddField("charid", personCardID);

        // Convert the person card texture to a byte array
        //byte[] personCardBytes = GetTextureBytes(personCard.texture as Texture2D);
        //form.AddBinaryData("characterCard", personCardBytes, "characterCard.png", "image/png");

        using (UnityWebRequest www = UnityWebRequest.Post(serverUrl, form))
        {
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.Log(www.error);
                errorPanel.SetActive(true);
                Debug.Log("character card EPanel.");
            }
            else
            {
                Debug.Log("Character card uploaded.");
            }
        }
    }


    private IEnumerator UploadGoalCard(string gameNumber, int goalCardID)  //upload the goal cards
    {
        string serverUrl = "https://smarthubs.media.tuwien.ac.at/api/add_card_to_player";
        WWWForm form = new WWWForm();

        Debug.Log("goalCard gameNumber: " + gameNumber);
        Debug.Log("goalCard playerNumber: " + finalPlayerNumber);
        Debug.Log("goalCard ID: " + goalCardID);

        form.AddField("game", gameNumber);
        form.AddField("player", finalPlayerNumber);
        form.AddField("cid", goalCardID);

        // Convert the goal card texture to a byte array
        //byte[] goalCardBytes = GetTextureBytes(goalCard.texture as Texture2D);
        //form.AddBinaryData("goalCard", goalCardBytes, "goalCard.png", "image/png");

        using (UnityWebRequest www = UnityWebRequest.Post(serverUrl, form))
        {
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.Log(www.error);
                errorPanel.SetActive(true);
                Debug.Log("goal card EPanel.");
            }
            else
            {
                Debug.Log("Goal card uploaded.");
            }
        }
    }

    /*private byte[] GetTextureBytes(Texture2D texture)
    {
        return texture.EncodeToPNG();
    }*/


    // Action card selection
    public void SelectActionCard()
    {
        actionCardView.gameObject.SetActive(true);

        int randomAction = Random.Range(0, actionCardImages.Count);

        actionCard.texture = actionCardImages[randomAction];

        int actionCardID = actionCardIDs[actionCard.texture.name];

        Debug.Log("Selected action card texture: " + actionCard.texture.name);
        Debug.Log("Action card ID: " + actionCardID);

        // Send the selected action card to the server
        StartCoroutine(UploadActionCard(actionCardID));
        
    }

    // Transfer the action card to server (server should be able to adding multiple action card IDs)
    private IEnumerator UploadActionCard(int actionCardID)
    {
        string serverUrl = "https://smarthubs.media.tuwien.ac.at/api/add_action_card_to_player";
        WWWForm form = new WWWForm();
        form.AddField("game", serverManager.GetComponent<CurrentGameConnect>().GetGameNumber());
        form.AddField("player", finalPlayerNumber);
        form.AddField("actionCardID", actionCardID.ToString());

        using (UnityWebRequest www = UnityWebRequest.Post(serverUrl, form))
        {
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.Log(www.error);
                errorPanel.SetActive(true);
                Debug.Log("action card EPanel.");
            }
            else
            {
                Debug.Log("Action card uploaded.");
            }
        }
    }

   

}