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

module.exports = Self => {
    Self.remoteMethod('createShipment', {
        description: 'Create an expedition and return a base64Binary label from de MRW WebService',
        accessType: 'WRITE',
        accepts: [{
            arg: 'expeditionFk',
            type: 'number',
            required: true
        }],
        returns: {
            type: ['object'],
            root: true
        },
        http: {
            path: `/createShipment`,
            verb: 'POST'
        }
    });

    Self.createShipment = async expeditionFk => {
        const models = Self.app.models;
        const mrw = await Self.getConfig();
        const clientType = await models.MrwConfig.getClientType(expeditionFk);

        const today = Date.vnNew();
        const [hours, minutes] = mrw?.expeditionDeadLine ? mrw.expeditionDeadLine.split(':').map(Number) : [0, 0];

        const deadLine = Date.vnNew();
        deadLine.setHours(hours, minutes, 0);

        if (today > deadLine && (!mrw.notified || mrw.notified.setHours(0, 0, 0, 0) !== today.setHours(0, 0, 0, 0))) {
            await models.NotificationQueue.create({notificationFk: 'mrw-deadline'});
            await mrw.updateAttributes({notified: Date.vnNow()});
        }

        const query =
            `SELECT 
                CASE co.code 
                    WHEN 'ES' THEN a.postalCode
                    WHEN 'PT' THEN LEFT(a.postalCode, mc.portugalPostCodeTrim)
                    WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00')
                END postalCode,
                a.city,
                a.street,
                co.code countryCode,
                c.fi,
                c.name clientName,
                IFNULL(a.mobile, c.mobile) mobile,
                DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
                t.shipped,
                CONCAT( e.ticketFk, LPAD(e.counter, mc.counterWidth, '0')) reference,
                LPAD(IF(mw.serviceType IS NULL, ms.serviceType, mw.serviceType), mc.serviceTypeWidth, '0') serviceType,
                IF(mw.weekdays, 'S', 'N') weekDays,
                ta.description deliveryObservation
            FROM expedition e
                JOIN ticket t ON e.ticketFk = t.id
                JOIN agencyMode am ON am.id = t.agencyModeFk
                JOIN mrwService ms ON ms.agencyModeCodeFk = am.code
                LEFT JOIN mrwServiceWeekday mw ON mw.agencyModeCodeFk = am.code
                    AND mw.weekDays & (1 << WEEKDAY(t.landed)) 
                JOIN client c ON t.clientFk = c.id
                JOIN address a ON t.addressFk = a.id
                LEFT JOIN ticketObservation ta ON ta.ticketFk = t.id
                    AND ta.observationTypeFk IN (SELECT id FROM observationType ot WHERE ot.code = 'agency')
                JOIN province p ON a.provinceFk = p.id
                JOIN country co ON co.id = p.countryFk
                JOIN mrwConfig mc
            WHERE e.id = ?
            LIMIT 1`;

        const [expeditionData] = await Self.rawSql(query, [expeditionFk]);

        if (expeditionData?.shipped.setHours(0, 0, 0, 0) < today.setHours(0, 0, 0, 0))
            throw new UserError(`This ticket has a shipped date earlier than today`);

        const shipmentResponse = await Self.sendXmlDoc(
            __dirname + `/createShipment.ejs`,
            {mrw, expeditionData, clientType},
            'application/soap+xml'
        );
        const shipmentId = Self.getTextByTag(shipmentResponse, 'NumeroEnvio');

        if (!shipmentId) throw new UserError(Self.getTextByTag(shipmentResponse, 'Mensaje'));

        const file = await models.MrwConfig.getLabel(shipmentId, clientType);

        return {shipmentId, file};
    };
};