const { throwTypeError } = require("./Errors");

/**
 * Prepares a new insertion
 */
class Insert {
    #instance;
    #database;
    #into;

    #data;
    
    constructor(instance, defaultDatabase, into){
        this.#instance = instance;
        this.#database = defaultDatabase;
        this.#into = into;
    }

    /**
     * Selects a database for this query
     * @param {String} database - Name of the database 
     * @returns {this}
     */
    selectDatabase(database){
        if (!database) throw new Error("database must not be empty");
        if (typeof database !== "string") throwTypeError("string", database);
        this.#database = database;
        return this;
    }

    /**
     * The data (rows) to insert
     * @param {Array<Object>} objects - Array containing objects to insert, where the key represents the column-name. All objects must have the same structure! 
     * @returns {this}
     */
    data(objects=[]){
        if (!Array.isArray(objects)) throwTypeError("array", objects);
        if (objects.length===0) throw new Error("data objects must not be empty");
        this.#data = objects;
        return this;
    }

    /**
     * Executes the prepared querry
     * @returns {Any}
     */
    async execute(){
        if (!this.#data) throw new Error("Insert: tried to insert without data");
        if (!this.#instance.isConnected()) throw new Error(`Can't execute query: Instance has no connection`);
        if (!this.#database) throw new Error(`Can't execute query: Database not selected`);

        const columns = Object.keys(this.#data[0]);
        const queryString = `INSERT INTO ${this.#database}.${this.#into} (${columns.toString()}) VALUES ?`;

        const values = [];
        for (let obj of this.#data){
            let thisRow = [];
            for (let key of columns){
                thisRow.push(obj[key]);
            }
            values.push(thisRow);
        }

        return await this.#instance.queryRaw(queryString, [values]);
    }
}

module.exports = Insert;