using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
/// Keep track of all users
/// </summary>
[CreateAssetMenu(menuName = "Create new Scriptable/UserList")]
public class UserList : ScriptableObject
{
    /// <summary>
    /// Helper class to enable serialization of the UserList class
    /// (<c>ScriptableObkect</c>s cannot be serialized)
    /// </summary>
    [Serializable]
    public class StoredUserList
    {
        /// <summary>
        /// The index of the current/last logged in user in the <c>storedUsers</c> list
        /// </summary>
        public int currentUserIndex;
        /// <summary>
        /// A list containing all users (which can be serialized)
        /// </summary>
        public List<User> storedUsers = new List<User>();
    }

    /// <summary>
    /// Reference to the serializable version of <c>UserList</c>
    /// </summary>
    [SerializeField]
    private StoredUserList storedUserList = new StoredUserList();

    /// <summary>
    /// Path of the <c>.json</c>-file to store all serialized data
    /// </summary>
    public static string PATH = null;

    /// <summary>
    /// OnEnable will make sure the <c>PATH</c>-variable is correctly initialized
    /// </summary>
    void OnEnable()
    {
        PATH = $"{Application.dataPath}/users.json";
        Load();
    }

    /// <summary>
    /// Create a new user
    /// </summary>
    /// <param name="name">The username of the new user</param>
    /// <param name="avatar">Reference to the user avatar</param>
    /// <returns>A newly created user</returns>
    public User CreateNewUser(string name, Sprite avatar)
    {
        User user = new User();
        user.username = name;
        user.avatar = avatar;
        return user;
    }

    /// <summary>
    /// Create a new user and save (add to list)
    /// </summary>
    /// <param name="name">The username of the new user</param>
    /// <param name="avatar">Reference to the user avatar</param>
    /// <returns>A newly created user</returns>
    public User CreateAndAddNewUser(string name, Sprite avatar)
    {
        User user = CreateNewUser(name, avatar);
        storedUserList.storedUsers.Add(user);
        Save();
        return user;
    }

    /// <summary>
    /// Get a user by username
    /// </summary>
    /// <param name="username">The username of the user</param>
    /// <returns><c>User</c>-object if a user with such username was found, <c>null</c> otherwise</returns>
    public User GetUserByUsername(string username)
    {
        foreach (User user in storedUserList.storedUsers)
            if (user.username == username) return user;

        return null;
    }

    /// <summary>
    /// Get a list of all users currently stored
    /// </summary>
    /// <returns>A list of all users</returns>
    public List<User> GetUsers()
    {
        return storedUserList.storedUsers;
    }

    /// <summary>
    /// Get the current logged in user
    /// </summary>
    /// <returns>The current logged in user</returns>
    public User GetCurrentUser()
    {
        return storedUserList.storedUsers[storedUserList.currentUserIndex];
    }

    /// <summary>
    /// Save the users
    /// </summary>
    public void Save()
    {
        string json = JsonUtility.ToJson(storedUserList);
        File.CreateText(PATH).Close();
        File.WriteAllText(PATH, json);
    }

    /// <summary>
    /// Override the current content of the userlist by what is stored on disk
    /// </summary>
    public void Load()
    {
        try
        {
            storedUserList.storedUsers.Clear();

            string text = File.ReadAllText(PATH);
            storedUserList = JsonUtility.FromJson<StoredUserList>(text);
        }
        catch (FileNotFoundException) { Debug.Log($"Path '{PATH}' not found"); }
    }
}
