let UserError = require('vn-loopback/util/user-error');

module.exports = Self => {
    Self.remoteMethodCtx('confirm', {
        description: '',
        accessType: 'WRITE',
        accepts: [{
            arg: 'id',
            type: 'Integer',
            required: true,
            description: 'The request ID',
        }, {
            arg: 'itemFk',
            type: 'Integer',
            required: true,
            description: 'The requested item ID',
        }, {
            arg: 'quantity',
            type: 'Integer',
            required: true,
            description: 'The requested item quantity',
        }],
        returns: {
            type: 'Object',
            root: true
        },
        http: {
            path: `/:id/confirm`,
            verb: 'post'
        }
    });

    Self.confirm = async ctx => {
        const userId = ctx.req.accessToken.userId;
        const models = Self.app.models;
        const tx = await Self.beginTransaction({});
        const $t = ctx.req.__; // $translate
        let sale;

        try {
            let options = {transaction: tx};

            let item = await models.Item.findById(ctx.args.itemFk, null, options);
            if (!item)
                throw new UserError(`That item doesn't exists`);

            let request = await models.TicketRequest.findById(ctx.args.id, {
                include: {relation: 'ticket'}
            }, options);

            const res = await models.Item.getVisibleAvailable(ctx.args.itemFk, request.ticket().warehouseFk, request.ticket().shipped);

            if (res.available < 0)
                throw new UserError(`This item is not available`);

            if (request.saleFk) {
                sale = await models.Sale.findById(request.saleFk, null, options);
                await sale.updateAttributes({
                    itemFk: ctx.args.itemFk,
                    quantity: ctx.args.quantity,
                    concept: item.name,
                }, options);
            } else {
                sale = await models.Sale.create({
                    ticketFk: request.ticketFk,
                    itemFk: ctx.args.itemFk,
                    quantity: ctx.args.quantity,
                    concept: item.name
                }, options);
                await request.updateAttributes({
                    saleFk: sale.id,
                    itemFk: sale.itemFk,
                    isOk: true
                }, options);
            }

            query = `CALL vn.sale_calculateComponent(?, NULL)`;
            await Self.rawSql(query, [sale.id], options);

            const origin = ctx.req.headers.origin;
            const requesterId = request.requesterFk;
            const message = $t('MESSAGE_BOUGHT_UNITS', {
                quantity: sale.quantity,
                concept: sale.concept,
                itemId: sale.itemFk,
                ticketId: sale.ticketFk,
                url: `${origin}/#!/ticket/${sale.ticketFk}/summary`
            });
            await models.Chat.sendCheckingPresence(ctx, requesterId, message);

            // loguejar
            let logRecord = {
                originFk: sale.ticketFk,
                userFk: userId,
                action: 'update',
                changedModel: 'ticketRequest',
                newInstance: {
                    destinationFk: sale.ticketFk,
                    quantity: sale.quantity,
                    concept: sale.concept,
                    itemId: sale.itemFk,
                    ticketId: sale.ticketFk,
                }
            };

            await Self.app.models.TicketLog.create(logRecord);

            await tx.commit();

            return sale;
        } catch (error) {
            await tx.rollback();
            throw error;
        }
    };
};