/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Entity, world } from "@minecraft/server";
import { Server } from "./serverBuilder.js";
const objective = world.scoreboard.getObjective("GAMETEST_DB") ?? world.scoreboard.addObjective("GAMETEST_DB", "");
export class Database {
    constructor(name, provider = world, reviver) {
        this.name = name;
        if (this.provider instanceof Entity)
            this.name += this.provider.id;
        const table = this.getScoreboardParticipant();
        this.data = table ? JSON.parse(JSON.parse(`"${table.displayName}"`), reviver)[1] : {};
        this.provider = provider;
    }
    /**
     * Save a value or update a value in the Database under a key
     * @param key The key you want to save the value as
     * @param value The value you want to save
     * @example Database.set('Test Key', 'Test Value');
     */
    set(key, value) {
        this.data[key] = value;
    }
    /**
     * Get the value of the key
     * @param key
     * @returns value
     * @example Database.get('Test Key');
     */
    get(key) {
        return this.data[key];
    }
    /**
     * Check if the key exists in the table
     * @param key
     * @returns Whether the key exists
     * @example Database.has('Test Key');
     */
    has(key) {
        return key in this.data;
    }
    /**
     * Delete the key from the table
     * @param key
     * @example Database.delete('Test Key');
     */
    delete(key) {
        delete this.data[key];
    }
    /**
     * Clear everything in the table
     * @example Database.clear()
     */
    clear() {
        this.data = {};
    }
    /**
     * Save all changes to the scoreboard.
     * @example Database.save()
     */
    save() {
        const table = this.getScoreboardParticipant();
        if (table)
            Server.runCommand(`scoreboard players reset "${table.displayName}" GAMETEST_DB`);
        Server.runCommand(`scoreboard players add ${JSON.stringify(JSON.stringify(["wedit:" + this.name, this.data]))} GAMETEST_DB 0`);
    }
    /**
     * Get all the keys in the table
     * @returns Array of keys
     * @example Database.keys();
     */
    keys() {
        return Object.keys(this.data);
    }
    /**
     * Get all the values in the table
     * @returns Array of values
     * @example Database.values();
     */
    values() {
        return Object.values(this.data);
    }
    /**
     * Get all the keys and values in the table in pairs
     * @returns Array of key/value pairs
     * @example Database.entries();
     */
    entries() {
        return Object.entries(this.data);
    }
    /**
     * Check if all the keys exists in the table
     * @param keys
     * @returns Whether all keys exist
     * @example Database.hasAll('Test Key', 'Test Key 2', 'Test Key 3');
     */
    hasAll(...keys) {
        return keys.every((k) => this.has(k));
    }
    /**
     * Check if any of the keys exists in the table
     * @param keys
     * @returns Whether any key exists
     * @example Database.hasAny('Test Key', 'Test Key 2', 'Test Key 3');
     */
    hasAny(...keys) {
        return keys.some((k) => this.has(k));
    }
    getScoreboardParticipant() {
        for (const table of objective.getParticipants()) {
            const name = table.displayName;
            if (name.startsWith(`[\\"wedit:${this.name}\\"`)) {
                return table;
            }
        }
    }
}
