package jesse.keeblarcraft.ConfigMgr;

import java.util.ArrayList;
import java.util.List;

import jesse.keeblarcraft.Utils.DirectionalVec;

public class GeneralConfig {
    private static GeneralConfig static_inst;
    ConfigManager cfgMgr = new ConfigManager();
    private ImplementedConfig config;

    public static GeneralConfig GetInstance() {
        if (static_inst == null) {
            static_inst = new GeneralConfig();
        }

        return static_inst;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         GetConfig
    ///
    /// @brief      Returns the mods general configuration file object
    ///
    /// @return     The configuration object
    /////////////////////////////////////////////////////////////////////////////
    public ImplementedConfig GetConfig() {
        if (config == null) {
            config = new ImplementedConfig();
            FlashConfig();
        }

        return config;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         GeneralConfig
    ///
    /// @brief      Constructs the general configuration file for the project
    /////////////////////////////////////////////////////////////////////////////
    public GeneralConfig() {
        Boolean existingFile = false;
        try {
            config = cfgMgr.GetJsonObjectFromFile("general.json", ImplementedConfig.class);

            existingFile = true;
        } catch(Exception e) {
            System.out.println("FAILED TO READ IN GENERALCONFIG");
            e.printStackTrace();
        }

        if (!existingFile) {
            config = new ImplementedConfig();
            FlashConfig();
        }

        if (config == null) {
            config = new ImplementedConfig();
            FlashConfig();
        }
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         GetSpawnCoords
    ///
    /// @brief      Gets the coordinates for the global spawn
    ///
    /// @return     A vector containing how a player should spawn in or null if not
    ///             set yet.
    /////////////////////////////////////////////////////////////////////////////
    public DirectionalVec GetSpawnCoords() {
        System.out.println("Among us");
        System.out.println("GetSpawnCoords called. is global_spawn null? " + (config.global_spawn == null ? "YES": "NO"));
        return config.global_spawn;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         SetSpawnCoords
    ///
    /// @brief      Sets the coordinates for the global spawn
    /////////////////////////////////////////////////////////////////////////////
    public void SetSpawnCoords(DirectionalVec vec) {
        config.global_spawn = vec;
        FlashConfig();
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         GetSQLPassword
    ///
    /// @brief      Returns the SQL password set in the text config
    /////////////////////////////////////////////////////////////////////////////
    public String GetSQLPassword() {
        return config.sqlPassword;
    }

    public String GetSQLUsername() {
        return config.sqlUsername;
    }

    public String GetSQLAddress() {
        return config.sqlAddress;
    }

    public String GetSQLDatabase() {
        return config.sqlDatabaseName;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         IsNewPlayer
    ///
    /// @param[in]  uuid is the player uuid
    ///
    /// @brief      Checks to see if player uuid has ever joined. If not, then add
    ///             to global list of uuids who have joined.
    ///
    /// @return     True if player is new, false if not
    /////////////////////////////////////////////////////////////////////////////
    public Boolean IsNewPlayer(String uuid) {
        System.out.println("Is config null? " + (config == null ? "YES" : "NO"));
        System.out.println("IsNewPlayer called. List has: " + config.playerList);
        Boolean isNew = !config.playerList.contains(uuid);

        System.out.println("Value of isNew is " + isNew);

        if (isNew) {
            config.playerList.add(uuid);
            FlashConfig();
        }
        return isNew;
    }


    /////////////////////////////////////////////////////////////////////////////
    /// @fn         GetMOTD
    ///
    /// @brief      String object with the MOTD of the server
    /////////////////////////////////////////////////////////////////////////////
    public String GetMOTD() {
        return config.MOTD;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @class      ImplementedConfig is the configuration class holder
    /////////////////////////////////////////////////////////////////////////////
    private class ImplementedConfig {
        public String MOTD = "Welcome to the server! Have fun!";
        public String sqlAddress = "localhost";
        public String sqlDatabaseName = "keeblarcraft";
        public String sqlUsername = "SQL_USERNAME";
        public String sqlPassword = "SQL_PASSWORD";

        // This is lazy, but this will fill with every unique UUID that has joined the server. This is how I am checking
        // to see if a player has just joined the server for a first time or not
        public List<String> playerList = new ArrayList<>();
        DirectionalVec global_spawn;
    }

    /////////////////////////////////////////////////////////////////////////////
    /// @fn         FlashConfig
    ///
    /// @brief      String object with the MOTD of the server
    /////////////////////////////////////////////////////////////////////////////
    private void FlashConfig() {
        System.out.println("Attempting to write generalconfig to file. Is null? " + (config == null ? "YES" : "NO"));
        cfgMgr.WriteToJsonFile("general.json", config);
    }
}
