import { GameSaveStateMetadata } from "../../../../view/game/save/GameSaveStateMetadata.js";
import { array_pick_best_element } from "../../core/collection/array/array_pick_best_element.js";
import { EnginePlugin } from "../plugin/EnginePlugin.js";

class GameStateLoader extends EnginePlugin {

    id = 'game-state-loader';

    /**
     *
     * @type {Storage}
     */
    storage = null;

    async startup() {
        this.storage = this.engine.storage;
    }

    save(name, resolve, reject, progress) {
        const engine = this.engine;

        const currentScene = engine.sceneManager.current_scene;


        /**
         *
         * @type {GameSaveStateManager}
         */
        const gameSaves = engine.plugins.getById('game-save-state-manager');

        const saveComplete = gameSaves.store({ scene: currentScene, name });
        saveComplete.then(resolve, reject);

    }

    /**
     * @deprecated
     * @param {string} name
     * @param {function} resolve
     * @param {function} reject
     * @param {function} progress
     */
    legacyLoad(name, resolve, reject, progress) {
        console.warn('legacyLoad', name);

        this.storage.loadBinary(name, resolve, reject, progress);
    }

    /**
     * @deprecated
     * @param name
     * @param resolve
     * @param reject
     */
    legacyExists(name, resolve, reject) {
        console.warn('legacyExists', name);

        this.storage.contains(name, resolve, reject);
    }

    /**
     *
     * @param {string} name
     * @param {function(ArrayBuffer)} resolve
     * @param {function(reason:*)} reject
     * @param {function(number)} [progress]
     */
    load(name, resolve, reject, progress) {
        const engine = this.engine;


        /**
         *
         * @type {GameSaveStateManager}
         */
        const gameSaves = engine.plugins.getById('game-save-state-manager');

        gameSaves.update()
            .then(() => {
                /**
                 *
                 * @type {Array<GameSaveStateMetadata>}
                 */
                const matches = gameSaves.data.filter(m => {

                    if (m.locked) {
                        return false;
                    }

                    if (m.name === name) {
                        return true;
                    } else {
                        return false;
                    }
                });

                //find most recent
                const mostRecent = array_pick_best_element(matches, m => m.timestamp);


                if (mostRecent === undefined) {
                    //try legacy
                    return new Promise((lResolve, lReject) => this.legacyLoad(name, lResolve, lReject, progress));

                } else {

                    return gameSaves.loadData(mostRecent.id);
                }

            }).then(resolve, reject);
    }

    /**
     *
     * @param {string} name
     * @param {function(number)} resolve
     * @param {function} reject
     */
    count(name, resolve, reject) {
        const engine = this.engine;

        /**
         *
         * @type {GameSaveStateManager}
         */
        const gameSaves = engine.plugins.getById('game-save-state-manager');

        gameSaves.update()
            .then(() => {

                const matches = gameSaves.data.filter(m => m.name === name);

                resolve(matches.length);

            });
    }

    /**
     *
     * @param {string} name
     * @param {function(boolean)} resolve
     * @param {function} reject
     */
    exists(name, resolve, reject) {
        const engine = this.engine;

        /**
         *
         * @type {GameSaveStateManager}
         */
        const gameSaves = engine.plugins.getById('game-save-state-manager');

        gameSaves.update()
            .then(() => {
                const exists = gameSaves.data.some(m => !m.locked && (m.name === name));

                if (!exists) {
                    //try legacy
                    this.legacyExists(name, resolve, reject);
                } else {
                    resolve(exists);
                }

            }).catch(reject);
    }
}

export default GameStateLoader;
