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

module.exports = Self => {
    Self.remoteMethodCtx('handleUser', {
        description: 'Manage various aspects related to a user with the app',
        accepts: [
            {
                arg: 'androidId',
                type: 'String',
                description: 'Android id'
            },
            {
                arg: 'deviceId',
                type: 'String',
                description: 'Device id'
            },
            {
                arg: 'versionApp',
                type: 'String',
                description: 'Version app'
            }, {
                arg: 'nameApp',
                type: 'String',
                description: 'Version app'
            },

        ],
        returns: {
            type: 'object',
            root: true
        },
        http: {
            path: `/handleUser`,
            verb: 'POST'
        }
    });

    Self.handleUser = async(ctx, androidId, deviceId, versionApp, nameApp, options) => {
        const models = Self.app.models;
        const myOptions = {};

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

        const accessToken = ctx.req.accessToken;
        let user = await models.VnUser.findById(accessToken.userId);

        const [[{vIsAuthorized, vMessage}]] =
            await Self.rawSql('CALL vn.device_checkLogin(?, ?);',
                [user.id, androidId], myOptions);

        if (!vIsAuthorized)
            throw new UserError('Not authorized');

        const isUserInOperator = await models.Operator.findOne({
            where: {
                workerFk: user.id
            }
        }, myOptions);

        if (!isUserInOperator) {
            await models.Operator.create({
                'workerFk': user.id,
                'isOnReservationMode': false
            });
        }

        const whereCondition = deviceId ? {id: deviceId} : {android_id: androidId};
        const serialNumber =
            (await models.DeviceProduction.findOne({where: whereCondition}, myOptions))?.serialNumber ?? '';

        await models.DeviceLog.create({
            'android_id': androidId,
            'userFk': user.id,
            'nameApp': nameApp,
            'versionApp': versionApp,
            'serialNumber': serialNumber
        }, myOptions);
        const getDataUser = await models.VnUser.getCurrentUserData(ctx);

        const getDataOperator = await models.Operator.findOne({
            where: {workerFk: user.id},
            fields: ['numberOfWagons', 'warehouseFk', 'itemPackingTypeFk', 'sectorFk', 'sector',
                'trainFk', 'train', 'labelerFk', 'printer', 'isOnReservationMode'],
            include: [
                {
                    relation: 'sector',
                    scope: {
                        fields: ['warehouseFk', 'description', 'isOnReservationMode'],
                    }
                }, {
                    relation: 'printer',
                    scope: {
                        fields: ['name'],
                    }
                }, {
                    relation: 'train',
                    scope: {
                        fields: ['name'],
                    }
                }

            ]
        }, myOptions);

        const getVersion = await models.MobileAppVersionControl.getVersion(ctx, nameApp);

        const combinedResult = {
            ...getDataOperator.toObject(),
            ...getDataUser.toObject(),
            ...getVersion,
            message: vMessage,
            serialNumber,
        };
        return combinedResult;
    };
};