module.exports = function(Self) {
    Self.validateCredit = function(credit) {
        return credit >= 0;
    };

    Self.validateBinded('credit', Self.validateCredit, {
        message: 'The credit must be an integer greater than or equal to zero',
        allowNull: false, // FIXME: Ignored by loopback when it's false
        allowBlank: false
    });

    Self.validateGrade = function(grade) {
        return typeof grade === 'undefined' || grade >= 0;
    };

    Self.validateBinded('grade', Self.validateGrade, {
        message: 'The grade must be an integer greater than or equal to zero',
        allowNull: true
    });

    async function validateNullGrade(err, done) {
        let filter = {
            fields: ['grade'],
            where: {
                creditClassification: this.creditClassification
            },
            order: 'created DESC'
        };
        let insurance = await Self.findOne(filter);

        if (insurance && (!insurance.grade && this.grade || insurance.grade && !this.grade))
            err();

        done();
    }

    Self.validateAsync('nullGrade', validateNullGrade, {
        message: 'The grade must be similar to the last one'
    });

    Self.messageSend = async function(data, accessToken) {
        let filter = {
            include: {
                relation: 'classification',
                scope: {
                    fields: ['client'],
                    include: {
                        relation: 'customer',
                        scope: {
                            fields: ['name', 'salesPersonFk'],
                            include: {
                                relation: 'salesPerson',
                                scope: {
                                    fields: 'userFk',
                                    include: {
                                        relation: 'user',
                                        scope: {
                                            fields: ['name']
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        };

        let ctx = {req: {accessToken: accessToken}};
        let insurance = await Self.findById(data.id, filter);
        let customer = insurance.classification().customer();

        if (!customer.salesPerson()) return;
        let salesPersonId = customer.salesPerson().user().id;
        let grade = data.grade ? `(Grado ${data.grade})` : '(Sin grado)';
        let params = {
            recipientFk: salesPersonId,
            message: `He cambiado el crédito asegurado del `
                + `cliente "${customer.name}" a ${data.credit} € ${grade}`
        };

        Self.app.models.Message.send(ctx, params);
    };

    // Update from transaction misses ctx accessToken.
    // Fixed passing accessToken from method messageSend()
    Self.observe('after save', async function(ctx) {
        if (ctx.options.accessToken)
            await Self.messageSend(ctx.instance, ctx.options.accessToken);
    });
};