using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.EventSystems;
using System;
using System.Linq;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;


// Player Details for the Game
[System.Serializable]
public class Profile_PlayerDet {
    public int xp;
    public string rank;
    public string prevRank;
    public int overall_matches;
    public int win_streak;
    public int loss_streak;
    public int overall_wins;
    public int overall_losses;
    public int rank_level;
    public int rank_game;
    public int eliminations;
    public int deaths;
    public int revives;
}

// Add new class for user data
[System.Serializable]
public class UserData
{
    public string username;
    public string email;
    public string country;
}

public class ProfileManager : MonoBehaviour{
    private const string player_profileData = "Player_RewardsData"; //Reference to PlayerPrefs related to Profile Data 
    Profile_PlayerDet retrieved_playerData;
    Profile_PlayerDet playerData;

    //Show values on UI
    public TMP_Text rank_text;
    public TMP_Text matches_text;
    public TMP_Text wins_text;
    public TMP_Text loss_text;
    public TMP_Text xp_text;
    public TMP_Text deaths_text;
    public TMP_Text revives_text;
    public TMP_Text profile_name;
    public TMP_Text country_text;

    public GameObject backButton; //Reference to the back button in the Profile UI
    public Image rankImg; //Reference to the rank Image in the Profile UI

    //A GameObject array of icons to represent Ranks
    public Sprite[] rankIcons;

    // Add UI reference for logout button
    public Button logoutButton;

    // Add scene name constant
    private const string AUTH_SCENE_NAME = "AuthenticationScene";

    private string logoutUrl = "http://127.0.0.1:8001/auth/token/logout/";

    private void OnEnable(){
        // Load player data and update text field immediately upon component creation
        Start();
        EventSystem.current.SetSelectedGameObject(backButton);
        StartCoroutine(FetchUserProfile());
    }

    private IEnumerator FetchUserProfile()
    {
        string userProfileUrl = "http://127.0.0.1:8001/auth/users/me/";
        string authToken = PlayerPrefs.GetString("AuthToken");
        
        Debug.Log($"Attempting to fetch profile with token: {authToken}");  // Debug token

        using (UnityWebRequest request = UnityWebRequest.Get(userProfileUrl))
        {
            request.SetRequestHeader("Authorization", $"Token {authToken}");

            yield return request.SendWebRequest();

            Debug.Log($"Raw API Response: {request.downloadHandler.text}");  // Debug response

            if (request.result == UnityWebRequest.Result.Success)
            {
                try
                {
                    UserData userData = JsonUtility.FromJson<UserData>(request.downloadHandler.text);
                    Debug.Log($"Parsed username: {userData.username}");  // Debug parsed username
                    
                    if (!string.IsNullOrEmpty(userData.username))
                    {
                        profile_name.text = userData.username.ToUpper();
                        Debug.Log($"Profile name updated to: {profile_name.text}");  // Debug UI update
                    }
                    if (!string.IsNullOrEmpty(userData.country))
                    {
                        country_text.text = userData.country.ToUpper();
                    }
                }
                catch (System.Exception e)
                {
                    Debug.LogError($"Error parsing user data: {e.Message}");
                    Debug.LogError($"Response: {request.downloadHandler.text}");
                }
            }
            else
            {
                Debug.LogError($"Failed to fetch user profile: {request.error}");
                Debug.LogError($"Response Code: {request.responseCode}");
                Debug.LogError($"Response: {request.downloadHandler.text}");
            }
        }
    }

    // Start is called before the first frame update
    void Start(){

        // Check if the PlayerPrefs for Profile has been assigned 
        if (PlayerPrefs.HasKey(player_profileData)){
            //Load Player Data
            retrieved_playerData = LoadPlayerData();

            //Matches Text
            if (retrieved_playerData.overall_matches != 0){
                StartCoroutine(Animate_Text(matches_text, retrieved_playerData.overall_matches));
            }else{
                matches_text.text = (retrieved_playerData.overall_matches).ToString();
            }

            //Wins Text
            if (retrieved_playerData.overall_wins != 0){
                Debug.Log(retrieved_playerData.overall_wins);
                StartCoroutine(Animate_Text(wins_text, retrieved_playerData.overall_wins));
            }else{
                wins_text.text = (retrieved_playerData.overall_wins).ToString();
            }

            //Loss Text
            if (retrieved_playerData.overall_losses != 0){
                StartCoroutine(Animate_Text(loss_text, retrieved_playerData.overall_losses));
            }else{
                loss_text.text = (retrieved_playerData.overall_losses).ToString();
            }

            //XP Text
            if (retrieved_playerData.xp != 0){
                StartCoroutine(Animate_Text(xp_text, retrieved_playerData.xp));
            }else{

                if (retrieved_playerData.xp < 0){
                    retrieved_playerData.xp = 0;
                    SavePlayerData(retrieved_playerData);
                }
                xp_text.text = (retrieved_playerData.xp).ToString();
            }

            //Deaths Text
            if (retrieved_playerData.deaths != 0){
                StartCoroutine(Animate_Text(deaths_text, retrieved_playerData.deaths));
            }else{
                deaths_text.text = (retrieved_playerData.deaths).ToString();
            }

            //Revives Text
            if (retrieved_playerData.revives != 0){
                StartCoroutine(Animate_Text(revives_text, retrieved_playerData.revives));
            }else{
                revives_text.text = (retrieved_playerData.revives).ToString();
            }

            //Rank text
            rank_text.text = retrieved_playerData.rank + " " + retrieved_playerData.rank_level; //Diamond 1

            //Rank Level
            profile_name.text = "LEVEL " + retrieved_playerData.rank_level;

            //Displaying the Rank Icon
            string rankIconReference = retrieved_playerData.rank + retrieved_playerData.rank_level;
            foreach (Sprite spr in rankIcons){
                if (spr.name == rankIconReference){
                    rankImg.sprite = spr;
                }
            }

        }else{ //If no rewards data saved, start somewhere, save and load
            playerData = new Profile_PlayerDet { xp = 0, rank = "Bronze", prevRank = "Bronze", overall_matches = 0, win_streak = 0, loss_streak = 0, overall_wins = 0, overall_losses = 0, rank_level = 1, rank_game = 0,
            eliminations = 0, deaths = 0, revives = 0 };

            SavePlayerData(playerData); //Saves the player's mission_progress data
            retrieved_playerData = LoadPlayerData();
        }

        // Setup logout button
        if (logoutButton != null)
        {
            logoutButton.onClick.AddListener(LogoutUser);
        }
    }


    //Function to Animate Text
    private IEnumerator Animate_Text(TMP_Text text_component, int targetIntValue){
        float animationDuration = 1.0f; // You can adjust the duration of the animation

        for (float t = 0f; t < 1.0f; t += Time.deltaTime / animationDuration){
            int animatedValue = Mathf.RoundToInt(Mathf.Lerp(0, targetIntValue, t));
            text_component.text = animatedValue.ToString();
            yield return null;
        }

        text_component.text = targetIntValue.ToString();
    }


    // Update is called once per frame
    void Update(){
        
    }


    /* PLAYERPREFS used in this Script */
    // Save player data to PlayerPrefs
    private void SavePlayerData(Profile_PlayerDet data){
        string jsonData = JsonUtility.ToJson(data);
        PlayerPrefs.SetString(player_profileData, jsonData); // Details stored as "PlayerData"
        PlayerPrefs.Save();
    }

    // Load player data from PlayerPrefs
    Profile_PlayerDet LoadPlayerData(){
        string jsonData = PlayerPrefs.GetString(player_profileData, "{}"); // Details were stored as "PlayerData"
        return JsonUtility.FromJson<Profile_PlayerDet>(jsonData);
    }



    //Add MATCHES after match starts, whenever a match starts
    // public void addMatch(){
    //     retrieved_playerData = LoadPlayerData();
    //     retrieved_playerData.overall_matches = retrieved_playerData.overall_matches + 1;

    //     SavePlayerData(retrieved_playerData);
    //     Debug.Log("Matches: " + (retrieved_playerData.overall_matches).ToString());
    // }


    // //Add WINS after match, if player wins
    // public void addWins(){
    //     retrieved_playerData = LoadPlayerData();
    //     retrieved_playerData.overall_wins = retrieved_playerData.overall_wins + 1;

    //     SavePlayerData(retrieved_playerData);
    //     Debug.Log("Wins: " + (retrieved_playerData.overall_wins).ToString());
    // }


    // //Add LOSS after match, if player loses
    // public void addLoss(){
    //     retrieved_playerData = LoadPlayerData();
    //     retrieved_playerData.overall_losses = retrieved_playerData.overall_losses + 1;

    //     SavePlayerData(retrieved_playerData);
    //     Debug.Log("Losses: " + (retrieved_playerData.overall_losses).ToString());
    // }


    public void LogoutUser()
    {
        StartCoroutine(LogoutUserCoroutine());
    }

    private IEnumerator LogoutUserCoroutine()
    {
        string token = PlayerPrefs.GetString("AuthToken", "");
        Debug.Log($"Current token value: {token}");

        if (string.IsNullOrEmpty(token))
        {
            Debug.Log("No token found, performing direct logout");
            HandleLogout();
            yield break;
        }

        using (UnityWebRequest request = new UnityWebRequest(logoutUrl, "POST"))
        {
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Authorization", $"Token {token}");
            request.SetRequestHeader("Content-Type", "application/json");

            Debug.Log($"Sending logout request with header: Token {token}");
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.Success)
            {
                Debug.Log("Logout successful from server");
                HandleLogout();
            }
            else
            {
                Debug.LogError($"Logout failed: {request.error}");
                Debug.LogError($"Response: {request.downloadHandler.text}");
                // Force logout even if server request fails
                HandleLogout();
            }
        }
    }

    private void HandleLogout()
    {
        Debug.Log("Performing logout cleanup");
        // Clear all authentication-related data
        PlayerPrefs.DeleteKey("AuthToken");
        PlayerPrefs.Save();
        GameInitialize.Instance?.SetUserAuthenticated(false);
        
        // Return to authentication scene
        SceneManager.LoadScene("Scenes/AuthenticationScene");
    }

    private void OnDestroy()
    {
        if (logoutButton != null)
        {
            logoutButton.onClick.RemoveListener(LogoutUser);
        }
    }

}
