import sharp from 'sharp';
sharp.cache({ files : 0 });

const collection = 'games';
/**
 * Games manager class
 */
class GamesManager{
    name = 'game';

    /**
     * Class initializer, инициализация на плъгин
     * @param {App} app Class initializer, основна апликация
     */
    init(app){
        const {db, am, config} = app;

        /**
         * Creates a new game definition, създаване на нова игрова дефиниция
         * @param {Context} ctx Request context, контекст на заявката
         * @param {Game} data the game description, дефиниция на играта
         */
        this.create = async function(ctx, data){
            data.id = await db.getId(collection);
            await db.create(collection, data);
            return data;
        }

        /**
         * Reads game definition by ID, извличане на игрова дефиниция от базата от данни по подаден идентификатор
         * @param {Number} id game ID, идентификатор на играта
         * @returns {Game} the game, игрова дефиниция
         */
        this.read = async function(id){
            id = parseInt(id);
            return await db.get(collection, {id});
        }

        /**
         * Updates game definition, обновяване на игрова дефиниция
         * @param {Context} ctx Request context, контекст на заявката
         * @param {Game} data the game description, игрова дефиниция
         */
        this.update = async function(ctx, data){
            data.id = parseInt(data.id);
            let object = await this.read(data.id);
            await am.addToHistory(object, collection, 'update');
            data = Object.assign(object, data);
            await db.update(collection, {id: data.id}, data);
            return data;
        }

        /**
         * Removes game by ID, изтриване на игрова дефиниция по зададен идентификатор
         * @param {Number} id game definition ID, идентификатор на игровата дефиниция
         */
        this.remove = async function(id){
            id = parseInt(id);
            await am.addToHistory(id, collection, 'delete');
            await db.remove(collection, {id});
        }

        /**
         * Returns a set of games by given criteria, търсене в игровите дефиниции по зададени критерии
         * @param {Query} query criteria, критерии за търсене - заявка към базата от данни
         * @returns {Game[]} Array of games, масив от игрови дефиниции
         */
        this.list = async function(query){
            return await db.list(collection, {
                query,
                project: { name:1, description:1, id:1, thumb: 1, group: 1, order: 1, activationTriggers: 1}
            });
        }

        this.setHeader = async function(ctx, id, file){
            await sharp(file.path).resize({height: 500}).webp({quality: 75}).toFile(`${config.fs.repo}/thumb/${id}.webp`);
            await sharp(file.path).webp({quality: 75}).toFile(`${config.fs.repo}/default/${id}.webp`);
            let object = await this.read(id);
            object.thumb = id;
            await this.update(ctx, object);
        }
    }

    /**
     * Class starter
     * @param {App} app The application, основна апликация
     */
    async start(app){

    }
}

/**
 * Game entity, игрова дефиниция - елемент
 */
class Game {
    /**
     * Game name, име на играта
     * @type {string}
     */
    name = null;

    /**
     * Game scenario, сценарий на играта
     * @type { Scenario }
     */
    scenario = null;
}

export { GamesManager }