module.exports = Self => {
    Self.remoteMethodCtx('getSales', {
        description: 'Get sales from ticket, collection or sectorCollection',
        accessType: 'READ',
        accepts: [
            {
                arg: 'collectionOrTicketFk',
                type: 'number',
                required: true
            }, {
                arg: 'print',
                type: 'boolean',
                required: true
            }, {
                arg: 'source',
                type: 'string',
                required: true
            },

        ],
        returns: {
            type: 'Object',
            root: true
        },
        http: {
            path: `/getSales`,
            verb: 'GET'
        },
    });

    Self.getSales = async(ctx, collectionOrTicketFk, print, source, options) => {
        const models = Self.app.models;
        const userId = ctx.req.accessToken.userId;
        const myOptions = {userId};
        const $t = ctx.req.__;

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

        const [{id}] = await Self.rawSql('SELECT vn.ticket_get(?) as id',
            [collectionOrTicketFk],
            myOptions);

        const [tickets] = await Self.rawSql('CALL vn.collection_getTickets(?)', [id], myOptions);

        if (source) {
            await Self.rawSql(
                'CALL vn.ticketStateToday_setState(?,?)', [id, source], myOptions
            );
        }

        const [sales] = await Self.rawSql('CALL vn.sale_getFromTicketOrCollection(?)',
            [id], myOptions);

        const isPicker = source != 'CHECKER';
        const [placements] = await Self.rawSql('CALL vn.collectionPlacement_get(?, ?)',
            [id, isPicker], myOptions
        );

        if (print) await Self.rawSql('CALL vn.collection_printSticker(?,NULL)', [id], myOptions);

        for (let ticket of tickets) {
            if (ticket.observaciones) {
                let observations = ticket.observaciones.split(' ');

                for (let observation of observations) {
                    const salesPerson = ticket.salesPersonFk;
                    if (observation.startsWith('#') || observation.startsWith('@')) {
                        await models.Chat.send(ctx,
                            observation,
                            $t('ticketCommercial', {ticket: ticket.ticketFk, salesPerson})
                        );
                    }
                }
            }
        }

        return getCollection(id, tickets, sales, placements, myOptions);
    };

    async function getCollection(id, tickets, sales, placements, options) {
        const collection = {
            collectionFk: id,
            tickets: [],
        };
        for (let ticket of tickets) {
            const {ticketFk} = ticket;
            ticket.sales = [];

            const barcodes = await getBarcodes(ticketFk, options);
            await Self.rawSql(
                'CALL util.log_add(?, ?, ?, ?, ?, ?, ?, ?)',
                ['vn', 'ticket', 'Ticket', ticketFk, ticketFk, 'select', null, null],
                options
            );

            for (let sale of sales) {
                if (sale.ticketFk == ticketFk) {
                    sale.placements = [];
                    for (const salePlacement of placements) {
                        if (salePlacement.saleFk == sale.saleFk && salePlacement.order) {
                            const placement = {
                                saleFk: salePlacement.saleFk,
                                itemFk: salePlacement.itemFk,
                                placement: salePlacement.placement,
                                shelving: salePlacement.shelving,
                                created: salePlacement.created,
                                visible: salePlacement.visible,
                                order: salePlacement.order,
                                grouping: salePlacement.grouping,
                                priority: salePlacement.priority,
                                saleOrder: salePlacement.saleOrder,
                                isPreviousPrepared: salePlacement.isPreviousPrepared,
                                itemShelvingSaleFk: salePlacement.itemShelvingSaleFk,
                                ticketFk: salePlacement.ticketFk,
                                id: salePlacement.id
                            };
                            sale.placements.push(placement);
                        }
                    }

                    sale.barcodes = [];
                    for (const barcode of barcodes) {
                        if (barcode.movementId == sale.saleFk) {
                            if (barcode.code) {
                                sale.barcodes.push(barcode.code);
                                sale.barcodes.push(`0 ${barcode.code}`);
                            }

                            if (barcode.id) {
                                sale.barcodes.push(barcode.id);
                                sale.barcodes.push(`0 ${barcode.id}`);
                            }
                        }
                    }

                    ticket.sales.push(sale);
                }
            }
            collection.tickets.push(ticket);
        }

        return collection;
    }

    async function getBarcodes(ticketId, options) {
        const query =
                `SELECT s.id movementId, 
                        b.code, 
                        c.id
                    FROM vn.sale s
                        LEFT JOIN vn.itemBarcode b ON b.itemFk = s.itemFk
                        LEFT JOIN vn.buy c ON c.itemFk = s.itemFk
                        LEFT JOIN vn.entry e ON e.id = c.entryFk
                        LEFT JOIN vn.travel tr ON tr.id = e.travelFk
                    WHERE s.ticketFk = ? 
                        AND tr.landed >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)`;
        return Self.rawSql(query, [ticketId], options);
    }
};