using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UIElements;

/// <summary>
///     singleton for a single source of truth game state and flow management
/// </summary>
public class GameManager : MonoBehaviour
{
    /// <summary>
    ///     enum for available menus in the game, for use with <c>ShowMenu()</c>
    /// </summary>
    public enum DisplayState
    {
        Nothing,
        PlayView,
        LeaderboardView,
        AccountView,
    }

    /// <summary>
    ///     singleton pattern: define instance field for accessing the singleton elsewhere
    /// </summary>
    public static GameManager Instance;
    
    /// <summary>
    ///     the current display state of the game
    /// </summary>
    [SerializeField] private DisplayState state = DisplayState.Nothing;

    /// <summary>
    ///     the visual element object for game ui (hud/prompts/tooltips)
    /// </summary>
    private VisualElement _ui;

    /// <summary>
    ///     backend object for handling communication with the firebase backend
    /// </summary>
    public Backend Backend;
    
    /// <summary>
    ///     the local player data object for storing player data
    /// </summary>
    private LocalPlayerData _localPlayerData;

    /// <summary>
    ///     enforces singleton behaviour; sets doesn't destroy on load and checks for multiple instances
    /// </summary>
    private void Awake()
    {
        // check if instance hasn't been set yet
        if (Instance == null)
        {
            Debug.Log("awake as singleton instance, setting self as the forever-alive instance");
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        // check if instance is already set and it's not this instance
        else if (Instance != null && Instance != this)
        {
            Debug.Log("awake as non-singleton instance, destroying self");
            Destroy(gameObject);
        }
    }

    private void Start()
    {
        SetDisplayState(DisplayState.PlayView);
        
        // load the local player data and refresh the ui
        _localPlayerData = new LocalPlayerData();
        _localPlayerData.LoadFromTheWorld();
        
        // register a callback to refresh the ui when the player signs in
        Backend.RegisterOnSignInCallback(_ =>
        {
            _localPlayerData.LoadFromTheWorld();
        });
    }

    /// <summary>
    ///     called when the game object is enabled
    /// </summary>
    private void OnEnable()
    {
        Backend = new Backend();
        Backend.Initialise();
    }

    /// <summary>
    ///     called when the game object is disabled
    /// </summary>
    private void OnDestroy()
    {
        Backend.Cleanup();
    }

    /// <summary>
    ///     function to show a menu based on the enum passed,
    ///     and any other necessary actions
    /// </summary>
    /// <param name="newDisplayState">the game menu to show</param>
    public void SetDisplayState(DisplayState newDisplayState)
    {
    }
}