const UserError = require('vn-loopback/util/user-error');
const axios = require('axios');
const isProduction = require('vn-loopback/server/boot/isProduction');

module.exports = Self => {
    Self.remoteMethodCtx('upload', {
        description: 'Upload docuware PDFs',
        accessType: 'WRITE',
        accepts: [
            {
                arg: 'ticketIds',
                type: ['number'],
                description: 'The ticket ids',
                required: true
            },
            {
                arg: 'fileCabinet',
                type: 'string',
                description: 'The file cabinet',
                required: true
            }
        ],
        returns: {
            type: 'object',
            root: true
        },
        http: {
            path: `/upload`,
            verb: 'POST'
        }
    });

    Self.upload = async function(ctx, ticketIds, fileCabinet, options) {
        delete ctx.args.ticketIds;
        const models = Self.app.models;
        const action = 'store';

        const myOptions = {};

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

        const userConfig = await models.UserConfig.findById(ctx.req.accessToken.userId, {
            fields: ['tabletFk']
        }, myOptions);

        if (!userConfig?.tabletFk)
            throw new UserError('This user does not have an assigned tablet');

        const docuwareOptions = await Self.getOptions();
        const fileCabinetId = await Self.getFileCabinet(fileCabinet);
        const dialogId = await Self.getDialog(fileCabinet, action, fileCabinetId);

        const uploaded = [];
        for (id of ticketIds) {
            // get delivery note
            ctx.args.id = id;
            const deliveryNote = await models.Ticket.deliveryNotePdf(ctx, {
                id,
                type: 'deliveryNote'
            }, myOptions);
            // get ticket data
            const ticket = await models.Ticket.findById(id, {
                include: [{
                    relation: 'client',
                    scope: {
                        fields: ['id', 'name', 'fi']
                    }
                }]
            }, myOptions);

            // upload file
            const templateJson = {
                'Fields': [
                    {
                        'FieldName': 'N__ALBAR_N',
                        'ItemElementName': 'string',
                        'Item': id,
                    },
                    {
                        'FieldName': 'CIF_PROVEEDOR',
                        'ItemElementName': 'string',
                        'Item': ticket.client().fi,
                    },
                    {
                        'FieldName': 'CODIGO_PROVEEDOR',
                        'ItemElementName': 'string',
                        'Item': ticket.client().id,
                    },
                    {
                        'FieldName': 'NOMBRE_PROVEEDOR',
                        'ItemElementName': 'string',
                        'Item': ticket.client().name + ' - ' + id,
                    },
                    {
                        'FieldName': 'FECHA_FACTURA',
                        'ItemElementName': 'date',
                        'Item': ticket.shipped,
                    },
                    {
                        'FieldName': 'TOTAL_FACTURA',
                        'ItemElementName': 'Decimal',
                        'Item': ticket.totalWithVat,
                    },
                    {
                        'FieldName': 'ESTADO',
                        'ItemElementName': 'string',
                        'Item': 'Pendiente procesar',
                    },
                    {
                        'FieldName': 'FIRMA_',
                        'ItemElementName': 'string',
                        'Item': 'Si',
                    },
                    {
                        'FieldName': 'FILTRO_TABLET',
                        'ItemElementName': 'string',
                        'Item': userConfig.tabletFk,
                    }
                ]
            };

            if (!isProduction(false))
                throw new UserError('Action not allowed on the test environment');

            // delete old
            const docuwareFile = await models.Docuware.checkFile(id, fileCabinet, false);
            if (docuwareFile) {
                const deleteJson = {
                    'Field': [{'FieldName': 'ESTADO', 'Item': 'Pendiente eliminar', 'ItemElementName': 'String'}]
                };
                const deleteUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents/${docuwareFile.id}/Fields`;
                await axios.put(deleteUri, deleteJson, docuwareOptions.headers);
            }

            const uploadUri = `${docuwareOptions.url}/FileCabinets/${fileCabinetId}/Documents?StoreDialogId=${dialogId}`;
            const FormData = require('form-data');
            const data = new FormData();

            data.append('document', JSON.stringify(templateJson), 'schema.json');
            data.append('file[]', deliveryNote[0], 'file.pdf');
            const uploadOptions = {
                headers: {
                    'Content-Type': 'multipart/form-data',
                    'X-File-ModifiedDate': Date.vnNew(),
                    'Authorization': docuwareOptions.headers.headers.Authorization,
                    ...data.getHeaders()
                },
            };

            try {
                await axios.post(uploadUri, data, uploadOptions);
            } catch (err) {
                const $t = ctx.req.__;
                const message = $t('Failed to upload delivery note', {id});
                if (uploaded.length)
                    await models.TicketTracking.setDelivered(ctx, uploaded, myOptions);
                throw new UserError(message);
            }
            uploaded.push(id);
        }
        return models.TicketTracking.setDelivered(ctx, ticketIds, myOptions);
    };
};