module.exports = function(Self) {
    Self.remoteMethodCtx('toggleStarredModule', {
        description: 'creates or deletes a starred module for the current user',
        accessType: 'WRITE',
        returns: {
            type: 'object',
            root: true
        },
        accepts: {
            arg: 'moduleName',
            type: 'string',
            required: true,
            description: 'The module name'
        },
        http: {
            path: `/toggleStarredModule`,
            verb: 'post'
        }
    });

    Self.toggleStarredModule = async(ctx, moduleName, options) => {
        const models = Self.app.models;
        const userId = ctx.req.accessToken.userId;

        let tx;
        const myOptions = {};

        if (typeof options == 'object')
            Object.assign(myOptions, options);

        if (!myOptions.transaction) {
            tx = await Self.beginTransaction({});
            myOptions.transaction = tx;
        }

        try {
            const filter = {
                where: {
                    workerFk: userId,
                    moduleFk: moduleName
                }
            };

            const [starredModule] = await models.StarredModule.find(filter, myOptions);

            delete filter.moduleName;
            const allStarredModules = await models.StarredModule.getStarredModules(ctx, myOptions);

            let addedModule;

            if (starredModule)
                await starredModule.destroy(myOptions);
            else {
                let highestPosition;
                if (allStarredModules.length) {
                    allStarredModules.sort((a, b) => {
                        return a.position - b.position;
                    });
                    highestPosition = allStarredModules[allStarredModules.length - 1].position + 1;
                } else
                    highestPosition = 1;

                addedModule = await models.StarredModule.create({
                    workerFk: userId,
                    moduleFk: moduleName,
                    position: highestPosition
                }, myOptions);
            }

            if (tx) await tx.commit();

            return addedModule;
        } catch (e) {
            if (tx) await tx.rollback();
            throw e;
        }
    };
};