using UnityEngine;
using UnityEngine.Networking;
using System.Threading.Tasks;
using System;

public class CoinWalletSystem : MonoBehaviour
{
    private static CoinWalletSystem _instance;
    public static CoinWalletSystem Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindAnyObjectByType<CoinWalletSystem>();
                if (_instance != null)
                {
                    #if UNITY_EDITOR
                    if (Application.isPlaying)
                    {
                        DontDestroyOnLoad(_instance.gameObject);
                    }
                    #else
                    DontDestroyOnLoad(_instance.gameObject);
                    #endif
                }
            }
            return _instance;
        }
    }

    private int walletCoins = 0;
    private bool isInitialized = false;
    private string baseUrl = "http://127.0.0.1:8001/api";
    private CoinWalletUIManager uiManager;

    private void Awake()
    {
        if (_instance == null)
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else if (_instance != this)
        {
            Destroy(gameObject);
        }
    }

    private async void Start()
    {
        uiManager = FindAnyObjectByType<CoinWalletUIManager>();
        if (!isInitialized)
        {
            Debug.Log("Starting wallet initialization...");
            await InitializeWallet();
        }
    }

    public async Task<bool> InitializeWallet()
    {
        try
        {
            bool success = await FetchWalletBalance();
            return success;
        }
        catch (Exception e)
        {
            Debug.LogError($"Failed to initialize wallet: {e.Message}");
            return false;
        }
    }

    public bool IsInitialized()
    {
        return isInitialized;
    }

    private async Task<bool> FetchWalletBalance()
    {
        try
        {
            string url = $"{baseUrl}/wallet/?format=json"; // Use JSON format explicitly
            Debug.Log($"Sending GET request to: {url}");

            using (UnityWebRequest request = UnityWebRequest.Get(url))
            {
                string token = PlayerPrefs.GetString("AuthToken");
                if (string.IsNullOrEmpty(token))
                {
                    Debug.LogError("No auth token found in PlayerPrefs");
                    return false;
                }

                // Set Authorization and Accept headers
                request.SetRequestHeader("Authorization", $"Token {token}");
                request.SetRequestHeader("Accept", "application/json"); // Explicitly request JSON
                Debug.Log($"Authorization header set: Token {token}");

            var operation = request.SendWebRequest();
            while (!operation.isDone)
                await Task.Yield();

            Debug.Log($"Request completed with status: {request.result}");

                if (request.result == UnityWebRequest.Result.Success)
                {
                    Debug.Log($"Response received: {request.downloadHandler.text}");

                    JsonData walletData = JsonUtility.FromJson<JsonData>(request.downloadHandler.text);
                    if (walletData != null)
                    {
                        walletCoins = walletData.balance;
                        Debug.Log($"Wallet balance updated: {walletCoins}");
                        return true;
                    }
                    else
                    {
                        Debug.LogError("Failed to parse JSON response. Response text is empty or invalid.");
                        return false;
                    }
                }
                else
                {
                    Debug.LogError($"Request failed with status: {request.responseCode}, error: {request.error}");
                    return false;
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"Exception in FetchWalletBalance: {e.Message}");
            return false;
        }
    }

    public async Task AddCoins(int amount)
    {
#if UNITY_EDITOR
        // In development mode, simulate the API call
        try
        {
            Debug.Log($"Development mode: Simulating adding {amount} coins");
            await Task.Delay(500);
            walletCoins += amount;
            UpdateWalletUI();
            Debug.Log($"Development mode: Successfully added {amount} coins. New balance: {walletCoins}");
            return;
        }
        catch (Exception e)
        {
            Debug.LogError($"Development mode: Error adding coins: {e.Message}");
            throw;
        }
#else
        try
        {
            // Create JSON payload instead of form data
            string jsonPayload = JsonUtility.ToJson(new WalletUpdateRequest 
            { 
                amount = amount,
                operation = "add"
            });

            using (UnityWebRequest request = new UnityWebRequest($"{baseUrl}/wallet/update/", "POST"))
            {
                byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonPayload);
                request.uploadHandler = new UploadHandlerRaw(bodyRaw);
                request.downloadHandler = new DownloadHandlerBuffer();
                
                string token = PlayerPrefs.GetString("AuthToken");
                if (string.IsNullOrEmpty(token))
                {
                    Debug.LogError("No auth token found in PlayerPrefs");
                    throw new Exception("Authentication token not found");
                }

                // Set proper headers
                request.SetRequestHeader("Authorization", $"Token {token}");
                request.SetRequestHeader("Content-Type", "application/json");
                request.SetRequestHeader("Accept", "application/json");
                
                Debug.Log($"Sending request with payload: {jsonPayload}");
                
                var operation = request.SendWebRequest();
                while (!operation.isDone)
                    await Task.Yield();

                if (request.result == UnityWebRequest.Result.Success)
                {
                    Debug.Log($"Successfully added {amount} coins. Response: {request.downloadHandler.text}");
                    await FetchWalletBalance();
                    UpdateWalletUI();
                }
                else
                {
                    string errorMessage = $"Failed to add coins. Status: {request.responseCode}, Error: {request.error}, Response: {request.downloadHandler.text}";
                    Debug.LogError(errorMessage);
                    throw new Exception(errorMessage);
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"Error adding coins: {e.Message}");
            throw;
        }
#endif
    }

    private void UpdateWalletUI()
    {
        try
        {
            if (uiManager == null)
            {
                uiManager = FindAnyObjectByType<CoinWalletUIManager>();
            }

            if (uiManager != null)
            {
                Debug.Log($"Updating UI with walletCoins: {walletCoins}");
                uiManager.UpdateAllWallets(walletCoins);
            }
            else
            {
                Debug.LogWarning("CoinWalletUIManager not found, creating new instance");
                var go = new GameObject("CoinWalletUIManager");
                uiManager = go.AddComponent<CoinWalletUIManager>();
                uiManager.UpdateAllWallets(walletCoins);
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"Error updating wallet UI: {e.Message}");
        }
    }

    public int GetCurrentBalance()
    {
        return walletCoins;
    }

    public async Task ResetCoins()
    {
        try
        {
            WWWForm form = new WWWForm();
            form.AddField("amount", 0);
            form.AddField("operation", "reset");

            using (UnityWebRequest request = UnityWebRequest.Post($"{baseUrl}/wallet/update/", form))
            {
                string token = PlayerPrefs.GetString("AuthToken");
                request.SetRequestHeader("Authorization", $"Token {token}");

                var operation = request.SendWebRequest();
                while (!operation.isDone)
                    await Task.Yield();

                if (request.result == UnityWebRequest.Result.Success)
                {
                    walletCoins = 0;
                    UpdateWalletUI();
                    Debug.Log("Wallet reset successful");
                }
                else
                {
                    Debug.LogError($"Failed to reset wallet: {request.error}");
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"Error resetting wallet: {e.Message}");
        }
    }

    public async Task RefreshWallet()
    {
        await FetchWalletBalance();
        UpdateWalletUI();
    }

    [Serializable]
    private class JsonData
    {
        public int balance;
    }

    // Add this class to match your server's expected request format
    [Serializable]
    private class WalletUpdateRequest
    {
        public int amount;
        public string operation;
    }
}
